├── .gitignore ├── LICENSE ├── README.md ├── behavioral ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── siriusxi │ └── dp │ └── behav │ ├── observer │ ├── Message.java │ ├── Observer.java │ ├── Subject.java │ ├── WeatherStation.java │ ├── WeatherStationSimulator.java │ └── concrete │ │ ├── Alert.java │ │ ├── BusinessApp.java │ │ ├── Logger.java │ │ └── UserInterface.java │ └── strategy │ ├── Fighter.java │ ├── StreetFightersSimulator.java │ ├── algorithms │ ├── jump │ │ ├── HighJump.java │ │ ├── JumpBehavior.java │ │ ├── NoJump.java │ │ └── NormalJump.java │ ├── kick │ │ ├── KickBehavior.java │ │ ├── NormalKick.java │ │ └── TornadoKick.java │ └── roll │ │ ├── NoRoll.java │ │ ├── NormalRoll.java │ │ └── RollBehavior.java │ └── fighters │ ├── ChunLi.java │ ├── EHonda.java │ ├── Ken.java │ └── Ryu.java ├── pom.xml ├── principles ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── siriusxi │ └── principle │ └── coupling │ ├── RemoteSimulator.java │ ├── loose │ ├── Device.java │ ├── LCRemote.java │ ├── LCTelevision.java │ └── Radio.java │ └── tight │ ├── Remote.java │ └── Television.java └── structural ├── pom.xml └── src └── main └── java └── com └── siriusxi └── dp └── structural ├── adapter ├── AmericanCity.java ├── CelsiusToFahrenheitCityAdapter.java ├── City.java ├── MiddleEastCity.java ├── WeatherFeeder.java └── WeatherStation.java └── decorator ├── CondimentDecorator.java ├── Drink.java ├── FuzzBuzzCoffeeShop.java ├── component ├── DarkRoast.java ├── Decaf.java ├── Espresso.java └── HouseBlend.java └── condiment ├── Milk.java ├── Mocha.java ├── Sprinkles.java └── Whip.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | target/ 26 | !.mvn/wrapper/maven-wrapper.jar 27 | 28 | ### IntelliJ IDEA ### 29 | .idea 30 | *.iws 31 | *.iml 32 | *.ipr 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Mohamed Taman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design Patterns 2 | Java design patterns implementations and code examples. 3 | -------------------------------------------------------------------------------- /behavioral/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | design-patterns 7 | com.siriusxi.dp 8 | 0.0.1-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | behavioral 13 | 14 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/Message.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer; 2 | 3 | public record Message(int pressure, int windSpeed, int temperature) { 4 | } 5 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/Observer.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer; 2 | 3 | @FunctionalInterface 4 | public interface Observer { 5 | void update(Message message); 6 | } 7 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/Subject.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer; 2 | 3 | import java.util.List; 4 | 5 | public abstract class Subject { 6 | 7 | protected List observers; 8 | 9 | public abstract void register(Observer observer); 10 | 11 | public abstract void remove(Observer observer); 12 | 13 | protected abstract void notifyObservers(); 14 | } 15 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/WeatherStation.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer; 2 | 3 | import java.util.ArrayList; 4 | 5 | import static java.lang.System.out; 6 | import static java.util.Objects.requireNonNull; 7 | 8 | public class WeatherStation extends Subject { 9 | 10 | private int pressure; 11 | private int windSpeed; 12 | private int temperature; 13 | 14 | public WeatherStation() { 15 | super.observers = new ArrayList<>(); 16 | } 17 | 18 | @Override 19 | public void register(Observer observer) { 20 | requireNonNull(observer, "Observer can't be null."); 21 | if (!observers.contains(observer)) 22 | observers.add(observer); 23 | 24 | out.printf("%s is registered for weather forecasting.%n", 25 | observer.getClass().getSimpleName()); 26 | } 27 | 28 | @Override 29 | public void remove(Observer observer) { 30 | requireNonNull(observer, "Observer can't be null."); 31 | observers.remove(observer); 32 | out.printf("%s has left the Station.%n", observer.getClass().getSimpleName()); 33 | } 34 | 35 | @Override 36 | protected void notifyObservers() { 37 | out.println(observers.size()); 38 | observers.forEach(observer -> observer.update(new Message(this.pressure, 39 | this.windSpeed, this.temperature))); 40 | } 41 | 42 | protected void updateMeasures(int pressure, int windSpeed, int temperature) { 43 | this.pressure = pressure; 44 | this.windSpeed = windSpeed; 45 | this.temperature = temperature; 46 | this.notifyObservers(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/WeatherStationSimulator.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer; 2 | 3 | import com.siriusxi.dp.behav.observer.concrete.Alert; 4 | import com.siriusxi.dp.behav.observer.concrete.BusinessApp; 5 | import com.siriusxi.dp.behav.observer.concrete.Logger; 6 | import com.siriusxi.dp.behav.observer.concrete.UserInterface; 7 | 8 | /** 9 | * Main driver class to show Observer pattern in action. 10 | * 11 | * @author mohamed_taman. 12 | */ 13 | public class WeatherStationSimulator { 14 | 15 | public static void main(String[] args) { 16 | // 1. create weather station subject 17 | WeatherStation station = new WeatherStation(); 18 | 19 | // Create observers 20 | UserInterface ui = new UserInterface(station); 21 | Alert alert = new Alert(station); 22 | Logger logger = new Logger(station); 23 | BusinessApp businessApp = new BusinessApp(station); 24 | 25 | System.out.println("-------------- First Weather Update -----------------"); 26 | // Update weather data 27 | station.updateMeasures(100, 20, 15); 28 | 29 | // Logger is not interested anymore 30 | logger.unsubscribe(); 31 | 32 | System.out.println("-------------- Second Weather Update -----------------"); 33 | // Second Update weather data 34 | station.updateMeasures(160, 20, -1); 35 | // All observers are unregistered 36 | alert.unsubscribe(); 37 | ui.unsubscribe(); 38 | businessApp.unsubscribe(); 39 | 40 | System.out.println("-------------- Third Weather Update -----------------"); 41 | // Third Update weather data 42 | station.updateMeasures(134, 150, -12); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/concrete/Alert.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer.concrete; 2 | 3 | import com.siriusxi.dp.behav.observer.Message; 4 | import com.siriusxi.dp.behav.observer.Observer; 5 | import com.siriusxi.dp.behav.observer.Subject; 6 | 7 | import static java.lang.System.out; 8 | 9 | public class Alert implements Observer { 10 | 11 | private final Subject station; 12 | 13 | public Alert(Subject station) { 14 | this.station = station; 15 | station.register(this); 16 | } 17 | 18 | public void unsubscribe() { 19 | station.remove(this); 20 | } 21 | 22 | @Override 23 | public void update(Message message) { 24 | if (message.temperature() <= 0 || 25 | message.pressure() >= 150 || 26 | message.windSpeed() >= 50) 27 | alert(message); 28 | } 29 | 30 | private void alert(Message message) { 31 | out.printf("Alert Critical Weather: [Temp %d, Pressure %d, Wind Speed %d]%n", 32 | message.temperature(), 33 | message.pressure(), 34 | message.windSpeed()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/concrete/BusinessApp.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer.concrete; 2 | 3 | import com.siriusxi.dp.behav.observer.Message; 4 | import com.siriusxi.dp.behav.observer.Observer; 5 | import com.siriusxi.dp.behav.observer.Subject; 6 | 7 | public class BusinessApp implements Observer { 8 | 9 | private final Subject station; 10 | 11 | public BusinessApp(Subject station) { 12 | this.station = station; 13 | station.register(this); 14 | } 15 | 16 | @Override 17 | public void update(Message message) { 18 | show(message); 19 | } 20 | 21 | public void unsubscribe() { 22 | station.remove(this); 23 | } 24 | 25 | private void show(Message message) { 26 | 27 | var finalMessage = """ 28 | Current Weather Forecast: 29 | * Temperature: %d 30 | * Wind Speed: %d 31 | * Pressure: %d 32 | """.formatted(message.temperature(), 33 | message.windSpeed(), 34 | message.pressure()); 35 | 36 | System.out.println(finalMessage); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/concrete/Logger.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer.concrete; 2 | 3 | import com.siriusxi.dp.behav.observer.Message; 4 | import com.siriusxi.dp.behav.observer.Observer; 5 | import com.siriusxi.dp.behav.observer.Subject; 6 | 7 | import static java.lang.System.out; 8 | 9 | public class Logger implements Observer { 10 | 11 | private final Subject station; 12 | 13 | public Logger(Subject station) { 14 | this.station = station; 15 | station.register(this); 16 | } 17 | 18 | public void unsubscribe() { 19 | station.remove(this); 20 | } 21 | 22 | @Override 23 | public void update(Message message) { 24 | log(message); 25 | } 26 | 27 | private void log(Message message) { 28 | out.printf("Logger: Current Weather measures: [Temperature %d, Pressure %d, Wind Speed " + 29 | "%d]%n", 30 | message.temperature(), 31 | message.pressure(), 32 | message.windSpeed()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/observer/concrete/UserInterface.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.observer.concrete; 2 | 3 | import com.siriusxi.dp.behav.observer.Message; 4 | import com.siriusxi.dp.behav.observer.Observer; 5 | import com.siriusxi.dp.behav.observer.Subject; 6 | 7 | public class UserInterface implements Observer { 8 | 9 | private final Subject station; 10 | 11 | public UserInterface(Subject station) { 12 | this.station = station; 13 | station.register(this); 14 | } 15 | 16 | @Override 17 | public void update(Message message) { 18 | display(message); 19 | } 20 | 21 | public void unsubscribe() { 22 | station.remove(this); 23 | } 24 | 25 | private void display(Message message) { 26 | 27 | var finalMessage = """ 28 |

