From 92f8501f7d87563617664b215436f912df0ce079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilkka=20Sepp=C3=A4l=C3=A4?= Date: Tue, 22 Nov 2016 23:08:39 +0200 Subject: [PATCH] Decorator pattern: Improve the example --- decorator/README.md | 6 +- decorator/etc/decorator.png | Bin 29945 -> 21795 bytes decorator/etc/decorator.ucls | 106 +++++++++--------- .../main/java/com/iluwatar/decorator/App.java | 16 +-- .../com/iluwatar/decorator/ClubbedTroll.java | 49 ++++++++ .../{Hostile.java => SimpleTroll.java} | 89 ++++++++------- .../java/com/iluwatar/decorator/Troll.java | 89 +++++++-------- ...{SmartHostile.java => TrollDecorator.java} | 20 +--- ...HostileTest.java => ClubbedTrollTest.java} | 22 ++-- .../{TrollTest.java => SimpleTrollTest.java} | 12 +- 10 files changed, 225 insertions(+), 184 deletions(-) create mode 100644 decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java rename decorator/src/main/java/com/iluwatar/decorator/{Hostile.java => SimpleTroll.java} (70%) rename decorator/src/main/java/com/iluwatar/decorator/{SmartHostile.java => TrollDecorator.java} (71%) rename decorator/src/test/java/com/iluwatar/decorator/{SmartHostileTest.java => ClubbedTrollTest.java} (79%) rename decorator/src/test/java/com/iluwatar/decorator/{TrollTest.java => SimpleTrollTest.java} (90%) diff --git a/decorator/README.md b/decorator/README.md index 819873429..d2ba55afa 100644 --- a/decorator/README.md +++ b/decorator/README.md @@ -24,9 +24,9 @@ functionality. ## Applicability Use Decorator -* to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects -* for responsibilities that can be withdrawn -* when extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing +* To add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects +* For responsibilities that can be withdrawn +* When extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing ## Real world examples * [java.io.InputStream](http://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html), [java.io.OutputStream](http://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html), diff --git a/decorator/etc/decorator.png b/decorator/etc/decorator.png index 47a87b20b33dd4964ad94d7309bd63eb7b828d70..35a7ef35db7e7aac6621d6d33116ad2d692a76cd 100644 GIT binary patch literal 21795 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 KIaN6BNcsz+?~j@Q literal 29945 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 diff --git a/decorator/etc/decorator.ucls b/decorator/etc/decorator.ucls index a5353d4ec..88bea6987 100644 --- a/decorator/etc/decorator.ucls +++ b/decorator/etc/decorator.ucls @@ -1,66 +1,72 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + + - - + + - + - - - - - - - - diff --git a/decorator/src/main/java/com/iluwatar/decorator/App.java b/decorator/src/main/java/com/iluwatar/decorator/App.java index 808bd1bd7..a5225d72c 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/App.java +++ b/decorator/src/main/java/com/iluwatar/decorator/App.java @@ -32,8 +32,8 @@ import org.slf4j.LoggerFactory; * target. Using the Decorator pattern it is possible to change the behavior of the class during * runtime. *

- * In this example we show how the simple {@link Troll} first attacks and then flees the battle. - * Then we decorate the {@link Troll} with a {@link SmartHostile} and perform the attack again. You + * In this example we show how the simple {@link SimpleTroll} first attacks and then flees the battle. + * Then we decorate the {@link SimpleTroll} with a {@link ClubbedTroll} and perform the attack again. You * can see how the behavior changes after the decoration. * */ @@ -50,16 +50,16 @@ public class App { // simple troll LOGGER.info("A simple looking troll approaches."); - Hostile troll = new Troll(); + Troll troll = new SimpleTroll(); troll.attack(); troll.fleeBattle(); LOGGER.info("Simple troll power {}.\n", troll.getAttackPower()); // change the behavior of the simple troll by adding a decorator - LOGGER.info("A smart looking troll surprises you."); - Hostile smart = new SmartHostile(troll); - smart.attack(); - smart.fleeBattle(); - LOGGER.info("Smart troll power {}.\n", smart.getAttackPower()); + LOGGER.info("A troll with huge club surprises you."); + Troll clubbed = new ClubbedTroll(troll); + clubbed.attack(); + clubbed.fleeBattle(); + LOGGER.info("Clubbed troll power {}.\n", clubbed.getAttackPower()); } } diff --git a/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java new file mode 100644 index 000000000..318b76f32 --- /dev/null +++ b/decorator/src/main/java/com/iluwatar/decorator/ClubbedTroll.java @@ -0,0 +1,49 @@ +/** + * The MIT License + * Copyright (c) 2014 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; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Decorator that adds a club for the troll + */ +public class ClubbedTroll extends TrollDecorator { + + private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class); + + public ClubbedTroll(Troll decorated) { + super(decorated); + } + + @Override + public void attack() { + super.attack(); + LOGGER.info("The troll swings at you with a club!"); + } + + @Override + public int getAttackPower() { + return super.getAttackPower() + 10; + } +} diff --git a/decorator/src/main/java/com/iluwatar/decorator/Hostile.java b/decorator/src/main/java/com/iluwatar/decorator/SimpleTroll.java similarity index 70% rename from decorator/src/main/java/com/iluwatar/decorator/Hostile.java rename to decorator/src/main/java/com/iluwatar/decorator/SimpleTroll.java index d3414c9dd..ad1316643 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/Hostile.java +++ b/decorator/src/main/java/com/iluwatar/decorator/SimpleTroll.java @@ -1,38 +1,51 @@ -/** - * The MIT License - * Copyright (c) 2014 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; - -/** - * - * Interface for the hostile enemies. - * - */ -public interface Hostile { - - void attack(); - - int getAttackPower(); - - void fleeBattle(); - -} +/** + * The MIT License + * Copyright (c) 2014 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; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * SimpleTroll implements {@link Troll} interface directly. + * + */ +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!"); + } +} diff --git a/decorator/src/main/java/com/iluwatar/decorator/Troll.java b/decorator/src/main/java/com/iluwatar/decorator/Troll.java index 0fff3b812..d9f1da968 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/Troll.java +++ b/decorator/src/main/java/com/iluwatar/decorator/Troll.java @@ -1,51 +1,38 @@ -/** - * The MIT License - * Copyright (c) 2014 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; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * Troll implements {@link Hostile} interface directly. - * - */ -public class Troll implements Hostile { - - private static final Logger LOGGER = LoggerFactory.getLogger(Troll.class); - - @Override - public void attack() { - LOGGER.info("The troll swings at you with a club!"); - } - - @Override - public int getAttackPower() { - return 10; - } - - @Override - public void fleeBattle() { - LOGGER.info("The troll shrieks in horror and runs away!"); - } -} +/** + * The MIT License + * Copyright (c) 2014 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; + +/** + * + * Interface for trolls + * + */ +public interface Troll { + + void attack(); + + int getAttackPower(); + + void fleeBattle(); + +} diff --git a/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java b/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java similarity index 71% rename from decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java rename to decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java index 9a4a136ad..4495311cf 100644 --- a/decorator/src/main/java/com/iluwatar/decorator/SmartHostile.java +++ b/decorator/src/main/java/com/iluwatar/decorator/TrollDecorator.java @@ -22,40 +22,32 @@ */ package com.iluwatar.decorator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** - * SmartHostile is a decorator for {@link Hostile} objects. The calls to the {@link Hostile} interface - * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Hostile} + * 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 SmartHostile implements Hostile { +public class TrollDecorator implements Troll { - private static final Logger LOGGER = LoggerFactory.getLogger(SmartHostile.class); + private Troll decorated; - private Hostile decorated; - - public SmartHostile(Hostile decorated) { + public TrollDecorator(Troll decorated) { this.decorated = decorated; } @Override public void attack() { - LOGGER.info("It throws a rock at you!"); decorated.attack(); } @Override public int getAttackPower() { - // decorated hostile's power + 20 because it is smart - return decorated.getAttackPower() + 20; + return decorated.getAttackPower(); } @Override public void fleeBattle() { - LOGGER.info("It calls for help!"); decorated.fleeBattle(); } } diff --git a/decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java similarity index 79% rename from decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java rename to decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java index 6432d4e90..75b98df1a 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/SmartHostileTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/ClubbedTrollTest.java @@ -29,30 +29,26 @@ import static org.mockito.Mockito.*; import static org.mockito.internal.verification.VerificationModeFactory.times; /** - * Date: 12/7/15 - 7:47 PM - * - * @author Jeroen Meulemeester + * Tests for {@link ClubbedTroll} */ -public class SmartHostileTest { +public class ClubbedTrollTest { @Test public void testSmartHostile() throws Exception { // Create a normal troll first, but make sure we can spy on it later on. - final Hostile simpleTroll = spy(new Troll()); + final Troll simpleTroll = spy(new SimpleTroll()); - // Now we want to decorate the troll to make it smarter ... - final Hostile smartTroll = new SmartHostile(simpleTroll); - assertEquals(30, smartTroll.getAttackPower()); + // Now we want to decorate the troll to make it stronger ... + final Troll clubbed = new ClubbedTroll(simpleTroll); + assertEquals(20, clubbed.getAttackPower()); verify(simpleTroll, times(1)).getAttackPower(); - // Check if the smart troll actions are delegated to the decorated troll - smartTroll.attack(); + // Check if the clubbed troll actions are delegated to the decorated troll + clubbed.attack(); verify(simpleTroll, times(1)).attack(); - smartTroll.fleeBattle(); + clubbed.fleeBattle(); verify(simpleTroll, times(1)).fleeBattle(); verifyNoMoreInteractions(simpleTroll); - } - } diff --git a/decorator/src/test/java/com/iluwatar/decorator/TrollTest.java b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java similarity index 90% rename from decorator/src/test/java/com/iluwatar/decorator/TrollTest.java rename to decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java index 652c1fcdc..775813eff 100644 --- a/decorator/src/test/java/com/iluwatar/decorator/TrollTest.java +++ b/decorator/src/test/java/com/iluwatar/decorator/SimpleTrollTest.java @@ -36,17 +36,15 @@ import java.util.List; import static org.junit.Assert.assertEquals; /** - * Date: 12/7/15 - 7:26 PM - * - * @author Jeroen Meulemeester + * Tests for {@link SimpleTroll} */ -public class TrollTest { +public class SimpleTrollTest { private InMemoryAppender appender; @Before public void setUp() { - appender = new InMemoryAppender(Troll.class); + appender = new InMemoryAppender(SimpleTroll.class); } @After @@ -56,11 +54,11 @@ public class TrollTest { @Test public void testTrollActions() throws Exception { - final Troll troll = new Troll(); + final SimpleTroll troll = new SimpleTroll(); assertEquals(10, troll.getAttackPower()); troll.attack(); - assertEquals("The troll swings at you with a club!", appender.getLastMessage()); + assertEquals("The troll tries to grab you!", appender.getLastMessage()); troll.fleeBattle(); assertEquals("The troll shrieks in horror and runs away!", appender.getLastMessage());