├── .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 |
30 | - Temperature: %d
31 | - Pressure: %d
32 | - Wind Speed: %d
33 |
""".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 | }
--------------------------------------------------------------------------------