Current Weather forecast UI

29 | """.formatted(message.temperature(), 34 | message.pressure(), 35 | message.windSpeed()); 36 | 37 | System.out.println(finalMessage); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/Fighter.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy; 2 | 3 | import com.siriusxi.dp.behav.strategy.algorithms.jump.JumpBehavior; 4 | import com.siriusxi.dp.behav.strategy.algorithms.kick.KickBehavior; 5 | import com.siriusxi.dp.behav.strategy.algorithms.roll.RollBehavior; 6 | import lombok.NoArgsConstructor; 7 | import lombok.NonNull; 8 | import lombok.RequiredArgsConstructor; 9 | import lombok.extern.java.Log; 10 | 11 | /** 12 | * Strategy Fighter class to be implemented, as you must have a specific fighter. 13 | * 14 | * @author Mohamed Taman 15 | */ 16 | @Log 17 | @NoArgsConstructor 18 | @RequiredArgsConstructor 19 | public abstract class Fighter { 20 | 21 | @NonNull 22 | protected JumpBehavior jumpBehavior; 23 | 24 | @NonNull 25 | protected KickBehavior kickBehavior; 26 | 27 | @NonNull 28 | protected RollBehavior rollBehavior; 29 | 30 | public void setBehavior(JumpBehavior jumpBehavior) { 31 | this.jumpBehavior = jumpBehavior; 32 | } 33 | 34 | public void setBehavior(KickBehavior kickBehavior) { 35 | this.kickBehavior = kickBehavior; 36 | } 37 | 38 | public void setBehavior(RollBehavior rollBehavior) { 39 | this.rollBehavior = rollBehavior; 40 | } 41 | 42 | public void jump() { 43 | // delegate to jump behavior 44 | jumpBehavior.jump(); 45 | } 46 | 47 | public void kick() { 48 | // delegate to kick behavior 49 | kickBehavior.kick(); 50 | } 51 | 52 | public void roll() { 53 | // delegate to roll behavior 54 | rollBehavior.roll(); 55 | } 56 | 57 | public void punch() { 58 | log.info("Performing a Quick punch!"); 59 | } 60 | 61 | public abstract void display(); 62 | } 63 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/StreetFightersSimulator.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy; 2 | 3 | import com.siriusxi.dp.behav.strategy.algorithms.jump.HighJump; 4 | import com.siriusxi.dp.behav.strategy.algorithms.jump.JumpBehavior; 5 | import com.siriusxi.dp.behav.strategy.algorithms.kick.KickBehavior; 6 | import com.siriusxi.dp.behav.strategy.fighters.Ken; 7 | import lombok.extern.java.Log; 8 | 9 | /** 10 | * Street Fighters game Simulator, 11 | * to demonstrate implementation of Strategy Pattern. 12 | * 13 | * @author mohamed_taman 14 | */ 15 | @Log 16 | public class StreetFightersSimulator { 17 | 18 | public static void main(String[] args) { 19 | 20 | // let us make some behaviors first 21 | JumpBehavior highJump = new HighJump(); 22 | 23 | // Make a fighter with default behaviors 24 | Fighter ken = new Ken(); 25 | ken.display(); 26 | 27 | // Test behaviors 28 | ken.punch(); 29 | ken.kick(); 30 | ken.jump(); 31 | ken.roll(); 32 | 33 | // Change behavior dynamically (algorithms are interchangeable) 34 | ken.setBehavior(highJump); 35 | ken.jump(); 36 | 37 | // Creating inline kick implementation 38 | KickBehavior backwardKick = () -> log.info("Performing a Backward Kick!"); 39 | ken.setBehavior(backwardKick); 40 | ken.kick(); 41 | 42 | //Returning to normal Kick behavior 43 | ken.setBehavior(KickBehavior.tornadoKick()); 44 | ken.kick(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/jump/HighJump.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.jump; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | @Log 6 | public class HighJump implements JumpBehavior { 7 | @Override 8 | public void jump() { 9 | log.info("Performing a High Jump!"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/jump/JumpBehavior.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.jump; 2 | 3 | /** 4 | * Encapsulated Jump behavior 5 | * 6 | * @author mohamed_taman 7 | */ 8 | public interface JumpBehavior { 9 | void jump(); 10 | } 11 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/jump/NoJump.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.jump; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | @Log 6 | public class NoJump implements JumpBehavior { 7 | @Override 8 | public void jump() { 9 | log.info("I am not Jumping!"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/jump/NormalJump.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.jump; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | @Log 6 | public class NormalJump implements JumpBehavior { 7 | 8 | @Override 9 | public void jump() { 10 | log.info("Performing a Short Jump!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/kick/KickBehavior.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.kick; 2 | 3 | /** 4 | * Encapsulated Kick behavior 5 | * 6 | * @author mohamed_taman 7 | */ 8 | public interface KickBehavior { 9 | void kick(); 10 | 11 | static KickBehavior normalKick() { 12 | return () -> System.out.println("Performing a Straight Kick!"); 13 | } 14 | 15 | static KickBehavior tornadoKick() { 16 | return () -> System.out.println("Performing a Tornado Kick!"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/kick/NormalKick.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.kick; 2 | 3 | 4 | import lombok.extern.java.Log; 5 | 6 | @Log 7 | public class NormalKick implements KickBehavior { 8 | @Override 9 | public void kick() { 10 | log.info("Performing a Straight Kick!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/kick/TornadoKick.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.kick; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | @Log 6 | public class TornadoKick implements KickBehavior { 7 | @Override 8 | public void kick() { 9 | log.info("Performing a Tornado Kick!"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/roll/NoRoll.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.roll; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | @Log 6 | public class NoRoll implements RollBehavior { 7 | @Override 8 | public void roll() { 9 | log.info("I am not Rolling!"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/roll/NormalRoll.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.roll; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | @Log 6 | public class NormalRoll implements RollBehavior { 7 | 8 | @Override 9 | public void roll() { 10 | log.info("Performing a Rolling!"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/algorithms/roll/RollBehavior.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.algorithms.roll; 2 | 3 | /** 4 | * Encapsulated Roll behavior 5 | * 6 | * @author mohamed_taman 7 | */ 8 | public interface RollBehavior { 9 | void roll(); 10 | } 11 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/fighters/ChunLi.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.fighters; 2 | 3 | import com.siriusxi.dp.behav.strategy.Fighter; 4 | import com.siriusxi.dp.behav.strategy.algorithms.jump.HighJump; 5 | import com.siriusxi.dp.behav.strategy.algorithms.jump.JumpBehavior; 6 | import com.siriusxi.dp.behav.strategy.algorithms.kick.KickBehavior; 7 | import com.siriusxi.dp.behav.strategy.algorithms.kick.NormalKick; 8 | import com.siriusxi.dp.behav.strategy.algorithms.roll.NormalRoll; 9 | import com.siriusxi.dp.behav.strategy.algorithms.roll.RollBehavior; 10 | import lombok.extern.java.Log; 11 | 12 | @Log 13 | public class ChunLi extends Fighter { 14 | 15 | public ChunLi() { 16 | this.jumpBehavior = new HighJump(); 17 | this.kickBehavior = new NormalKick(); 18 | this.rollBehavior = new NormalRoll(); 19 | } 20 | 21 | public ChunLi(JumpBehavior jumpBehavior, 22 | KickBehavior kickBehavior, 23 | RollBehavior rollBehavior) { 24 | super(jumpBehavior, kickBehavior, rollBehavior); 25 | } 26 | 27 | @Override 28 | public void display() { 29 | log.info("I am \"Chun-Li\"!"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/fighters/EHonda.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.fighters; 2 | 3 | 4 | import com.siriusxi.dp.behav.strategy.Fighter; 5 | import com.siriusxi.dp.behav.strategy.algorithms.jump.JumpBehavior; 6 | import com.siriusxi.dp.behav.strategy.algorithms.jump.NoJump; 7 | import com.siriusxi.dp.behav.strategy.algorithms.kick.KickBehavior; 8 | import com.siriusxi.dp.behav.strategy.algorithms.kick.NormalKick; 9 | import com.siriusxi.dp.behav.strategy.algorithms.roll.NoRoll; 10 | import com.siriusxi.dp.behav.strategy.algorithms.roll.RollBehavior; 11 | import lombok.extern.java.Log; 12 | 13 | @Log 14 | public class EHonda extends Fighter { 15 | 16 | public EHonda() { 17 | this.jumpBehavior = new NoJump(); 18 | this.kickBehavior = new NormalKick(); 19 | this.rollBehavior = new NoRoll(); 20 | } 21 | 22 | public EHonda(JumpBehavior jumpBehavior, 23 | KickBehavior kickBehavior, 24 | RollBehavior rollBehavior) { 25 | super(jumpBehavior, kickBehavior, rollBehavior); 26 | } 27 | 28 | @Override 29 | public void display() { 30 | log.info("I am a Sumo \"E.Honda\"!"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/fighters/Ken.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.fighters; 2 | 3 | import com.siriusxi.dp.behav.strategy.Fighter; 4 | import com.siriusxi.dp.behav.strategy.algorithms.jump.JumpBehavior; 5 | import com.siriusxi.dp.behav.strategy.algorithms.jump.NormalJump; 6 | import com.siriusxi.dp.behav.strategy.algorithms.kick.KickBehavior; 7 | import com.siriusxi.dp.behav.strategy.algorithms.kick.TornadoKick; 8 | import com.siriusxi.dp.behav.strategy.algorithms.roll.NormalRoll; 9 | import com.siriusxi.dp.behav.strategy.algorithms.roll.RollBehavior; 10 | import lombok.extern.java.Log; 11 | 12 | @Log 13 | public class Ken extends Fighter { 14 | 15 | public Ken() { 16 | this.jumpBehavior = new NormalJump(); 17 | this.kickBehavior = new TornadoKick(); 18 | this.rollBehavior = new NormalRoll(); 19 | } 20 | 21 | public Ken(JumpBehavior jumpBehavior, 22 | KickBehavior kickBehavior, 23 | RollBehavior rollBehavior) { 24 | super(jumpBehavior, kickBehavior, rollBehavior); 25 | } 26 | 27 | @Override 28 | public void display() { 29 | log.info("I am the Master \"Ken\"!"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /behavioral/src/main/java/com/siriusxi/dp/behav/strategy/fighters/Ryu.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.behav.strategy.fighters; 2 | 3 | import com.siriusxi.dp.behav.strategy.Fighter; 4 | import com.siriusxi.dp.behav.strategy.algorithms.jump.JumpBehavior; 5 | import com.siriusxi.dp.behav.strategy.algorithms.jump.NormalJump; 6 | import com.siriusxi.dp.behav.strategy.algorithms.kick.KickBehavior; 7 | import com.siriusxi.dp.behav.strategy.algorithms.kick.NormalKick; 8 | import com.siriusxi.dp.behav.strategy.algorithms.roll.NoRoll; 9 | import com.siriusxi.dp.behav.strategy.algorithms.roll.RollBehavior; 10 | import lombok.extern.java.Log; 11 | 12 | 13 | @Log 14 | public class Ryu extends Fighter { 15 | 16 | public Ryu() { 17 | this.jumpBehavior = new NormalJump(); 18 | this.kickBehavior = new NormalKick(); 19 | this.rollBehavior = new NoRoll(); 20 | } 21 | 22 | public Ryu(JumpBehavior jumpBehavior, 23 | KickBehavior kickBehavior, 24 | RollBehavior rollBehavior) { 25 | super(jumpBehavior, kickBehavior, rollBehavior); 26 | } 27 | 28 | @Override 29 | public void display() { 30 | log.info("I am \"Ryu\", Kens friend!"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.siriusxi.dp 8 | design-patterns 9 | pom 10 | 0.0.1-SNAPSHOT 11 | Design Pattern 12 | Design patterns project code examples 13 | 14 | 15 | behavioral 16 | principles 17 | structural 18 | 19 | 20 | 21 | 17 22 | UTF-8 23 | UTF-8 24 | 25 | 26 | 3.8.1 27 | 3.0.0-M5 28 | 3.0.0-M5 29 | 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | 1.18.20 35 | provided 36 | 37 | 38 | org.junit.jupiter 39 | junit-jupiter 40 | 5.8.1 41 | test 42 | 43 | 44 | 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-compiler-plugin 49 | ${maven.compiler.plugin.version} 50 | 51 | 52 | 53 | 54 | org.projectlombok 55 | lombok 56 | 1.18.20 57 | 58 | 59 | ${java.version} 60 | --enable-preview 61 | 62 | 63 | 64 | org.apache.maven.plugins 65 | maven-surefire-plugin 66 | ${maven.surefire.plugin.version} 67 | 68 | --enable-preview 69 | 70 | **/*Tests.java 71 | **/*Test.java 72 | 73 | 74 | 75 | 76 | org.apache.maven.plugins 77 | maven-failsafe-plugin 78 | ${maven.failsafe.plugin.version} 79 | 80 | --enable-preview 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /principles/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | design-patterns 7 | com.siriusxi.dp 8 | 0.0.1-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | principles 13 | 14 | -------------------------------------------------------------------------------- /principles/src/main/java/com/siriusxi/principle/coupling/RemoteSimulator.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.principle.coupling; 2 | 3 | import com.siriusxi.principle.coupling.loose.Device; 4 | import com.siriusxi.principle.coupling.loose.LCRemote; 5 | import com.siriusxi.principle.coupling.loose.LCTelevision; 6 | import com.siriusxi.principle.coupling.loose.Radio; 7 | import com.siriusxi.principle.coupling.tight.Remote; 8 | import com.siriusxi.principle.coupling.tight.Television; 9 | import lombok.extern.java.Log; 10 | 11 | @Log 12 | public class RemoteSimulator { 13 | 14 | public static void main(String[] args) { 15 | // Tight coupling implementation 16 | Television tv = new Television(); 17 | Remote remote = new Remote(tv); 18 | 19 | remote.switchOn(); 20 | log.info("Watching programs and eating popcorn!"); 21 | remote.switchOff(); 22 | 23 | // Loose coupling implementation 24 | log.info("---------------------------"); 25 | Device radio = new Radio(); 26 | Device lcTv = new LCTelevision(); 27 | 28 | LCRemote radioRemote = new LCRemote(radio); 29 | LCRemote tvRemote = new LCRemote(lcTv); 30 | 31 | radioRemote.switchOn(); 32 | log.info("Listening to Radio programs!"); 33 | radioRemote.switchOff(); 34 | 35 | tvRemote.switchOn(); 36 | log.info("Watching TV programs and eating popcorn!"); 37 | tvRemote.switchOff(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /principles/src/main/java/com/siriusxi/principle/coupling/loose/Device.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.principle.coupling.loose; 2 | 3 | public abstract class Device { 4 | 5 | public abstract void onDevice(); 6 | 7 | public abstract void offDevice(); 8 | 9 | public String type(){ 10 | return this.getClass().getSimpleName(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /principles/src/main/java/com/siriusxi/principle/coupling/loose/LCRemote.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.principle.coupling.loose; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | import java.util.Objects; 6 | 7 | /** 8 | * LC for loose coupling, just to make difference 9 | * from the Remote class in tight package. 10 | */ 11 | @Log 12 | public class LCRemote { 13 | 14 | private final Device device; 15 | 16 | 17 | 18 | public LCRemote(Device device){ 19 | 20 | this.device = Objects.requireNonNull(device, 21 | "Device can't be null"); 22 | } 23 | 24 | public void switchOn() { 25 | log.info("Switching on "+ device.type() + "..."); 26 | device.onDevice(); 27 | } 28 | 29 | public void switchOff() { 30 | log.info("Switching off " + device.type() + "..."); 31 | device.offDevice(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /principles/src/main/java/com/siriusxi/principle/coupling/loose/LCTelevision.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.principle.coupling.loose; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | /** 6 | * LC for loose coupling, just to make difference 7 | * from the Television class in tight package. 8 | */ 9 | @Log 10 | public class LCTelevision extends Device { 11 | 12 | private void on(){ 13 | log.info(type() + " is switched on."); 14 | } 15 | 16 | private void loadLastState(){ 17 | log.info(type() + " is loading last program."); 18 | } 19 | 20 | private void off(){ 21 | log.info(type() + " is switched off."); 22 | } 23 | 24 | private void saveCurrentState(){ 25 | log.info(type() + " is saving current program."); 26 | } 27 | 28 | @Override 29 | public void onDevice() { 30 | this.on(); 31 | this.loadLastState(); 32 | } 33 | 34 | @Override 35 | public void offDevice() { 36 | this.saveCurrentState(); 37 | this.off(); 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /principles/src/main/java/com/siriusxi/principle/coupling/loose/Radio.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.principle.coupling.loose; 2 | 3 | 4 | import lombok.extern.java.Log; 5 | 6 | @Log 7 | public class Radio extends Device { 8 | 9 | private void on() { 10 | log.info(type() + " is switched on."); 11 | } 12 | 13 | private void off() { 14 | log.info(type() + " is switched off."); 15 | } 16 | 17 | @Override 18 | public void onDevice() { 19 | this.on(); 20 | } 21 | 22 | @Override 23 | public void offDevice() { 24 | this.off(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /principles/src/main/java/com/siriusxi/principle/coupling/tight/Remote.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.principle.coupling.tight; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | import java.util.Objects; 6 | 7 | @Log 8 | public class Remote { 9 | 10 | private final Television television; 11 | 12 | public Remote(){ 13 | television = new Television(); 14 | } 15 | 16 | public Remote(Television tv){ 17 | 18 | television = Objects.requireNonNull(tv, 19 | "Television instance can't be null"); 20 | } 21 | 22 | public void switchOn() { 23 | log.info("Switching on TV..."); 24 | television.on(); 25 | television.loadLastState(); 26 | } 27 | 28 | public void switchOff() { 29 | log.info("Switching off TV..."); 30 | television.saveCurrentState(); 31 | television.off(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /principles/src/main/java/com/siriusxi/principle/coupling/tight/Television.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.principle.coupling.tight; 2 | 3 | import lombok.extern.java.Log; 4 | 5 | @Log 6 | public class Television { 7 | 8 | public void on(){ 9 | log.info("TV is switched on."); 10 | } 11 | 12 | public void loadLastState(){ 13 | log.info("TV is loading last program."); 14 | } 15 | 16 | public void off(){ 17 | log.info("TV is switched off."); 18 | } 19 | 20 | public void saveCurrentState(){ 21 | log.info("TV is saving current program."); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /structural/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | design-patterns 7 | com.siriusxi.dp 8 | 0.0.1-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | structural 13 | 14 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/adapter/AmericanCity.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.adapter; 2 | 3 | public class AmericanCity implements City { 4 | 5 | private final String name; 6 | private final double temperature; 7 | private boolean hasWarning; 8 | 9 | public AmericanCity(String name, double temperature) { 10 | this.name = name; 11 | this.temperature = temperature; 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | @Override 20 | public double getTemperature() { 21 | return temperature; 22 | } 23 | 24 | @Override 25 | public boolean hasWeatherWarning() { 26 | return hasWarning; 27 | } 28 | 29 | @Override 30 | public void setWeatherWarning(boolean hasWarning) { 31 | this.hasWarning = hasWarning; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/adapter/CelsiusToFahrenheitCityAdapter.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.adapter; 2 | 3 | public class CelsiusToFahrenheitCityAdapter implements City{ 4 | 5 | private final City city; 6 | 7 | public CelsiusToFahrenheitCityAdapter(City city) { 8 | this.city = city; 9 | } 10 | 11 | @Override 12 | public String getName() { 13 | return city.getName(); 14 | } 15 | 16 | @Override 17 | public double getTemperature() { 18 | return city.getTemperature() * 1.8 + 32; 19 | } 20 | 21 | @Override 22 | public boolean hasWeatherWarning() { 23 | return city.hasWeatherWarning(); 24 | } 25 | 26 | @Override 27 | public void setWeatherWarning(boolean hasWarning) { 28 | city.setWeatherWarning(hasWarning); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/adapter/City.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.adapter; 2 | 3 | public interface City { 4 | String getName(); 5 | double getTemperature(); 6 | default String getTemperatureScale(){ 7 | return "Fahrenheit"; 8 | } 9 | boolean hasWeatherWarning(); 10 | void setWeatherWarning(boolean hasWarning); 11 | } 12 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/adapter/MiddleEastCity.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.adapter; 2 | 3 | public class MiddleEastCity implements City { 4 | 5 | private final String name; 6 | private final double temperature; 7 | private boolean hasWarning; 8 | 9 | public MiddleEastCity(String name, double temperature) { 10 | this.name = name; 11 | this.temperature = temperature; 12 | } 13 | 14 | @Override 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | @Override 20 | public double getTemperature() { 21 | return temperature; 22 | } 23 | 24 | @Override 25 | public String getTemperatureScale() { 26 | return "Celsius"; 27 | } 28 | 29 | @Override 30 | public boolean hasWeatherWarning() { 31 | return hasWarning; 32 | } 33 | 34 | @Override 35 | public void setWeatherWarning(boolean hasWarning) { 36 | this.hasWarning = hasWarning; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/adapter/WeatherFeeder.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.adapter; 2 | 3 | import java.util.Objects; 4 | 5 | public final class WeatherFeeder { 6 | public static final double MAX_TEMPERATURE = 100; 7 | public static final double MIN_TEMPERATURE = 16; 8 | 9 | private WeatherFeeder() { 10 | } 11 | 12 | public static void postWarning(City city){ 13 | Objects.requireNonNull(city, "City cannot be null"); 14 | var message = ""; 15 | if (city.getTemperature() >= MAX_TEMPERATURE || 16 | city.getTemperature() <= MIN_TEMPERATURE) { 17 | 18 | message = "Warning! The current temperature in %s is %.1f %s." 19 | .formatted(city.getName(), 20 | city.getTemperature(), 21 | city.getTemperatureScale()); 22 | 23 | city.setWeatherWarning(true); 24 | } else 25 | message = "The temperature in %s is OK.".formatted(city.getName()); 26 | 27 | System.out.println(message); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/adapter/WeatherStation.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.adapter; 2 | 3 | public class WeatherStation { 4 | 5 | public static void main(String[] args) { 6 | 7 | WeatherFeeder.postWarning(new AmericanCity("San Francisco",15.2)); 8 | 9 | WeatherFeeder.postWarning(new AmericanCity("Atlanta",70.6)); 10 | 11 | WeatherFeeder.postWarning(new AmericanCity("New York",104.3)); 12 | 13 | City kuwait = new CelsiusToFahrenheitCityAdapter(new MiddleEastCity("Kuwait",50)); 14 | WeatherFeeder.postWarning(kuwait); 15 | 16 | City cairo = new CelsiusToFahrenheitCityAdapter(new MiddleEastCity("Cairo",35.2)); 17 | WeatherFeeder.postWarning(cairo); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/CondimentDecorator.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator; 2 | 3 | public abstract class CondimentDecorator extends Drink { 4 | public abstract String getIngredients(); 5 | } 6 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/Drink.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator; 2 | 3 | /** 4 | * This abstract class Drink defines the functionality of Drink implemented by decorator 5 | */ 6 | public abstract class Drink { 7 | protected String ingredients = "Unknown Drink"; 8 | 9 | /** 10 | * @return the ingredients of the drink 11 | */ 12 | public String getIngredients() { 13 | return ingredients; 14 | } 15 | 16 | /** 17 | * @return the cost of the drink 18 | */ 19 | public abstract double cost(); 20 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/FuzzBuzzCoffeeShop.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator; 2 | 3 | import com.siriusxi.dp.structural.decorator.component.Espresso; 4 | import com.siriusxi.dp.structural.decorator.condiment.Mocha; 5 | import com.siriusxi.dp.structural.decorator.condiment.Sprinkles; 6 | 7 | public class FuzzBuzzCoffeeShop { 8 | 9 | public static void main(String... args) { 10 | 11 | Drink espresso = new Espresso(); 12 | espresso = new Sprinkles(espresso); 13 | espresso = new Mocha(espresso); 14 | espresso = new Mocha(espresso); 15 | 16 | System.out.printf(""" 17 | Coffee Ingredients: %s. 18 | Cost: $ %.2f%n""", 19 | espresso.getIngredients(), 20 | espresso.cost()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/component/DarkRoast.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.component; 2 | 3 | import com.siriusxi.dp.structural.decorator.Drink; 4 | 5 | public class DarkRoast extends Drink { 6 | 7 | public DarkRoast() { 8 | ingredients = "Dark Roast Coffee"; 9 | } 10 | 11 | @Override 12 | public double cost() { 13 | return 2.00; 14 | } 15 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/component/Decaf.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.component; 2 | 3 | import com.siriusxi.dp.structural.decorator.Drink; 4 | 5 | public class Decaf extends Drink { 6 | 7 | public Decaf() { 8 | ingredients = "Decaffeinated Coffee"; 9 | } 10 | 11 | @Override 12 | public double cost() { 13 | return 2.25; 14 | } 15 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/component/Espresso.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.component; 2 | 3 | import com.siriusxi.dp.structural.decorator.Drink; 4 | 5 | public class Espresso extends Drink { 6 | 7 | public Espresso() { 8 | ingredients = "Espresso Coffee"; 9 | } 10 | 11 | @Override 12 | public double cost() { 13 | return 4.00; 14 | } 15 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/component/HouseBlend.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.component; 2 | 3 | import com.siriusxi.dp.structural.decorator.Drink; 4 | 5 | public class HouseBlend extends Drink { 6 | 7 | public HouseBlend() { 8 | ingredients = "House Blend Coffee"; 9 | } 10 | 11 | @Override 12 | public double cost() { 13 | return 1.49; 14 | } 15 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/condiment/Milk.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.condiment; 2 | 3 | import com.siriusxi.dp.structural.decorator.CondimentDecorator; 4 | import com.siriusxi.dp.structural.decorator.Drink; 5 | 6 | public class Milk extends CondimentDecorator { 7 | Drink drink; 8 | 9 | public Milk(Drink drink) { 10 | this.drink = drink; 11 | } 12 | 13 | @Override 14 | public String getIngredients() { 15 | return drink.getIngredients().concat(", Milk"); 16 | } 17 | 18 | @Override 19 | public double cost() { 20 | return drink.cost() + .30; 21 | } 22 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/condiment/Mocha.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.condiment; 2 | 3 | import com.siriusxi.dp.structural.decorator.CondimentDecorator; 4 | import com.siriusxi.dp.structural.decorator.Drink; 5 | 6 | public class Mocha extends CondimentDecorator { 7 | Drink drink; 8 | 9 | public Mocha(Drink drink) { 10 | this.drink = drink; 11 | } 12 | 13 | @Override 14 | public String getIngredients() { 15 | return drink.getIngredients().concat(", Mocha"); 16 | } 17 | 18 | @Override 19 | public double cost() { 20 | return drink.cost() + .18; 21 | } 22 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/condiment/Sprinkles.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.condiment; 2 | 3 | import com.siriusxi.dp.structural.decorator.CondimentDecorator; 4 | import com.siriusxi.dp.structural.decorator.Drink; 5 | 6 | public class Sprinkles extends CondimentDecorator { 7 | Drink drink; 8 | 9 | public Sprinkles(Drink drink) { 10 | this.drink = drink; 11 | } 12 | 13 | @Override 14 | public String getIngredients() { 15 | return drink.getIngredients().concat(", Sprinkles"); 16 | } 17 | 18 | @Override 19 | public double cost() { 20 | return drink.cost() + .20; 21 | } 22 | } -------------------------------------------------------------------------------- /structural/src/main/java/com/siriusxi/dp/structural/decorator/condiment/Whip.java: -------------------------------------------------------------------------------- 1 | package com.siriusxi.dp.structural.decorator.condiment; 2 | 3 | import com.siriusxi.dp.structural.decorator.CondimentDecorator; 4 | import com.siriusxi.dp.structural.decorator.Drink; 5 | 6 | public class Whip extends CondimentDecorator { 7 | Drink drink; 8 | 9 | public Whip(Drink drink) { 10 | this.drink = drink; 11 | } 12 | 13 | @Override 14 | public String getIngredients() { 15 | return drink.getIngredients().concat(", Whip"); 16 | } 17 | 18 | @Override 19 | public double cost() { 20 | return drink.cost() + .10; 21 | } 22 | } --------------------------------------------------------------------------------