Skip to content
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

Redesign of decorator pattern #12

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

srgtrujillo
Copy link
Member

@srgtrujillo srgtrujillo commented Mar 15, 2017

I've opened this pull request to discuss the necessary changes so that the implemented example complies with the principles of the Decorator Pattern

#1

@@ -28,4 +34,75 @@ class IngredientDecoratorTest {
fun `price of ingredient is calculated correctly`() =
assertThat(Tuna(Pork(UdonNoodles())).calculateCost(), `is`(10.75))

@Test
fun `has the same interface`() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my good lots asserts

@Cotel
Copy link
Member

Cotel commented Mar 15, 2017

I've made some refactors and now IngredientDecorator makes use of by correctly (though it is not the most clever way to implement this example (Noodles could be an abstract class too and every noodles and ingredient only should need to define its cost reducing that way lines of code)).

I've detected a bug too. When showPrice() is called the price is shown correctly while noodles are not decorated or when they are decorated only by ingredients. But when the type changes to a sauce decorator it only returns the base price again because it has no calculateTotalCost() from ingredients decorators.

Does this mean we are not implementing the pattern correctly yet? If an object gets decorated it shouldn't lose its previous decorators isn't it?

fun calculateCost() : Double
interface Noodles {
fun calculateCost(): Double
fun calculateTotalCost(): Double
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then IngredientDecorator is not adding any behaviour 😵

Copy link
Member Author

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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But If Noodles already has a method calculateTotalCost() then, every child that implements it modifies its behaviour. Noodles shouldn't have that method, it belongs to IngredientDecorator and the concrete decorators which will add that behaviour to Noodles.

@@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COST is a constant. It shouln't go in the constructor because you are opening it to change and we are not interested in that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the keyword val make the constant COST inmutable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you are placing the declaration in the constructor. You are giving the opportunity to set another COST when making a new instance.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done some tests and you're right. I have extracted the COST variable from the constructor to an immutable constant.

@tonilopezmr
Copy link
Member

tonilopezmr commented Mar 30, 2017

@srgtrujillo You still alive?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants