From 9d2f0c6c71c2105d8468f4d3fe4526fc611ca361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Sat, 2 Sep 2017 23:10:39 +0300 Subject: [PATCH] #590 Add explanation to Decorator pattern --- decorator/README.md | 91 +++++++++++++++++- decorator/etc/decorator.png | Bin 21795 -> 0 bytes decorator/etc/decorator.ucls | 76 --------------- decorator/etc/decorator.urm.puml | 38 -------- .../com/iluwatar/decorator/ClubbedTroll.java | 15 ++- .../iluwatar/decorator/TrollDecorator.java | 53 ---------- .../iluwatar/decorator/ClubbedTrollTest.java | 2 +- pom.xml | 1 + 8 files changed, 103 insertions(+), 173 deletions(-) delete mode 100644 decorator/etc/decorator.png delete mode 100644 decorator/etc/decorator.ucls delete mode 100644 decorator/etc/decorator.urm.puml delete mode 100644 decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java diff --git a/decorator/README.md b/decorator/README.md index d2ba55afa..5f86166fe 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -19,7 +19,96 @@ Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. -![alt text](./etc/decorator.png "Decorator") +## Explanation + +Real world example + +> There is an angry troll living in the nearby hills. Usually it goes bare handed but sometimes it has a weapon. To arm the troll it's not necessary to create a new troll but to decorate it dynamically with a suitable weapon. + +In plain words + +> Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping them in an object of a decorator class. + +Wikipedia says + +> In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern. + +**Programmatic Example** + +Lets take the troll example. First of all we have a simple troll implementing the troll interface + +``` +public interface Troll { + void attack(); + int getAttackPower(); + void fleeBattle(); +} + +public class SimpleTroll implements Troll { + + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTroll.class); + + @Override + public void attack() { + LOGGER.info("The troll tries to grab you!"); + } + + @Override + public int getAttackPower() { + return 10; + } + + @Override + public void fleeBattle() { + LOGGER.info("The troll shrieks in horror and runs away!"); + } +} +``` + +Next we want to add club for the troll. We can do it dynamically by using a decorator + +``` +public class ClubbedTroll implements Troll { + + private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); + + private Troll decorated; + + public ClubbedTroll(Troll decorated) { + this.decorated = decorated; + } + + @Override + public void attack() { + decorated.attack(); + LOGGER.info("The troll swings at you with a club!"); + } + + @Override + public int getAttackPower() { + return decorated.getAttackPower() + 10; + } + + @Override + public void fleeBattle() { + decorated.fleeBattle(); + } +} +``` + +Here's the troll in action + +``` +// simple troll +Troll troll = new SimpleTroll(); +troll.attack(); // The troll tries to grab you! +troll.fleeBattle(); // The troll shrieks in horror and runs away! + +// change the behavior of the simple troll by adding a decorator +Troll clubbed = new ClubbedTroll(troll); +clubbed.attack(); // The troll tries to grab you! The troll swings at you with a club! +clubbed.fleeBattle(); // The troll shrieks in horror and runs away! +``` ## Applicability Use Decorator diff --git a/decorator/etc/decorator.png b/decorator/etc/decorator.png deleted file mode 100644 index 35a7ef35db7e7aac6621d6d33116ad2d692a76cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21795 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 KIaN6BNcsz+?~j@Q diff --git a/decorator/etc/decorator.ucls b/decorator/etc/decorator.ucls deleted file mode 100644 index 88bea6987..000000000 --- a/decorator/etc/decorator.ucls +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/decorator/etc/decorator.urm.puml b/decorator/etc/decorator.urm.puml deleted file mode 100644 index be878bd91..000000000 --- a/decorator/etc/decorator.urm.puml +++ /dev/null @@ -1,38 +0,0 @@ -@startuml -package com.iluwatar.decorator { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - class ClubbedTroll { - - LOGGER : Logger {static} - + ClubbedTroll(decorated : Troll) - + attack() - + getAttackPower() : int - } - class SimpleTroll { - - LOGGER : Logger {static} - + SimpleTroll() - + attack() - + fleeBattle() - + getAttackPower() : int - } - interface Troll { - + attack() {abstract} - + fleeBattle() {abstract} - + getAttackPower() : int {abstract} - } - class TrollDecorator { - - decorated : Troll - + TrollDecorator(decorated : Troll) - + attack() - + fleeBattle() - + getAttackPower() : int - } -} -TrollDecorator --> "-decorated" Troll -ClubbedTroll --|> TrollDecorator -SimpleTroll ..|> Troll -TrollDecorator ..|> Troll -@enduml \ No newline at end of file diff --git a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java index e309f17cd..edaa334a5 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java +++ b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java @@ -28,22 +28,29 @@ import org.slf4j.LoggerFactory; /** * Decorator that adds a club for the troll */ -public class ClubbedTroll extends TrollDecorator { +public class ClubbedTroll implements Troll { private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); + private Troll decorated; + public ClubbedTroll(Troll decorated) { - super(decorated); + this.decorated = decorated; } @Override public void attack() { - super.attack(); + decorated.attack(); LOGGER.info("The troll swings at you with a club!"); } @Override public int getAttackPower() { - return super.getAttackPower() + 10; + return decorated.getAttackPower() + 10; + } + + @Override + public void fleeBattle() { + decorated.fleeBattle(); } } diff --git a/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java b/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java deleted file mode 100644 index d84c3a2b3..000000000 --- a/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * The MIT License - * Copyright (c) 2014-2016 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.iluwatar.decorator; - -/** - * TrollDecorator is a decorator for {@link Troll} objects. The calls to the {@link Troll} interface - * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Troll} - * object. - * - */ -public class TrollDecorator implements Troll { - - private Troll decorated; - - public TrollDecorator(Troll decorated) { - this.decorated = decorated; - } - - @Override - public void attack() { - decorated.attack(); - } - - @Override - public int getAttackPower() { - return decorated.getAttackPower(); - } - - @Override - public void fleeBattle() { - decorated.fleeBattle(); - } -} diff --git a/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java index a097752cd..fb86615c6 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java @@ -34,7 +34,7 @@ import static org.mockito.internal.verification.VerificationModeFactory.times; public class ClubbedTrollTest { @Test - public void testSmartHostile() throws Exception { + public void testClubbedTroll() throws Exception { // Create a normal troll first, but make sure we can spy on it later on. final Troll simpleTroll = spy(new SimpleTroll()); diff --git a/pom.xml b/pom.xml index 6212ddc05..5e3995976 100644 --- a/pom.xml +++ b/pom.xml @@ -469,6 +469,7 @@ adapter bridge composite + decorator