-
Notifications
You must be signed in to change notification settings - Fork 1
Redesign of decorator pattern #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 4 commits
6b956fa
45f69a1
5be0c75
b31714e
12ba9ba
9177395
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,5 @@ | ||
| package Decorator.littlekai.base | ||
|
|
||
| abstract class IngredientDecorator (private val noodles: Noodles) : Noodles by noodles { | ||
| protected abstract val COST : Double | ||
|
|
||
| override fun calculateCost(): Double = noodles.calculateCost() + this.COST | ||
| abstract class IngredientDecorator (private val noodles: Noodles): Noodles by noodles { | ||
| override fun calculateTotalCost(): Double = noodles.calculateTotalCost() | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package Decorator.littlekai.base | ||
|
|
||
| interface Noodles { | ||
| fun calculateCost() : Double | ||
| fun calculateCost(): Double | ||
| fun calculateTotalCost(): Double | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| package Decorator.littlekai.base | ||
|
|
||
| abstract class SauceDecorator(private val noodles: Noodles) : Noodles by noodles { | ||
| abstract class SauceDecorator(private val noodles: Noodles): Noodles by noodles { | ||
| abstract val SPICINESS: Int | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,6 @@ import Decorator.littlekai.base.IngredientDecorator | |
| import Decorator.littlekai.base.Noodles | ||
|
|
||
|
|
||
| class Chicken(noodles: Noodles) : IngredientDecorator(noodles) { | ||
| override val COST: Double = 3.50 | ||
| class Chicken(noodles: Noodles, val COST: Double = 3.50): IngredientDecorator(noodles) { | ||
|
||
| override fun calculateTotalCost(): Double = super.calculateTotalCost() + COST | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,35 @@ | ||
| package Decorator.littlekai.base | ||
|
|
||
| import Decorator.littlekai.ingredients.Chicken | ||
| import Decorator.littlekai.ingredients.Peanuts | ||
| import Decorator.littlekai.ingredients.Pork | ||
| import Decorator.littlekai.ingredients.Tuna | ||
| import Decorator.littlekai.noodles.EggNoodles | ||
| import Decorator.littlekai.noodles.UdonNoodles | ||
| import Decorator.littlekai.noodles.WheatNoodles | ||
| import org.hamcrest.CoreMatchers.`is` | ||
| import org.junit.Assert.assertThat | ||
| import Decorator.littlekai.sauces.BittersweetSauce | ||
| import org.junit.Assert.assertTrue | ||
| import org.junit.Test | ||
|
|
||
| class IngredientDecoratorTest { | ||
|
|
||
| @Test | ||
| fun `check if decorated element is still Noodles`() = | ||
| assertTrue(Pork(UdonNoodles()) is Noodles) //:+1: | ||
| fun `has the same interface`() = | ||
| assertTrue(BittersweetSauce(Chicken(EggNoodles())) is Noodles) | ||
|
|
||
| @Test | ||
| fun `Ingredient Decorator should return ingredient cost plus base noodle cost`() = | ||
| assertThat(Pork(UdonNoodles()).calculateCost(), `is`(8.00)) | ||
| fun `does not modify behavior`() = | ||
| assertTrue(EggNoodles().calculateCost() == BittersweetSauce(Chicken(EggNoodles())).calculateCost()) | ||
|
|
||
| @Test | ||
| fun `check decorated Noodles is of type IngredientDecorator`() = | ||
| assertTrue(Tuna(UdonNoodles()) is IngredientDecorator) | ||
| fun `adds behavior`() = | ||
| assertTrue(Chicken(EggNoodles()).calculateTotalCost() == EggNoodles().calculateCost() + Chicken(EggNoodles()).COST) | ||
|
|
||
| @Test | ||
| fun `price of ingredient is calculated correctly`() = | ||
| assertThat(Tuna(Pork(UdonNoodles())).calculateCost(), `is`(10.75)) | ||
|
|
||
| fun `is stackable`() = | ||
| assertTrue( | ||
| Tuna(Pork(Peanuts(Chicken(EggNoodles())))).calculateTotalCost() == | ||
| EggNoodles().COST + | ||
| Chicken(EggNoodles()).COST + | ||
| Peanuts(EggNoodles()).COST + | ||
| Pork(EggNoodles()).COST + | ||
| Tuna(EggNoodles()).COST) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then
IngredientDecoratoris not adding any behaviour 😵There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think with the fact of implementing the decorator function in each concrete case, it's already adding behaviour. What do you think about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But If
Noodlesalready has a methodcalculateTotalCost()then, every child that implements it modifies its behaviour.Noodlesshouldn't have that method, it belongs toIngredientDecoratorand the concrete decorators which will add that behaviour to Noodles.