diff --git a/chapter1/jongwoon/strategy/src/adventureGame/GameSimulator.java b/chapter1/jongwoon/strategy/src/adventureGame/GameSimulator.java new file mode 100644 index 0000000..8bd3e10 --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/GameSimulator.java @@ -0,0 +1,18 @@ +package adventureGame; + +import adventureGame.domain.character.Character; +import adventureGame.domain.character.King; +import adventureGame.domain.character.Queen; +import adventureGame.domain.weapon.BowAndArrowBehavior; + +public class GameSimulator { + public static void main(String[] args) { + Character king = new King(); + Character queen = new Queen(); + king.fight(queen); + + king.changeWeapon(new BowAndArrowBehavior()); + king.fight(queen); + queen.fight(king); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Character.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Character.java new file mode 100644 index 0000000..36202f1 --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Character.java @@ -0,0 +1,23 @@ +package adventureGame.domain.character; + +import adventureGame.domain.weapon.WeaponBehavior; + +public abstract class Character { + String name; + WeaponBehavior weapon; + + public void fight(Character character) { + System.out.println(name + "이 무기를 사용하여 공격하였습니다."); + weapon.useWeapon(); + character.attacked(); + } + + public void changeWeapon(WeaponBehavior weapon) { + System.out.println(name + "이 무기를 교체하였습니다."); + this.weapon = weapon; + } + + private void attacked() { + System.out.println(name + "이 피해를 입었습니다."); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/character/King.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/King.java new file mode 100644 index 0000000..597ceb3 --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/King.java @@ -0,0 +1,11 @@ +package adventureGame.domain.character; + +import adventureGame.domain.weapon.SwordBehavior; + +public class King extends Character { + + public King() { + name = "king"; + weapon = new SwordBehavior(); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Knight.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Knight.java new file mode 100644 index 0000000..96f6a9d --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Knight.java @@ -0,0 +1,10 @@ +package adventureGame.domain.character; + +import adventureGame.domain.weapon.BowAndArrowBehavior; + +public class Knight extends Character { + public Knight() { + name = "knight"; + weapon = new BowAndArrowBehavior(); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Queen.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Queen.java new file mode 100644 index 0000000..7da0e4a --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Queen.java @@ -0,0 +1,11 @@ +package adventureGame.domain.character; + +import adventureGame.domain.weapon.KnifeBehavior; + +public class Queen extends Character { + + public Queen() { + name = "queen"; + weapon = new KnifeBehavior(); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Troll.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Troll.java new file mode 100644 index 0000000..4f7f8d0 --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/character/Troll.java @@ -0,0 +1,11 @@ +package adventureGame.domain.character; + +import adventureGame.domain.weapon.AxeBehavior; + +public class Troll extends Character { + + public Troll() { + name = "troll"; + weapon = new AxeBehavior(); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/AxeBehavior.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/AxeBehavior.java new file mode 100644 index 0000000..92d90b3 --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/AxeBehavior.java @@ -0,0 +1,8 @@ +package adventureGame.domain.weapon; + +public class AxeBehavior implements WeaponBehavior { + @Override + public void useWeapon() { + System.out.println("도끼로 내려찍기!"); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/BowAndArrowBehavior.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/BowAndArrowBehavior.java new file mode 100644 index 0000000..966659c --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/BowAndArrowBehavior.java @@ -0,0 +1,8 @@ +package adventureGame.domain.weapon; + +public class BowAndArrowBehavior implements WeaponBehavior { + @Override + public void useWeapon() { + System.out.println("활 쏘기!"); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/KnifeBehavior.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/KnifeBehavior.java new file mode 100644 index 0000000..67acd2e --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/KnifeBehavior.java @@ -0,0 +1,8 @@ +package adventureGame.domain.weapon; + +public class KnifeBehavior implements WeaponBehavior { + @Override + public void useWeapon() { + System.out.println("칼로 찌르기!"); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/SwordBehavior.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/SwordBehavior.java new file mode 100644 index 0000000..5614207 --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/SwordBehavior.java @@ -0,0 +1,8 @@ +package adventureGame.domain.weapon; + +public class SwordBehavior implements WeaponBehavior { + @Override + public void useWeapon() { + System.out.println("칼로 베기!"); + } +} diff --git a/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/WeaponBehavior.java b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/WeaponBehavior.java new file mode 100644 index 0000000..dd839ef --- /dev/null +++ b/chapter1/jongwoon/strategy/src/adventureGame/domain/weapon/WeaponBehavior.java @@ -0,0 +1,5 @@ +package adventureGame.domain.weapon; + +public interface WeaponBehavior { + void useWeapon(); +} diff --git a/chapter1/jongwoon/strategy/strategy.iml b/chapter1/jongwoon/strategy/strategy.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/chapter1/jongwoon/strategy/strategy.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter2/chapter2.iml b/chapter2/chapter2.iml new file mode 100644 index 0000000..cec3b1a --- /dev/null +++ b/chapter2/chapter2.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter2/jongwoon/src/main/java/Main.java b/chapter2/jongwoon/src/main/java/Main.java new file mode 100644 index 0000000..137758a --- /dev/null +++ b/chapter2/jongwoon/src/main/java/Main.java @@ -0,0 +1,16 @@ +import observer.Observer; +import observer.ObserverConcrete; +import subject.Subject; +import subject.SubjectConcrete; + +public class Main { + public static void main(String[] args) { + Subject subject = new SubjectConcrete(); + Observer observer1 = new ObserverConcrete("관찰자 1"); + Observer observer2 = new ObserverConcrete("관찰자 2"); + subject.addObserver(observer1); + subject.addObserver(observer2); + + subject.notifyObservers(); + } +} \ No newline at end of file diff --git a/chapter2/jongwoon/src/main/java/observer/Observer.java b/chapter2/jongwoon/src/main/java/observer/Observer.java new file mode 100644 index 0000000..cb19107 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/observer/Observer.java @@ -0,0 +1,5 @@ +package observer; + +public interface Observer { + void update(); +} diff --git a/chapter2/jongwoon/src/main/java/observer/ObserverConcrete.java b/chapter2/jongwoon/src/main/java/observer/ObserverConcrete.java new file mode 100644 index 0000000..4d075eb --- /dev/null +++ b/chapter2/jongwoon/src/main/java/observer/ObserverConcrete.java @@ -0,0 +1,15 @@ +package observer; + +public class ObserverConcrete implements Observer { + + String name; + + public ObserverConcrete(String name) { + this.name = name; + } + + @Override + public void update() { + System.out.println(name + "에게 발송 되었습니다."); + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/StockApp.java b/chapter2/jongwoon/src/main/java/stock/StockApp.java new file mode 100644 index 0000000..79b5858 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/StockApp.java @@ -0,0 +1,25 @@ +package stock; + +import stock.observer.Customer; +import stock.observer.StockCustomer; +import stock.stocks.repository.StocksRepository; +import stock.subject.Brokerage; +import stock.subject.SamsungBrokerage; + +public class StockApp { + public static void main(String[] args) { + Brokerage brokerage = new SamsungBrokerage(); + StockCustomer customer1 = new Customer("김봉팔"); + StockCustomer customer2 = new Customer("김사지"); + customer1.addStocks(StocksRepository.STOCKS_MAP.get("Kakao")); + customer1.addStocks(StocksRepository.STOCKS_MAP.get("Samsung")); + + customer2.addStocks(StocksRepository.STOCKS_MAP.get("Kakao")); + customer2.addStocks(StocksRepository.STOCKS_MAP.get("Samsung")); + customer2.addStocks(StocksRepository.STOCKS_MAP.get("Tesla")); + + brokerage.addCustomer(customer1); + brokerage.addCustomer(customer2); + brokerage.notifyToCustomer(); + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/observer/Customer.java b/chapter2/jongwoon/src/main/java/stock/observer/Customer.java new file mode 100644 index 0000000..57b8ba3 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/observer/Customer.java @@ -0,0 +1,18 @@ +package stock.observer; + +import stock.stocks.Stocks; + +public class Customer extends StockCustomer { + + public Customer(String customerName) { + super(customerName); + } + + @Override + public void update() { + System.out.println(customerName + "의 포트폴리오"); + for (Stocks stock : stockList) { + System.out.println(stock); + } + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/observer/StockCustomer.java b/chapter2/jongwoon/src/main/java/stock/observer/StockCustomer.java new file mode 100644 index 0000000..2c9d41b --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/observer/StockCustomer.java @@ -0,0 +1,21 @@ +package stock.observer; + +import stock.stocks.Stocks; + +import java.util.ArrayList; +import java.util.List; + +public abstract class StockCustomer { + String customerName; + List stockList = new ArrayList<>(); + + public StockCustomer(String customerName) { + this.customerName = customerName; + } + + public abstract void update(); + + public void addStocks(Stocks stocks) { + stockList.add(stocks); + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/stocks/Kakao.java b/chapter2/jongwoon/src/main/java/stock/stocks/Kakao.java new file mode 100644 index 0000000..c7e0c37 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/stocks/Kakao.java @@ -0,0 +1,10 @@ +package stock.stocks; + +import java.math.BigDecimal; + +public class Kakao extends Stocks { + public Kakao(BigDecimal stockPrice) { + super(stockPrice); + stockName = "카카오 주식"; + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/stocks/Samsung.java b/chapter2/jongwoon/src/main/java/stock/stocks/Samsung.java new file mode 100644 index 0000000..dddb3f7 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/stocks/Samsung.java @@ -0,0 +1,10 @@ +package stock.stocks; + +import java.math.BigDecimal; + +public class Samsung extends Stocks { + public Samsung(BigDecimal stockPrice) { + super(stockPrice); + stockName = "삼성 주식"; + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/stocks/Stocks.java b/chapter2/jongwoon/src/main/java/stock/stocks/Stocks.java new file mode 100644 index 0000000..ab2631a --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/stocks/Stocks.java @@ -0,0 +1,36 @@ +package stock.stocks; + +import java.math.BigDecimal; +import java.util.Random; + +public abstract class Stocks { + protected String stockName; + protected BigDecimal stockPrice; + + public Stocks(BigDecimal stockPrice) { + this.stockPrice = stockPrice; + } + + public void changeStockPrice() { + int randomMenu = new Random().nextInt(2) + 1; + int dollar = new Random().nextInt(2); + switch (randomMenu) { + case 1: + BigDecimal addMoney = BigDecimal.valueOf(new Random().nextDouble() + dollar); + stockPrice = stockPrice.add(addMoney); + break; + case 2: + BigDecimal subtractMoney = BigDecimal.valueOf(new Random().nextDouble() + dollar); + stockPrice = stockPrice.subtract(subtractMoney); + break; + } + } + + @Override + public String toString() { + return "Stocks{" + + "stockName='" + stockName + '\'' + + ", stockPrice=" + Math.round(stockPrice.doubleValue() * 100) / 100.0 + + '}'; + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/stocks/Tesla.java b/chapter2/jongwoon/src/main/java/stock/stocks/Tesla.java new file mode 100644 index 0000000..efd6559 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/stocks/Tesla.java @@ -0,0 +1,10 @@ +package stock.stocks; + +import java.math.BigDecimal; + +public class Tesla extends Stocks { + public Tesla(BigDecimal stockPrice) { + super(stockPrice); + stockName = "테슬라 주식"; + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/stocks/repository/StocksRepository.java b/chapter2/jongwoon/src/main/java/stock/stocks/repository/StocksRepository.java new file mode 100644 index 0000000..06fe0af --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/stocks/repository/StocksRepository.java @@ -0,0 +1,24 @@ +package stock.stocks.repository; + +import stock.stocks.Kakao; +import stock.stocks.Samsung; +import stock.stocks.Stocks; +import stock.stocks.Tesla; + +import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.Map; + +public class StocksRepository { + public static final Map STOCKS_MAP = new LinkedHashMap<>(); + + static { + STOCKS_MAP.put("Kakao", new Kakao(new BigDecimal("43.8"))); + STOCKS_MAP.put("Samsung", new Samsung(new BigDecimal("55.91"))); + STOCKS_MAP.put("Tesla", new Tesla(new BigDecimal("244.4"))); + + STOCKS_MAP.forEach((a, b) -> { + System.out.println(a + "의 첫 주가 : " + b); + }); + } +} diff --git a/chapter2/jongwoon/src/main/java/stock/subject/Brokerage.java b/chapter2/jongwoon/src/main/java/stock/subject/Brokerage.java new file mode 100644 index 0000000..2a17e15 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/subject/Brokerage.java @@ -0,0 +1,11 @@ +package stock.subject; + +import stock.observer.StockCustomer; + +public interface Brokerage { + void addCustomer(StockCustomer customer); + + void removeCustomer(StockCustomer customer); + + void notifyToCustomer(); +} diff --git a/chapter2/jongwoon/src/main/java/stock/subject/SamsungBrokerage.java b/chapter2/jongwoon/src/main/java/stock/subject/SamsungBrokerage.java new file mode 100644 index 0000000..18b5609 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/stock/subject/SamsungBrokerage.java @@ -0,0 +1,42 @@ +package stock.subject; + +import stock.observer.StockCustomer; +import stock.stocks.Stocks; +import stock.stocks.repository.StocksRepository; + +import java.util.ArrayList; +import java.util.List; + +public class SamsungBrokerage implements Brokerage { + + List stocksList; + List customers; + + public SamsungBrokerage() { + stocksList = new ArrayList<>(); + customers = new ArrayList<>(); + StocksRepository.STOCKS_MAP.forEach((a, b) -> { + stocksList.add(b); + }); + } + + @Override + public void addCustomer(StockCustomer customer) { + customers.add(customer); + } + + @Override + public void removeCustomer(StockCustomer customer) { + customers.remove(customer); + } + + @Override + public void notifyToCustomer() { + for (Stocks stock : stocksList) { + stock.changeStockPrice(); + } + for (StockCustomer customer : customers) { + customer.update(); + } + } +} diff --git a/chapter2/jongwoon/src/main/java/subject/Subject.java b/chapter2/jongwoon/src/main/java/subject/Subject.java new file mode 100644 index 0000000..57b467a --- /dev/null +++ b/chapter2/jongwoon/src/main/java/subject/Subject.java @@ -0,0 +1,10 @@ +package subject; + +import observer.Observer; + +public interface Subject { + + void addObserver(Observer observer); + void removeObserver(Observer observer); + void notifyObservers(); +} diff --git a/chapter2/jongwoon/src/main/java/subject/SubjectConcrete.java b/chapter2/jongwoon/src/main/java/subject/SubjectConcrete.java new file mode 100644 index 0000000..6222293 --- /dev/null +++ b/chapter2/jongwoon/src/main/java/subject/SubjectConcrete.java @@ -0,0 +1,33 @@ +package subject; + +import observer.Observer; + +import java.util.ArrayList; +import java.util.List; + +public class SubjectConcrete implements Subject { + + List observerList; + String msg; + + public SubjectConcrete() { + observerList = new ArrayList<>(); + } + + @Override + public void addObserver(Observer observer) { + observerList.add(observer); + } + + @Override + public void removeObserver(Observer observer) { + observerList.remove(observer); + } + + @Override + public void notifyObservers() { + for(Observer observer : observerList) { + observer.update(); + } + } +} diff --git a/chapter3/chapter3.iml b/chapter3/chapter3.iml new file mode 100644 index 0000000..5abffe5 --- /dev/null +++ b/chapter3/chapter3.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter3/jongwoon/jongwoon.iml b/chapter3/jongwoon/jongwoon.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/chapter3/jongwoon/jongwoon.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter3/jongwoon/src/Main.java b/chapter3/jongwoon/src/Main.java new file mode 100644 index 0000000..2999a1d --- /dev/null +++ b/chapter3/jongwoon/src/Main.java @@ -0,0 +1,13 @@ +import decorator.Weapon.*; + +public class Main { + public static void main(String[] args) { + Weapon weapon = new Buttstock(new BaseWeapon()); + weapon.aimAndFire(); + + System.out.println("============="); + + Weapon weapon2 = new Buttstock(new Scoped(new Grenade(new BaseWeapon()))); + weapon2.aimAndFire(); + } +} \ No newline at end of file diff --git a/chapter3/jongwoon/src/decorator/Weapon/BaseWeapon.java b/chapter3/jongwoon/src/decorator/Weapon/BaseWeapon.java new file mode 100644 index 0000000..f6ae82d --- /dev/null +++ b/chapter3/jongwoon/src/decorator/Weapon/BaseWeapon.java @@ -0,0 +1,8 @@ +package decorator.Weapon; + +public class BaseWeapon implements Weapon { + @Override + public void aimAndFire() { + System.out.println("총알 발사!!"); + } +} diff --git a/chapter3/jongwoon/src/decorator/Weapon/Buttstock.java b/chapter3/jongwoon/src/decorator/Weapon/Buttstock.java new file mode 100644 index 0000000..0e4fc7c --- /dev/null +++ b/chapter3/jongwoon/src/decorator/Weapon/Buttstock.java @@ -0,0 +1,18 @@ +package decorator.Weapon; + +public class Buttstock extends WeaponAccessory { + + public Buttstock(Weapon weapon) { + super(weapon); + } + + @Override + public void aimAndFire() { + holding(); + super.aimAndFire(); + } + + public void holding() { + System.out.println("견착 중"); + } +} diff --git a/chapter3/jongwoon/src/decorator/Weapon/Grenade.java b/chapter3/jongwoon/src/decorator/Weapon/Grenade.java new file mode 100644 index 0000000..5efcfd8 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/Weapon/Grenade.java @@ -0,0 +1,18 @@ +package decorator.Weapon; + +public class Grenade extends WeaponAccessory { + + public Grenade(Weapon weapon) { + super(weapon); + } + + @Override + public void aimAndFire() { + super.aimAndFire(); + grenade(); + } + + void grenade() { + System.out.println("유탄 발사!!"); + } +} diff --git a/chapter3/jongwoon/src/decorator/Weapon/Scoped.java b/chapter3/jongwoon/src/decorator/Weapon/Scoped.java new file mode 100644 index 0000000..8de06a8 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/Weapon/Scoped.java @@ -0,0 +1,18 @@ +package decorator.Weapon; + +public class Scoped extends WeaponAccessory { + + public Scoped(Weapon weapon) { + super(weapon); + } + + @Override + public void aimAndFire() { + scope(); + super.aimAndFire(); + } + + void scope() { + System.out.println("조준 중"); + } +} diff --git a/chapter3/jongwoon/src/decorator/Weapon/Weapon.java b/chapter3/jongwoon/src/decorator/Weapon/Weapon.java new file mode 100644 index 0000000..f901015 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/Weapon/Weapon.java @@ -0,0 +1,5 @@ +package decorator.Weapon; + +public interface Weapon { + void aimAndFire(); +} diff --git a/chapter3/jongwoon/src/decorator/Weapon/WeaponAccessory.java b/chapter3/jongwoon/src/decorator/Weapon/WeaponAccessory.java new file mode 100644 index 0000000..4b81326 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/Weapon/WeaponAccessory.java @@ -0,0 +1,14 @@ +package decorator.Weapon; + +public abstract class WeaponAccessory implements Weapon{ + private Weapon weapon; + + public WeaponAccessory(Weapon weapon) { + this.weapon = weapon; + } + + @Override + public void aimAndFire() { + weapon.aimAndFire(); + } +} diff --git a/chapter3/jongwoon/src/decorator/Weapon/WeaponGame.java b/chapter3/jongwoon/src/decorator/Weapon/WeaponGame.java new file mode 100644 index 0000000..13bbfd3 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/Weapon/WeaponGame.java @@ -0,0 +1,13 @@ +package decorator.Weapon; + +public class WeaponGame { + public static void main(String[] args) { + Weapon weapon = new Buttstock(new BaseWeapon()); + weapon.aimAndFire(); + + System.out.println("============="); + + Weapon weapon2 = new Buttstock(new Scoped(new Grenade(new BaseWeapon()))); + weapon2.aimAndFire(); + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/Beverage.java b/chapter3/jongwoon/src/decorator/coffee/Beverage.java new file mode 100644 index 0000000..c11816a --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/Beverage.java @@ -0,0 +1,18 @@ +package decorator.coffee; + +public abstract class Beverage { + protected String name = ""; + protected Size size; + + public enum Size {TALL, GRANDE, VENTI}; + + public String getName() { + return name; + } + + public Size getSize() { + return size; + } + + public abstract double cost(); +} diff --git a/chapter3/jongwoon/src/decorator/coffee/CoffeeStore.java b/chapter3/jongwoon/src/decorator/coffee/CoffeeStore.java new file mode 100644 index 0000000..6a947b1 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/CoffeeStore.java @@ -0,0 +1,9 @@ +package decorator.coffee; + +public class CoffeeStore { + public static void main(String[] args) { + Beverage beverage = new Soybean(new Whip(new Mocha(new DarkRoast(Beverage.Size.VENTI)))); + + System.out.println(beverage.getName() + " " + beverage.cost()); + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/CondimentDecorator.java b/chapter3/jongwoon/src/decorator/coffee/CondimentDecorator.java new file mode 100644 index 0000000..9dca29d --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/CondimentDecorator.java @@ -0,0 +1,14 @@ +package decorator.coffee; + +public abstract class CondimentDecorator extends Beverage { + Beverage beverage; + + public CondimentDecorator(Beverage beverage) { + this.beverage = beverage; + } + public abstract String getName(); + + public Size getSize() { + return beverage.getSize(); + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/DarkRoast.java b/chapter3/jongwoon/src/decorator/coffee/DarkRoast.java new file mode 100644 index 0000000..868ae74 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/DarkRoast.java @@ -0,0 +1,18 @@ +package decorator.coffee; + +public class DarkRoast extends Beverage { + + public DarkRoast() { + this(Size.TALL); + } + + public DarkRoast(Size size) { + this.size = size; + name = "다크 로스트 커피"; + } + + @Override + public double cost() { + return .99; + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/Decaf.java b/chapter3/jongwoon/src/decorator/coffee/Decaf.java new file mode 100644 index 0000000..c1fd7cc --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/Decaf.java @@ -0,0 +1,18 @@ +package decorator.coffee; + +public class Decaf extends Beverage { + + public Decaf() { + this(Size.TALL); + } + + public Decaf(Size size) { + this.size = size; + name = "디카페인 커피"; + } + + @Override + public double cost() { + return 1.05; + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/Espresso.java b/chapter3/jongwoon/src/decorator/coffee/Espresso.java new file mode 100644 index 0000000..cbe4653 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/Espresso.java @@ -0,0 +1,18 @@ +package decorator.coffee; + +public class Espresso extends Beverage { + + public Espresso() { + this(Size.TALL); + } + + public Espresso(Size size) { + this.size = size; + name = "에스프레소 커피"; + } + + @Override + public double cost() { + return 1.99; + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/HouseBlend.java b/chapter3/jongwoon/src/decorator/coffee/HouseBlend.java new file mode 100644 index 0000000..2c46d91 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/HouseBlend.java @@ -0,0 +1,17 @@ +package decorator.coffee; + +public class HouseBlend extends Beverage { + + public HouseBlend() { + this(Size.TALL); + } + + public HouseBlend(Size size) { + this.size = size; + name = "하우스 블렌드 커피"; + } + + public double cost() { + return .89; + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/Mocha.java b/chapter3/jongwoon/src/decorator/coffee/Mocha.java new file mode 100644 index 0000000..c7aa6e5 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/Mocha.java @@ -0,0 +1,30 @@ +package decorator.coffee; + +public class Mocha extends CondimentDecorator { + + public Mocha(Beverage beverage) { + super(beverage); + } + + @Override + public String getName() { + return beverage.getName() + ", 모카"; + } + + @Override + public double cost() { + double cost = beverage.cost(); + + switch(beverage.getSize()) { + case TALL: + cost += 0.10; + break; + case GRANDE: + cost += 0.15; + break; + case VENTI: + cost += 0.20; + } + return cost; + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/Soybean.java b/chapter3/jongwoon/src/decorator/coffee/Soybean.java new file mode 100644 index 0000000..045b16d --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/Soybean.java @@ -0,0 +1,30 @@ +package decorator.coffee; + +public class Soybean extends CondimentDecorator { + + public Soybean(Beverage beverage) { + super(beverage); + } + + @Override + public String getName() { + return beverage.getName() + ", 두유"; + } + + @Override + public double cost() { + double cost = beverage.cost(); + + switch(beverage.getSize()) { + case TALL: + cost += 0.05; + break; + case GRANDE: + cost += 0.1; + break; + case VENTI: + cost += 0.15; + } + return cost; + } +} diff --git a/chapter3/jongwoon/src/decorator/coffee/Whip.java b/chapter3/jongwoon/src/decorator/coffee/Whip.java new file mode 100644 index 0000000..057360a --- /dev/null +++ b/chapter3/jongwoon/src/decorator/coffee/Whip.java @@ -0,0 +1,30 @@ +package decorator.coffee; + +public class Whip extends CondimentDecorator { + + public Whip(Beverage beverage) { + super(beverage); + } + + @Override + public String getName() { + return beverage.getName() + ", 휘핑크림"; + } + + @Override + public double cost() { + double cost = beverage.cost(); + + switch(beverage.getSize()) { + case TALL: + cost += 0.02; + break; + case GRANDE: + cost += 0.04; + break; + case VENTI: + cost += 0.1; + } + return cost; + } +} diff --git a/chapter3/jongwoon/src/decorator/miniproject/App.java b/chapter3/jongwoon/src/decorator/miniproject/App.java new file mode 100644 index 0000000..1ec1d5b --- /dev/null +++ b/chapter3/jongwoon/src/decorator/miniproject/App.java @@ -0,0 +1,14 @@ +package decorator.miniproject; + +public class App { + public static void main(String[] args) { + User user = new User("문종운", "010-6800-0708", "인천광역시 미추홀구"); + UserWrapper baseUser = new BaseUserWrapper(); + UserWrapper userDecorator = new UserValidationDecorator(new UserCryptographyDecorator(baseUser)); + userDecorator.write(user); + + System.out.println("encrypt 된 데이터 : " + baseUser.read()); + System.out.println("=============="); + System.out.println("decrypt 된 데이터 : " + userDecorator.read()); + } +} diff --git a/chapter3/jongwoon/src/decorator/miniproject/BaseUserWrapper.java b/chapter3/jongwoon/src/decorator/miniproject/BaseUserWrapper.java new file mode 100644 index 0000000..47c99d6 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/miniproject/BaseUserWrapper.java @@ -0,0 +1,16 @@ +package decorator.miniproject; + +public class BaseUserWrapper implements UserWrapper{ + private User user; + + @Override + public void write(User user) { + System.out.println(user); + this.user = user; + } + + @Override + public User read() { + return user; + } +} diff --git a/chapter3/jongwoon/src/decorator/miniproject/User.java b/chapter3/jongwoon/src/decorator/miniproject/User.java new file mode 100644 index 0000000..29f09fb --- /dev/null +++ b/chapter3/jongwoon/src/decorator/miniproject/User.java @@ -0,0 +1,35 @@ +package decorator.miniproject; + + +public class User { + private String name; + private String phoneNumber; + private String address; + + public User(String name, String phoneNumber, String address) { + this.name = name; + this.phoneNumber = phoneNumber; + this.address = address; + } + + public String getName() { + return name; + } + + public String getPhoneNumber() { + return phoneNumber; + } + + public String getAddress() { + return address; + } + + @Override + public String toString() { + return "User{" + + "name='" + name + '\'' + + ", phoneNumber='" + phoneNumber + '\'' + + ", address='" + address + '\'' + + '}'; + } +} diff --git a/chapter3/jongwoon/src/decorator/miniproject/UserCryptographyDecorator.java b/chapter3/jongwoon/src/decorator/miniproject/UserCryptographyDecorator.java new file mode 100644 index 0000000..67ca57c --- /dev/null +++ b/chapter3/jongwoon/src/decorator/miniproject/UserCryptographyDecorator.java @@ -0,0 +1,52 @@ +package decorator.miniproject; + +public class UserCryptographyDecorator extends UserDecorator { + + + private final int MOVE_VALUE = 20; + public UserCryptographyDecorator(UserWrapper userWrapper) { + super(userWrapper); + } + + @Override + public void write(User user) { + super.write(encryptUser(user)); + } + + private User encryptUser(User user) { + String encryptedName = encrypt(user.getName()); + String encryptedPhoneNumber = encrypt(user.getPhoneNumber()); + String encryptedAddress = encrypt(user.getAddress()); + return new User(encryptedName, encryptedPhoneNumber, encryptedAddress); + } + + private String encrypt(String value) { + StringBuilder sb = new StringBuilder(); + for(char ch : value.toCharArray()) { + sb.append((char)(ch + MOVE_VALUE)); + } + return sb.toString(); + } + + + @Override + public User read() { + User user = super.read(); + return decryptUser(user); + } + + private User decryptUser(User user) { + String decryptedName = decrypt(user.getName()); + String decryptedPhoneNumber = decrypt(user.getPhoneNumber()); + String decryptedAddress = decrypt(user.getAddress()); + return new User(decryptedName, decryptedPhoneNumber, decryptedAddress); + } + + private String decrypt(String value) { + StringBuilder sb = new StringBuilder(); + for(char ch : value.toCharArray()) { + sb.append((char)(ch - MOVE_VALUE)); + } + return sb.toString(); + } +} diff --git a/chapter3/jongwoon/src/decorator/miniproject/UserDecorator.java b/chapter3/jongwoon/src/decorator/miniproject/UserDecorator.java new file mode 100644 index 0000000..574a306 --- /dev/null +++ b/chapter3/jongwoon/src/decorator/miniproject/UserDecorator.java @@ -0,0 +1,20 @@ +package decorator.miniproject; + +public abstract class UserDecorator implements UserWrapper{ + + protected UserWrapper wrappedUser; + + public UserDecorator(UserWrapper userWrapper) { + this.wrappedUser = userWrapper; + } + + @Override + public void write(User user) { + wrappedUser.write(user); + } + + @Override + public User read() { + return wrappedUser.read(); + } +} diff --git a/chapter3/jongwoon/src/decorator/miniproject/UserValidationDecorator.java b/chapter3/jongwoon/src/decorator/miniproject/UserValidationDecorator.java new file mode 100644 index 0000000..0ca47ef --- /dev/null +++ b/chapter3/jongwoon/src/decorator/miniproject/UserValidationDecorator.java @@ -0,0 +1,35 @@ +package decorator.miniproject; + +import java.util.regex.Pattern; + +public class UserValidationDecorator extends UserDecorator { + + private static final String KOREAN_REGEX = "^[가-힣]+$"; + private static final Pattern KOREAN_REGEX_COMPILE = Pattern.compile(KOREAN_REGEX); + private static final String PHONE_NUMBER_REGEX = "^\\d{3}-\\d{4}-\\d{4}$"; + private static final Pattern PHONE_NUMBER_REGEX_COMPILE = Pattern.compile(PHONE_NUMBER_REGEX); + + public UserValidationDecorator(UserWrapper userWrapper) { + super(userWrapper); + } + + @Override + public void write(User user) { + if (validate(user)) { + wrappedUser.write(user); + } + } + + private boolean validate(User user) { + return isValidKoreanName(user.getName()) && isValidPhoneNumber(user.getPhoneNumber()); + } + + private boolean isValidKoreanName(String name) { + return KOREAN_REGEX_COMPILE.matcher(name).matches(); + } + + private boolean isValidPhoneNumber(String phoneNumber) { + return PHONE_NUMBER_REGEX_COMPILE.matcher(phoneNumber).matches(); + } + +} diff --git a/chapter3/jongwoon/src/decorator/miniproject/UserWrapper.java b/chapter3/jongwoon/src/decorator/miniproject/UserWrapper.java new file mode 100644 index 0000000..fc9885c --- /dev/null +++ b/chapter3/jongwoon/src/decorator/miniproject/UserWrapper.java @@ -0,0 +1,7 @@ +package decorator.miniproject; + +public interface UserWrapper { + + void write(User user); + User read(); +} diff --git a/chapter4,5/abstractFactory/abstractFactory.iml b/chapter4,5/abstractFactory/abstractFactory.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/chapter4,5/abstractFactory/abstractFactory.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter4,5/abstractFactory/src/Application.java b/chapter4,5/abstractFactory/src/Application.java new file mode 100644 index 0000000..5685c66 --- /dev/null +++ b/chapter4,5/abstractFactory/src/Application.java @@ -0,0 +1,20 @@ +import button.Button; +import checkBox.CheckBox; +import factory.GUIFactory; + +public class Application { + private GUIFactory factory; + private Button button; + private CheckBox checkBox; + + public Application(GUIFactory factory) { + this.factory = factory; + this.button = factory.createButton(); + this.checkBox = factory.createCheckBox(); + } + + public void createUI() { + button.paint(); + checkBox.paint(); + } +} diff --git a/chapter4,5/abstractFactory/src/ApplicationExecutor.java b/chapter4,5/abstractFactory/src/ApplicationExecutor.java new file mode 100644 index 0000000..3b162a0 --- /dev/null +++ b/chapter4,5/abstractFactory/src/ApplicationExecutor.java @@ -0,0 +1,26 @@ +import factory.GUIFactory; +import factory.MacFactory; +import factory.WinFactory; + +public class ApplicationExecutor { + public static void main(String[] args) { + Output.printOs(); + Operation operation = Operation.findOperation(Input.inputOsName()) + .orElseThrow(() -> new RuntimeException("안돼요~")); + + GUIFactory factory = null; + + switch (operation) { + case MAC: + factory = MacFactory.getInstance(); + break; + + case WINDOW: + factory = WinFactory.getInstance(); + break; + } + + Application application = new Application(factory); + application.createUI(); + } +} diff --git a/chapter4,5/abstractFactory/src/Input.java b/chapter4,5/abstractFactory/src/Input.java new file mode 100644 index 0000000..9070925 --- /dev/null +++ b/chapter4,5/abstractFactory/src/Input.java @@ -0,0 +1,9 @@ +import java.util.Scanner; + +public class Input { + private final static Scanner SCANNER = new Scanner(System.in); + + public static String inputOsName() { + return SCANNER.nextLine(); + } +} diff --git a/chapter4,5/abstractFactory/src/Operation.java b/chapter4,5/abstractFactory/src/Operation.java new file mode 100644 index 0000000..8f6029f --- /dev/null +++ b/chapter4,5/abstractFactory/src/Operation.java @@ -0,0 +1,26 @@ +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +public enum Operation { + WINDOW("window"), MAC("mac"); + + private final String os; + private final static Map OPERATION_MAP = Collections.unmodifiableMap(Arrays.stream(values()) + .collect(Collectors.toMap(Operation::getOs, Function.identity()))); + + Operation(String os) { + this.os = os; + } + + public String getOs() { + return this.os; + } + + public static Optional findOperation(String os) { + return Optional.ofNullable(OPERATION_MAP.get(os)); + } +} diff --git a/chapter4,5/abstractFactory/src/Output.java b/chapter4,5/abstractFactory/src/Output.java new file mode 100644 index 0000000..5d08964 --- /dev/null +++ b/chapter4,5/abstractFactory/src/Output.java @@ -0,0 +1,10 @@ +public class Output { + + public static void printOs() { + System.out.println("===수행 가능한 OS==="); + for (Operation operation : Operation.values()) { + System.out.println(operation.getOs()); + } + System.out.print("입력 : "); + } +} diff --git a/chapter4,5/abstractFactory/src/button/Button.java b/chapter4,5/abstractFactory/src/button/Button.java new file mode 100644 index 0000000..79ca518 --- /dev/null +++ b/chapter4,5/abstractFactory/src/button/Button.java @@ -0,0 +1,5 @@ +package button; + +public interface Button { + void paint(); +} diff --git a/chapter4,5/abstractFactory/src/button/MacButton.java b/chapter4,5/abstractFactory/src/button/MacButton.java new file mode 100644 index 0000000..b13360a --- /dev/null +++ b/chapter4,5/abstractFactory/src/button/MacButton.java @@ -0,0 +1,8 @@ +package button; + +public class MacButton implements Button { + @Override + public void paint() { + System.out.println("맥 버튼 렌더링"); + } +} diff --git a/chapter4,5/abstractFactory/src/button/WinButton.java b/chapter4,5/abstractFactory/src/button/WinButton.java new file mode 100644 index 0000000..b050d57 --- /dev/null +++ b/chapter4,5/abstractFactory/src/button/WinButton.java @@ -0,0 +1,8 @@ +package button; + +public class WinButton implements Button { + @Override + public void paint() { + System.out.println("윈도우 버튼 렌더링"); + } +} diff --git a/chapter4,5/abstractFactory/src/checkBox/CheckBox.java b/chapter4,5/abstractFactory/src/checkBox/CheckBox.java new file mode 100644 index 0000000..97c5677 --- /dev/null +++ b/chapter4,5/abstractFactory/src/checkBox/CheckBox.java @@ -0,0 +1,5 @@ +package checkBox; + +public interface CheckBox { + void paint(); +} diff --git a/chapter4,5/abstractFactory/src/checkBox/MacCheckBox.java b/chapter4,5/abstractFactory/src/checkBox/MacCheckBox.java new file mode 100644 index 0000000..f3e0b37 --- /dev/null +++ b/chapter4,5/abstractFactory/src/checkBox/MacCheckBox.java @@ -0,0 +1,8 @@ +package checkBox; + +public class MacCheckBox implements CheckBox { + @Override + public void paint() { + System.out.println("맥 체크박스 렌더링"); + } +} diff --git a/chapter4,5/abstractFactory/src/checkBox/WinCheckBox.java b/chapter4,5/abstractFactory/src/checkBox/WinCheckBox.java new file mode 100644 index 0000000..035b92e --- /dev/null +++ b/chapter4,5/abstractFactory/src/checkBox/WinCheckBox.java @@ -0,0 +1,8 @@ +package checkBox; + +public class WinCheckBox implements CheckBox { + @Override + public void paint() { + System.out.println("윈도우 체크박스 렌더링"); + } +} diff --git a/chapter4,5/abstractFactory/src/factory/GUIFactory.java b/chapter4,5/abstractFactory/src/factory/GUIFactory.java new file mode 100644 index 0000000..79f04d8 --- /dev/null +++ b/chapter4,5/abstractFactory/src/factory/GUIFactory.java @@ -0,0 +1,10 @@ +package factory; + +import button.Button; +import checkBox.CheckBox; + +public interface GUIFactory { + Button createButton(); + + CheckBox createCheckBox(); +} diff --git a/chapter4,5/abstractFactory/src/factory/MacFactory.java b/chapter4,5/abstractFactory/src/factory/MacFactory.java new file mode 100644 index 0000000..24a38fd --- /dev/null +++ b/chapter4,5/abstractFactory/src/factory/MacFactory.java @@ -0,0 +1,30 @@ +package factory; + +import button.Button; +import button.MacButton; +import checkBox.CheckBox; +import checkBox.MacCheckBox; + +public class MacFactory implements GUIFactory { + + private MacFactory() { + } + + private static class MacFactoryLazyHolder { + public static final MacFactory INSTANCE = new MacFactory(); + } + + public static MacFactory getInstance() { + return MacFactoryLazyHolder.INSTANCE; + } + + @Override + public Button createButton() { + return new MacButton(); + } + + @Override + public CheckBox createCheckBox() { + return new MacCheckBox(); + } +} diff --git a/chapter4,5/abstractFactory/src/factory/WinFactory.java b/chapter4,5/abstractFactory/src/factory/WinFactory.java new file mode 100644 index 0000000..f3f0274 --- /dev/null +++ b/chapter4,5/abstractFactory/src/factory/WinFactory.java @@ -0,0 +1,29 @@ +package factory; + +import button.Button; +import button.WinButton; +import checkBox.CheckBox; +import checkBox.WinCheckBox; + +public class WinFactory implements GUIFactory { + private WinFactory() { + } + + private static class WinFactoryLazyHolder { + private static final WinFactory INSTANCE = new WinFactory(); + } + + public static WinFactory getInstance() { + return WinFactoryLazyHolder.INSTANCE; + } + + @Override + public Button createButton() { + return new WinButton(); + } + + @Override + public CheckBox createCheckBox() { + return new WinCheckBox(); + } +} diff --git a/chapter6/command/.gitignore b/chapter6/command/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/chapter6/command/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/chapter6/command/.idea/.gitignore b/chapter6/command/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/chapter6/command/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/chapter6/command/build.gradle b/chapter6/command/build.gradle new file mode 100644 index 0000000..f7beddb --- /dev/null +++ b/chapter6/command/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group = 'org.example' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/chapter6/command/gradle/wrapper/gradle-wrapper.jar b/chapter6/command/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/chapter6/command/gradle/wrapper/gradle-wrapper.jar differ diff --git a/chapter6/command/gradle/wrapper/gradle-wrapper.properties b/chapter6/command/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..480c1e4 --- /dev/null +++ b/chapter6/command/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Jun 29 21:10:36 KST 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/chapter6/command/gradlew b/chapter6/command/gradlew new file mode 100755 index 0000000..1b6c787 --- /dev/null +++ b/chapter6/command/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/chapter6/command/gradlew.bat b/chapter6/command/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/chapter6/command/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/chapter6/command/settings.gradle b/chapter6/command/settings.gradle new file mode 100644 index 0000000..d731fe9 --- /dev/null +++ b/chapter6/command/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'command' + diff --git a/chapter6/command/src/main/java/Application.java b/chapter6/command/src/main/java/Application.java new file mode 100644 index 0000000..e7aa28f --- /dev/null +++ b/chapter6/command/src/main/java/Application.java @@ -0,0 +1,55 @@ +import java.util.ArrayList; +import java.util.List; + +public class Application { + String clipboard; + List editors = new ArrayList<>(); + Editor activeEditor; + CommandHistory history; + + public Application() { + this.history = new CommandHistory(); + } + + public void addEditor(Editor editor) { + System.out.println(editor + "가 추가되었습니다."); + editors.add(editor); + } + + public void changeEditor(Editor editor) { + if (editors.contains(editor)) { + activeEditor = editor; + System.out.println("application이 관리하는 editor가 " + editor + "로 변경되었습니다."); + } + editors.add(editor); + System.out.println(editor + "를 추가하고 변경하였습니다."); + activeEditor = editor; + } + + public Editor getActiveEditor() { + return activeEditor; + } + + public void executeCommand(Command command, CursorPosition cursorPosition) { + if (command.execute(cursorPosition)) { + history.push(command); + } + } + + public Command undo() { + if (history.isEmptyHistory()) { + return null; + } + return history.pop(); + } + + @Override + public String toString() { + return "Application{" + + "clipboard='" + clipboard + '\'' + + ", editors=" + editors + + ", activeEditor=" + activeEditor + + ", history=" + history + + '}'; + } +} diff --git a/chapter6/command/src/main/java/Command.java b/chapter6/command/src/main/java/Command.java new file mode 100644 index 0000000..6229c02 --- /dev/null +++ b/chapter6/command/src/main/java/Command.java @@ -0,0 +1,29 @@ +public abstract class Command { + public Application application; + public Editor editor; + private String backup; + + public Command(Application application, Editor editor) { + this.application = application; + this.editor = editor; + } + + public void saveBackup() { + this.backup = editor.text; + } + + public void undo() { + editor.text = backup; + } + + @Override + public String toString() { + return "Command{" + + "application=" + application + + ", editor=" + editor + + ", backup='" + backup + '\'' + + '}'; + } + + abstract boolean execute(CursorPosition cursorPosition); +} diff --git a/chapter6/command/src/main/java/CommandHistory.java b/chapter6/command/src/main/java/CommandHistory.java new file mode 100644 index 0000000..29925c6 --- /dev/null +++ b/chapter6/command/src/main/java/CommandHistory.java @@ -0,0 +1,22 @@ +import java.util.Stack; + +public class CommandHistory { + + Stack history = new Stack<>(); + + public void push(Command command) { + System.out.println(command + "를 스택에 넣었습니다."); + history.push(command); + } + + public Command pop() { + Command command = history.pop(); + System.out.println(command + "가 취소 되었습니다."); + return command; + } + + public boolean isEmptyHistory() { + return history.isEmpty(); + } + +} diff --git a/chapter6/command/src/main/java/CopyCommand.java b/chapter6/command/src/main/java/CopyCommand.java new file mode 100644 index 0000000..68c30a5 --- /dev/null +++ b/chapter6/command/src/main/java/CopyCommand.java @@ -0,0 +1,12 @@ +public class CopyCommand extends Command { + public CopyCommand(Application application, Editor editor) { + super(application, editor); + } + + @Override + boolean execute(CursorPosition cursorPosition) { + application.clipboard = editor.getSelection(cursorPosition.getStart(), cursorPosition.getEnd()); + System.out.println("현재 clipBoard 의 상태 : " + application.clipboard); + return false; + } +} diff --git a/chapter6/command/src/main/java/CursorPosition.java b/chapter6/command/src/main/java/CursorPosition.java new file mode 100644 index 0000000..4a865d3 --- /dev/null +++ b/chapter6/command/src/main/java/CursorPosition.java @@ -0,0 +1,17 @@ +public class CursorPosition { + private int start; + private int end; + + public CursorPosition(int start, int end) { + this.start = start; + this.end = end; + } + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } +} diff --git a/chapter6/command/src/main/java/CutCommand.java b/chapter6/command/src/main/java/CutCommand.java new file mode 100644 index 0000000..0bc850c --- /dev/null +++ b/chapter6/command/src/main/java/CutCommand.java @@ -0,0 +1,14 @@ +public class CutCommand extends Command { + public CutCommand(Application application, Editor editor) { + super(application, editor); + } + + @Override + boolean execute(CursorPosition cursorPosition) { + saveBackup(); + application.clipboard = editor.getSelection(cursorPosition.getStart(), cursorPosition.getEnd()); + editor.deleteSelection(cursorPosition.getStart(), cursorPosition.getEnd()); + System.out.println("현재 clipBoard 의 상태 : " + application.clipboard); + return true; + } +} diff --git a/chapter6/command/src/main/java/Editor.java b/chapter6/command/src/main/java/Editor.java new file mode 100644 index 0000000..53dd708 --- /dev/null +++ b/chapter6/command/src/main/java/Editor.java @@ -0,0 +1,27 @@ +public class Editor { + + public String text; + + public Editor(String text) { + this.text = text; + } + + public String getSelection(int start, int end) { + return text.substring(start, end); + } + + public void deleteSelection(int start, int end) { + this.text = text.substring(0, start) + text.substring(end); + } + + public void replaceSelection(int start, int end, String text) { + this.text = this.text.substring(0, start) + text + this.text.substring(end); + } + + @Override + public String toString() { + return "Editor{" + + "text='" + text + '\'' + + '}'; + } +} diff --git a/chapter6/command/src/main/java/EditorApp.java b/chapter6/command/src/main/java/EditorApp.java new file mode 100644 index 0000000..123cfd1 --- /dev/null +++ b/chapter6/command/src/main/java/EditorApp.java @@ -0,0 +1,14 @@ +public class EditorApp { + public static void main(String[] args) { + Application application = new Application(); + Editor editorA = new Editor("aaaabbbbccccccccc"); + Editor editorB = new Editor("aaaaaabbbbbbsssdddsfasd"); + application.addEditor(editorA); + application.addEditor(editorB); + application.changeEditor(editorA); + application.executeCommand(new CopyCommand(application, application.getActiveEditor()), new CursorPosition(0, 5)); + application.executeCommand(new CutCommand(application, application.getActiveEditor()), new CursorPosition(1, 3)); + application.executeCommand(new PasteCommand(application, application.getActiveEditor()), new CursorPosition(0, 5)); + application.executeCommand(new UndoCommand(application, application.getActiveEditor()), new CursorPosition(0, 0)); + } +} diff --git a/chapter6/command/src/main/java/PasteCommand.java b/chapter6/command/src/main/java/PasteCommand.java new file mode 100644 index 0000000..f7de3e1 --- /dev/null +++ b/chapter6/command/src/main/java/PasteCommand.java @@ -0,0 +1,12 @@ +public class PasteCommand extends Command { + public PasteCommand(Application application, Editor editor) { + super(application, editor); + } + + @Override + boolean execute(CursorPosition cursorPosition) { + editor.replaceSelection(cursorPosition.getStart(), cursorPosition.getEnd(), application.clipboard); + System.out.println("현재 clipBoard 의 상태 : " + application.clipboard); + return true; + } +} diff --git a/chapter6/command/src/main/java/UndoCommand.java b/chapter6/command/src/main/java/UndoCommand.java new file mode 100644 index 0000000..ff705ca --- /dev/null +++ b/chapter6/command/src/main/java/UndoCommand.java @@ -0,0 +1,12 @@ +public class UndoCommand extends Command { + public UndoCommand(Application application, Editor editor) { + super(application, editor); + } + + @Override + boolean execute(CursorPosition cursorPosition) { + application.undo(); + System.out.println("현재 clipBoard 의 상태 : " + application.clipboard); + return false; + } +} diff --git a/chapter7/Facade/.gitignore b/chapter7/Facade/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/chapter7/Facade/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/chapter7/Facade/.idea/.gitignore b/chapter7/Facade/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/chapter7/Facade/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/chapter7/Facade/.idea/uiDesigner.xml b/chapter7/Facade/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/chapter7/Facade/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/chapter7/Facade/build.gradle b/chapter7/Facade/build.gradle new file mode 100644 index 0000000..f7beddb --- /dev/null +++ b/chapter7/Facade/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group = 'org.example' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/chapter7/Facade/gradle/wrapper/gradle-wrapper.jar b/chapter7/Facade/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/chapter7/Facade/gradle/wrapper/gradle-wrapper.jar differ diff --git a/chapter7/Facade/gradle/wrapper/gradle-wrapper.properties b/chapter7/Facade/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..e931881 --- /dev/null +++ b/chapter7/Facade/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 30 01:33:34 KST 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/chapter7/Facade/gradlew b/chapter7/Facade/gradlew new file mode 100755 index 0000000..1b6c787 --- /dev/null +++ b/chapter7/Facade/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/chapter7/Facade/gradlew.bat b/chapter7/Facade/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/chapter7/Facade/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/chapter7/Facade/settings.gradle b/chapter7/Facade/settings.gradle new file mode 100644 index 0000000..84db708 --- /dev/null +++ b/chapter7/Facade/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'Facade' + diff --git a/chapter7/Facade/src/main/java/Application.java b/chapter7/Facade/src/main/java/Application.java new file mode 100644 index 0000000..750cb87 --- /dev/null +++ b/chapter7/Facade/src/main/java/Application.java @@ -0,0 +1,12 @@ +import domain.AudioFile; +import facade.VideoConversionFacade; + +import java.text.MessageFormat; + +public class Application { + public static void main(String[] args) { + VideoConversionFacade videoConversionFacade = new VideoConversionFacade(); + AudioFile file = videoConversionFacade.convertToAudio("movie.ogg", "mpeg4"); + System.out.println(MessageFormat.format("FileName : {0}, CodecType : {1}", file.getFileName(), file.getCodecType())); + } +} diff --git a/chapter7/Facade/src/main/java/domain/AudioFile.java b/chapter7/Facade/src/main/java/domain/AudioFile.java new file mode 100644 index 0000000..bfac023 --- /dev/null +++ b/chapter7/Facade/src/main/java/domain/AudioFile.java @@ -0,0 +1,30 @@ +package domain; + + +public class AudioFile { + + private String fileName; + private CodecType codecType; + + public AudioFile(String fileName, CodecType codecType) { + this.fileName = fileName; + this.codecType = CodecType.getCodecType(getExtract(fileName)); + } + + private String getExtract(String fileName) { + int index = fileName.indexOf("."); + return fileName.substring(index + 1); + } + + public static AudioFile fix(VideoFile convertFile) { + return new AudioFile(convertFile.fileName, convertFile.codecType); + } + + public String getFileName() { + return fileName; + } + + public CodecType getCodecType() { + return codecType; + } +} diff --git a/chapter7/Facade/src/main/java/domain/BitrateReader.java b/chapter7/Facade/src/main/java/domain/BitrateReader.java new file mode 100644 index 0000000..ba4c0d0 --- /dev/null +++ b/chapter7/Facade/src/main/java/domain/BitrateReader.java @@ -0,0 +1,10 @@ +package domain; + +public class BitrateReader { + + public static VideoFile convert(VideoFile file, CodecType codecType) { + int index = file.getFileName().indexOf("."); + String fileName = file.getFileName().substring(0, index + 1) + codecType.getCodecName(); + return new VideoFile(fileName); + } +} diff --git a/chapter7/Facade/src/main/java/domain/CodecType.java b/chapter7/Facade/src/main/java/domain/CodecType.java new file mode 100644 index 0000000..aebc865 --- /dev/null +++ b/chapter7/Facade/src/main/java/domain/CodecType.java @@ -0,0 +1,28 @@ +package domain; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public enum CodecType { + OGG_COMPRESSION("ogg"), MPEG4_COMPRESSION("mpeg4"); + + private final String codecName; + private static final Map CODECTYPE_MAP = Collections.unmodifiableMap(Arrays.stream(CodecType.values()) + .collect(Collectors.toMap(CodecType::getCodecName, Function.identity()))); + + + CodecType(String codecName) { + this.codecName = codecName; + } + + public static CodecType getCodecType(String codecName) { + return CODECTYPE_MAP.get(codecName); + } + + public String getCodecName() { + return codecName; + } +} diff --git a/chapter7/Facade/src/main/java/domain/VideoFile.java b/chapter7/Facade/src/main/java/domain/VideoFile.java new file mode 100644 index 0000000..155d43f --- /dev/null +++ b/chapter7/Facade/src/main/java/domain/VideoFile.java @@ -0,0 +1,24 @@ +package domain; + +public class VideoFile { + String fileName; + CodecType codecType; + + public VideoFile(String fileName) { + this.fileName = fileName; + this.codecType = CodecType.getCodecType(getExtract(fileName)); + } + + private String getExtract(String fileName) { + int index = fileName.indexOf("."); + return fileName.substring(index + 1); + } + + public CodecType getCodecType() { + return codecType; + } + + public String getFileName() { + return fileName; + } +} diff --git a/chapter7/Facade/src/main/java/facade/VideoConversionFacade.java b/chapter7/Facade/src/main/java/facade/VideoConversionFacade.java new file mode 100644 index 0000000..dfd227f --- /dev/null +++ b/chapter7/Facade/src/main/java/facade/VideoConversionFacade.java @@ -0,0 +1,17 @@ +package facade; + +import domain.AudioFile; +import domain.BitrateReader; +import domain.CodecType; +import domain.VideoFile; +import util.CodecFactory; + +public class VideoConversionFacade { + + public AudioFile convertToAudio(String fileName, String format) { + VideoFile videoFile = new VideoFile(fileName); + CodecType convertCodecType = CodecType.getCodecType(format); + VideoFile convertFile = BitrateReader.convert(videoFile, convertCodecType); + return AudioFile.fix(convertFile); + } +} diff --git a/chapter7/Facade/src/main/java/util/CodecFactory.java b/chapter7/Facade/src/main/java/util/CodecFactory.java new file mode 100644 index 0000000..522564a --- /dev/null +++ b/chapter7/Facade/src/main/java/util/CodecFactory.java @@ -0,0 +1,11 @@ +package util; + +import domain.CodecType; +import domain.VideoFile; + +public class CodecFactory { + + public static CodecType extractFrom(VideoFile file) { + return file.getCodecType(); + } +} diff --git a/chapter7/adapter/.gitignore b/chapter7/adapter/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/chapter7/adapter/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/chapter7/adapter/.idea/.gitignore b/chapter7/adapter/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/chapter7/adapter/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/chapter7/adapter/build.gradle b/chapter7/adapter/build.gradle new file mode 100644 index 0000000..f7beddb --- /dev/null +++ b/chapter7/adapter/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group = 'org.example' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/chapter7/adapter/gradle/wrapper/gradle-wrapper.jar b/chapter7/adapter/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/chapter7/adapter/gradle/wrapper/gradle-wrapper.jar differ diff --git a/chapter7/adapter/gradle/wrapper/gradle-wrapper.properties b/chapter7/adapter/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..3d236fd --- /dev/null +++ b/chapter7/adapter/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 30 00:21:04 KST 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/chapter7/adapter/gradlew b/chapter7/adapter/gradlew new file mode 100755 index 0000000..1b6c787 --- /dev/null +++ b/chapter7/adapter/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/chapter7/adapter/gradlew.bat b/chapter7/adapter/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/chapter7/adapter/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/chapter7/adapter/settings.gradle b/chapter7/adapter/settings.gradle new file mode 100644 index 0000000..8df43d4 --- /dev/null +++ b/chapter7/adapter/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'adapter' + diff --git a/chapter7/adapter/src/main/java/AdapterApp.java b/chapter7/adapter/src/main/java/AdapterApp.java new file mode 100644 index 0000000..261ee68 --- /dev/null +++ b/chapter7/adapter/src/main/java/AdapterApp.java @@ -0,0 +1,16 @@ +import domain.RoundHole; +import domain.RoundPeg; +import domain.RoundPegAdapter; +import domain.SquarePeg; + +public class AdapterApp { + public static void main(String[] args) { + RoundHole roundHole = new RoundHole(5); + RoundPeg roundPeg = new RoundPeg(5.5); + System.out.println(roundHole.fits(roundPeg)); + + SquarePeg squarePeg = new SquarePeg(8); + RoundPegAdapter roundPegAdapter = new RoundPegAdapter(squarePeg); + System.out.println(roundHole.fits(roundPegAdapter)); + } +} diff --git a/chapter7/adapter/src/main/java/domain/RoundHole.java b/chapter7/adapter/src/main/java/domain/RoundHole.java new file mode 100644 index 0000000..2f195c3 --- /dev/null +++ b/chapter7/adapter/src/main/java/domain/RoundHole.java @@ -0,0 +1,17 @@ +package domain; + +public class RoundHole { + int radius; + + public RoundHole(int radius) { + this.radius = radius; + } + + public int getRadius() { + return this.radius; + } + + public boolean fits(RoundPeg roundPeg) { + return this.radius >= roundPeg.getRadius(); + } +} diff --git a/chapter7/adapter/src/main/java/domain/RoundPeg.java b/chapter7/adapter/src/main/java/domain/RoundPeg.java new file mode 100644 index 0000000..7794f03 --- /dev/null +++ b/chapter7/adapter/src/main/java/domain/RoundPeg.java @@ -0,0 +1,15 @@ +package domain; + +public class RoundPeg { + private double radius; + + public RoundPeg() {} + + public RoundPeg(double radius) { + this.radius = radius; + } + + public double getRadius() { + return radius; + } +} diff --git a/chapter7/adapter/src/main/java/domain/RoundPegAdapter.java b/chapter7/adapter/src/main/java/domain/RoundPegAdapter.java new file mode 100644 index 0000000..7272b67 --- /dev/null +++ b/chapter7/adapter/src/main/java/domain/RoundPegAdapter.java @@ -0,0 +1,14 @@ +package domain; + +public class RoundPegAdapter extends RoundPeg{ + + private SquarePeg squarePeg; + + public RoundPegAdapter(SquarePeg squarePeg) { + this.squarePeg = squarePeg; + } + + public double getRadius() { + return squarePeg.getWidth() / 2.0; + } +} diff --git a/chapter7/adapter/src/main/java/domain/SquarePeg.java b/chapter7/adapter/src/main/java/domain/SquarePeg.java new file mode 100644 index 0000000..76dfe86 --- /dev/null +++ b/chapter7/adapter/src/main/java/domain/SquarePeg.java @@ -0,0 +1,13 @@ +package domain; + +public class SquarePeg { + private int width; + + public SquarePeg(int width) { + this.width = width; + } + + public int getWidth() { + return width; + } +} diff --git a/chapter8/Iterator/.idea/.gitignore b/chapter8/Iterator/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/chapter8/Iterator/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/chapter8/Iterator/.idea/misc.xml b/chapter8/Iterator/.idea/misc.xml new file mode 100644 index 0000000..6ccf6d9 --- /dev/null +++ b/chapter8/Iterator/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/chapter8/Iterator/.idea/modules.xml b/chapter8/Iterator/.idea/modules.xml new file mode 100644 index 0000000..67c9851 --- /dev/null +++ b/chapter8/Iterator/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/chapter8/Iterator/.idea/uiDesigner.xml b/chapter8/Iterator/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/chapter8/Iterator/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/chapter8/Iterator/.idea/vcs.xml b/chapter8/Iterator/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/chapter8/Iterator/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/chapter8/Iterator/Iterator.iml b/chapter8/Iterator/Iterator.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/chapter8/Iterator/Iterator.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter8/Iterator/src/com/iterator/Main.java b/chapter8/Iterator/src/com/iterator/Main.java new file mode 100644 index 0000000..f9e5852 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/Main.java @@ -0,0 +1,34 @@ +package com.iterator; + +import com.iterator.domain.Facebook; +import com.iterator.domain.LinkedIn; +import com.iterator.domain.SocialNetwork; +import com.iterator.domain.SocialNetworkType; +import com.iterator.service.SocialSpammer; + +import java.util.Scanner; + +public class Main { + private final static Scanner SCANNER = new Scanner(System.in); + + public static void main(String[] args) { + + System.out.println("==please input SocialTypeNumber=="); + + for (SocialNetworkType type : SocialNetworkType.values()) { + System.out.println(type.getTypeNumber() + ". : " + type.name()); + } + + int typeNumber = SCANNER.nextInt(); + SocialNetworkType socialNetworkType = SocialNetworkType.findByNumber(typeNumber); + + SocialNetwork socialNetwork = switch(socialNetworkType) { + case FACEBOOK -> new Facebook(TestData.initData()); + case LINKEDIN -> new LinkedIn(TestData.initData()); + }; + + SocialSpammer spammer = new SocialSpammer(socialNetwork); + spammer.sendSpamToFriends("bombo96@naver.com", "너모 어렵습니다"); + spammer.sendSpamToCoworkers("bombo96@naver.com", "스펜서님은 언제 쉬시나요?"); + } +} diff --git a/chapter8/Iterator/src/com/iterator/TestData.java b/chapter8/Iterator/src/com/iterator/TestData.java new file mode 100644 index 0000000..106eed8 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/TestData.java @@ -0,0 +1,20 @@ +package com.iterator; + +import com.iterator.domain.Profile; + +import java.util.ArrayList; +import java.util.List; + +public final class TestData { + + public static List initData() { + List data = new ArrayList<>(); + data.add(new Profile("bombo96@naver.com", "문종운", "friends:seyeon@naver.com", "friends:wonu123@naver.com", "friends:kbg1155@naver.com", "friends:sw1234@naver.com", "coworkers:spencer@naver.com")); + data.add(new Profile("kbg1155@naver.com", "강병곤", "friends:seyeon@naver.com", "friends:wonu123@naver.com", "friends:bombo96@naver.com", "friends:sw1234@naver.com", "coworkers:spencer@naver.com")); + data.add(new Profile("sw1234@naver.com", "한승원", "friends:seyeon@naver.com", "friends:wonu123@naver.com", "friends:kbg1155@naver.com", "friends:bombo96@naver.com", "coworkers:spencer@naver.com")); + data.add(new Profile("seyeon@naver.com", "박세연", "friends:bombo96@naver.com", "friends:wonu123@naver.com", "friends:kbg1155@naver.com", "friends:sw1234@naver.com", "coworkers:spencer@naver.com")); + data.add(new Profile("wonu123@naver.com", "유원우", "friends:seyeon@naver.com", "friends:bombo96@naver.com", "friends:kbg1155@naver.com", "friends:sw1234@naver.com", "coworkers:spencer@naver.com")); + data.add(new Profile("spencer@naver.com", "스펜서", "friends:seyeon@naver.com", "friends:wonu123@naver.com", "friends:kbg1155@naver.com", "friends:sw1234@naver.com", "coworkers:bombo96@naver.com")); + return data; + } +} diff --git a/chapter8/Iterator/src/com/iterator/domain/Facebook.java b/chapter8/Iterator/src/com/iterator/domain/Facebook.java new file mode 100644 index 0000000..9d18e37 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/Facebook.java @@ -0,0 +1,55 @@ +package com.iterator.domain; + +import com.iterator.domain.iterator.FacebookIterator; +import com.iterator.domain.iterator.ProfileIterator; + +import java.util.ArrayList; +import java.util.List; + +public class Facebook implements SocialNetwork { + private List profiles; + + public Facebook(List cache) { + if (cache != null) { + this.profiles = cache; + return; + } + this.profiles = new ArrayList<>(); + } + + public Profile requestProfileFriendsFromFacebook(String profileEmail) { + System.out.println("Facebook : Loading Profile '" + profileEmail + "' over the network..."); + + return findProfile(profileEmail); + } + + public List requestProfileFriendsFromFacebook(String profileEmail, String contactType) { + System.out.println("Facebook : Loading '" + contactType + "' list of '" + profileEmail + "' over the network..."); + + Profile profile = findProfile(profileEmail); + + if (profile != null) { + return profile.getContacts(contactType); + } + + return null; + } + + private Profile findProfile(String profileEmail) { + + return this.profiles.stream() + .filter((profile) -> profile.getEmail().equals(profileEmail)) + .findFirst() + .orElse(null); + } + + @Override + public ProfileIterator createFriendsIterator(String profileEmail) { + return new FacebookIterator(this, "friends", profileEmail); + } + + @Override + public ProfileIterator createCoWorkersIterator(String profileEmail) { + return new FacebookIterator(this, "coworkers", profileEmail); + } +} diff --git a/chapter8/Iterator/src/com/iterator/domain/LinkedIn.java b/chapter8/Iterator/src/com/iterator/domain/LinkedIn.java new file mode 100644 index 0000000..942886d --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/LinkedIn.java @@ -0,0 +1,61 @@ +package com.iterator.domain; + +import com.iterator.domain.iterator.LinkedInIterator; +import com.iterator.domain.iterator.ProfileIterator; + +import java.util.ArrayList; +import java.util.List; + +public class LinkedIn implements SocialNetwork{ + private List profiles; + + public LinkedIn(List cache) { + if (cache != null) { + this.profiles = cache; + } + this.profiles = new ArrayList<>(); + } + + public Profile requestContactInfoFromLinkedInAPI(String profileEmail) { + System.out.println("LinkedIn: Loading profile '" + profileEmail + "' over the network..."); + + return findContact(profileEmail); + } + + public List requestRelatedContactsFromLinkedInAPI(String profileEmail, String contactType) { + System.out.println("LinkedIn: Loading '" + contactType + "' list of '" + profileEmail + "' over the network..."); + + Profile profile = findContact(profileEmail); + if (profile != null) { + return profile.getContacts(contactType); + } + return null; + } + + private Profile findContact(String profileEmail) { + for (Profile profile : profiles) { + if (profile.getEmail().equals(profileEmail)) { + return profile; + } + } + return null; + } + + private void simulateNetworkLatency() { + try { + Thread.sleep(2500); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + @Override + public ProfileIterator createFriendsIterator(String profileEmail) { + return new LinkedInIterator(this, "friends", profileEmail); + } + + @Override + public ProfileIterator createCoWorkersIterator(String profileEmail) { + return new LinkedInIterator(this, "coworkers", profileEmail); + } +} diff --git a/chapter8/Iterator/src/com/iterator/domain/Profile.java b/chapter8/Iterator/src/com/iterator/domain/Profile.java new file mode 100644 index 0000000..06eebdd --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/Profile.java @@ -0,0 +1,52 @@ +package com.iterator.domain; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Profile { + private String name; + private String email; + private Map> contacts = new HashMap<>(); + + public Profile(String email, String name, String... contacts) { + + this.name = name; + this.email = email; + + for (String contact : contacts) { + String[] part = contact.split(":"); + String contactType = "friend"; + String contactEmail = ""; + + if(part.length == 1) { + contactEmail = part[0]; + } else { + contactType = part[0]; + contactEmail = part[1]; + } + + if(!this.contacts.containsKey(contactType)) { + this.contacts.put(contactType, new ArrayList<>()); + } + this.contacts.get(contactType).add(contactEmail); + } + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + public List getContacts(String contactType) { + if (!this.contacts.containsKey(contactType)) { + this.contacts.put(contactType, new ArrayList<>()); + } + + return this.contacts.get(contactType); + } +} diff --git a/chapter8/Iterator/src/com/iterator/domain/SocialNetwork.java b/chapter8/Iterator/src/com/iterator/domain/SocialNetwork.java new file mode 100644 index 0000000..3f82ac3 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/SocialNetwork.java @@ -0,0 +1,8 @@ +package com.iterator.domain; + +import com.iterator.domain.iterator.ProfileIterator; + +public interface SocialNetwork { + ProfileIterator createFriendsIterator(String profileEmail); + ProfileIterator createCoWorkersIterator(String profileEmail); +} diff --git a/chapter8/Iterator/src/com/iterator/domain/SocialNetworkType.java b/chapter8/Iterator/src/com/iterator/domain/SocialNetworkType.java new file mode 100644 index 0000000..86d332b --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/SocialNetworkType.java @@ -0,0 +1,27 @@ +package com.iterator.domain; + +import java.util.Arrays; + +public enum SocialNetworkType { + FACEBOOK(1), + LINKEDIN(2); + + private final int typeNumber; + + SocialNetworkType(int typeNumber) { + this.typeNumber = typeNumber; + } + + public static SocialNetworkType findByNumber(int number) { + SocialNetworkType socialNetworkType = Arrays.stream(values()) + .filter((type) -> type.typeNumber == number) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("존재하지 않은 소셜 타입 번호 입력")); + + return socialNetworkType; + } + + public int getTypeNumber() { + return this.typeNumber; + } +} diff --git a/chapter8/Iterator/src/com/iterator/domain/iterator/FacebookIterator.java b/chapter8/Iterator/src/com/iterator/domain/iterator/FacebookIterator.java new file mode 100644 index 0000000..3c9f506 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/iterator/FacebookIterator.java @@ -0,0 +1,59 @@ +package com.iterator.domain.iterator; + +import com.iterator.domain.Facebook; +import com.iterator.domain.Profile; + +import java.util.ArrayList; +import java.util.List; + +public class FacebookIterator implements ProfileIterator { + private Facebook facebook; + private String type; + private String email; + private int currentPosition = 0; + private List emails = new ArrayList<>(); + private List profiles = new ArrayList<>(); + + public FacebookIterator(Facebook facebook, String type, String email) { + this.facebook = facebook; + this.type = type; + this.email = email; + } + + private void lazyLoading() { + if (emails.size() == 0) { + List profiles = facebook.requestProfileFriendsFromFacebook(this.email, this.type); + for(String profile : profiles) { + this.emails.add(profile); + this.profiles.add(null); + } + } + } + + @Override + public boolean hasNext() { + lazyLoading(); + return currentPosition < emails.size(); + } + + @Override + public Profile getNext() { + if(!hasNext()) { + return null; + } + + String email = emails.get(currentPosition); + Profile profile = profiles.get(currentPosition); + if (profile == null) { + profile = facebook.requestProfileFriendsFromFacebook(email); + profiles.set(currentPosition, profile); + } + currentPosition++; + return profile; + } + + @Override + public void reset() { + currentPosition = 0; + } +} diff --git a/chapter8/Iterator/src/com/iterator/domain/iterator/LinkedInIterator.java b/chapter8/Iterator/src/com/iterator/domain/iterator/LinkedInIterator.java new file mode 100644 index 0000000..963d805 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/iterator/LinkedInIterator.java @@ -0,0 +1,59 @@ +package com.iterator.domain.iterator; + +import com.iterator.domain.LinkedIn; +import com.iterator.domain.Profile; + +import java.util.ArrayList; +import java.util.List; + +public class LinkedInIterator implements ProfileIterator { + private LinkedIn linkedIn; + private String type; + private String email; + private int currentPosition = 0; + private List emails = new ArrayList<>(); + private List contacts = new ArrayList<>(); + + public LinkedInIterator(LinkedIn linkedIn, String type, String email) { + this.linkedIn = linkedIn; + this.type = type; + this.email = email; + } + + private void lazyLoad() { + if (emails.size() == 0) { + List profiles = linkedIn.requestRelatedContactsFromLinkedInAPI(this.email, this.type); + for (String profile : profiles) { + this.emails.add(profile); + this.contacts.add(null); + } + } + } + + @Override + public boolean hasNext() { + lazyLoad(); + return currentPosition < emails.size(); + } + + @Override + public Profile getNext() { + if (!hasNext()) { + return null; + } + + String friendEmail = emails.get(currentPosition); + Profile friendContact = contacts.get(currentPosition); + if (friendContact == null) { + friendContact = linkedIn.requestContactInfoFromLinkedInAPI(friendEmail); + contacts.set(currentPosition, friendContact); + } + currentPosition++; + return friendContact; + } + + @Override + public void reset() { + currentPosition = 0; + } +} diff --git a/chapter8/Iterator/src/com/iterator/domain/iterator/ProfileIterator.java b/chapter8/Iterator/src/com/iterator/domain/iterator/ProfileIterator.java new file mode 100644 index 0000000..f39f752 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/domain/iterator/ProfileIterator.java @@ -0,0 +1,10 @@ +package com.iterator.domain.iterator; + +import com.iterator.domain.Profile; + +public interface ProfileIterator { + + boolean hasNext(); + Profile getNext(); + void reset(); +} diff --git a/chapter8/Iterator/src/com/iterator/service/SocialSpammer.java b/chapter8/Iterator/src/com/iterator/service/SocialSpammer.java new file mode 100644 index 0000000..7b53002 --- /dev/null +++ b/chapter8/Iterator/src/com/iterator/service/SocialSpammer.java @@ -0,0 +1,36 @@ +package com.iterator.service; + +import com.iterator.domain.Profile; +import com.iterator.domain.SocialNetwork; +import com.iterator.domain.iterator.ProfileIterator; + +public class SocialSpammer { + public SocialNetwork socialNetwork; + public ProfileIterator iterator; + + public SocialSpammer(SocialNetwork socialNetwork) { + this.socialNetwork = socialNetwork; + } + + public void sendSpamToFriends(String profileEmail, String message) { + System.out.println("Iterating over friends..."); + iterator = socialNetwork.createFriendsIterator(profileEmail); + while (iterator.hasNext()) { + Profile profile = iterator.getNext(); + sendMessage(profile.getEmail(), message); + } + } + + public void sendSpamToCoworkers(String profileEmail, String message) { + System.out.println("Iterating over coworkers..."); + iterator = socialNetwork.createCoWorkersIterator(profileEmail); + while (iterator.hasNext()) { + Profile profile = iterator.getNext(); + sendMessage(profile.getEmail(), message); + } + } + + public void sendMessage(String email, String message) { + System.out.println("Sent message to: '" + email + "'. Message body: '" + message + "'"); + } +} diff --git a/chapter8/templateMethod/.gitignore b/chapter8/templateMethod/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/chapter8/templateMethod/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/chapter8/templateMethod/.idea/.gitignore b/chapter8/templateMethod/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/chapter8/templateMethod/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/chapter8/templateMethod/.idea/misc.xml b/chapter8/templateMethod/.idea/misc.xml new file mode 100644 index 0000000..211753f --- /dev/null +++ b/chapter8/templateMethod/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/chapter8/templateMethod/.idea/modules.xml b/chapter8/templateMethod/.idea/modules.xml new file mode 100644 index 0000000..80aa6be --- /dev/null +++ b/chapter8/templateMethod/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/chapter8/templateMethod/.idea/vcs.xml b/chapter8/templateMethod/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/chapter8/templateMethod/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/chapter8/templateMethod/src/com/templateMethod/Game.java b/chapter8/templateMethod/src/com/templateMethod/Game.java new file mode 100644 index 0000000..ce8a0f2 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/Game.java @@ -0,0 +1,8 @@ +package com.templateMethod; + +public class Game { + public static void main(String[] args) { + GameAI orcAI = new OrcsAI(); + orcAI.turn(); + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/GameAI.java b/chapter8/templateMethod/src/com/templateMethod/GameAI.java new file mode 100644 index 0000000..4f48376 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/GameAI.java @@ -0,0 +1,56 @@ +package com.templateMethod; + +import com.templateMethod.domain.BuildStructure; +import com.templateMethod.domain.GameMap; +import com.templateMethod.domain.Player; +import com.templateMethod.domain.Position; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public abstract class GameAI { + + protected List playerList = new ArrayList<>(); + protected GameMap map = new GameMap(5); + protected Position position; + protected List buildStructures = new ArrayList<>(); + + protected void turn() { + collectResources(); + buildStructures(); + buildUnits(); + attack(); + } + + protected void collectResources() { + for (BuildStructure structure : buildStructures) { + structure.collect(); + } + } + + protected abstract void buildStructures(); + + protected abstract void buildUnits(); + + protected void attack() { + Player enemy = closestEnemy(); + + if (enemy == null) { + sendScouts(map.getCenter()); + return; + } + + sendWarriors(enemy.getPosition()); + } + + private Player closestEnemy() { + return playerList.stream() + .min(Comparator.comparingInt(p -> p.getPosition().calculateDistance(this.position))) + .orElse(null); + } + + protected abstract void sendScouts(Position position); + + protected abstract void sendWarriors(Position position); +} diff --git a/chapter8/templateMethod/src/com/templateMethod/OrcsAI.java b/chapter8/templateMethod/src/com/templateMethod/OrcsAI.java new file mode 100644 index 0000000..1a7e2ba --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/OrcsAI.java @@ -0,0 +1,51 @@ +package com.templateMethod; + +import com.templateMethod.domain.Player; +import com.templateMethod.domain.Position; +import com.templateMethod.domain.unit.Scout; +import com.templateMethod.domain.unit.Unit; +import com.templateMethod.domain.unit.Warrior; + +import java.util.ArrayList; +import java.util.List; + +public class OrcsAI extends GameAI { + List scouts = new ArrayList<>(); + List warriors = new ArrayList<>(); + + @Override + protected void buildStructures() { + + } + + @Override + protected void buildUnits() { + if (noScouts()) { + scouts.add(new Scout()); + } else { + warriors.add(new Warrior()); + } + } + + @Override + protected void sendScouts(Position position) { + if (!scouts.isEmpty()) { + for(Unit scout : scouts) { + scout.move(position); + } + } + } + + @Override + protected void sendWarriors(Position position) { + if (!warriors.isEmpty()) { + for (Unit warrior : warriors) { + warrior.move(position); + } + } + } + + private boolean noScouts() { + return scouts.isEmpty(); + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/BuildStructure.java b/chapter8/templateMethod/src/com/templateMethod/domain/BuildStructure.java new file mode 100644 index 0000000..5e9087c --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/BuildStructure.java @@ -0,0 +1,6 @@ +package com.templateMethod.domain; + +public interface BuildStructure { + + void collect(); +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/GameMap.java b/chapter8/templateMethod/src/com/templateMethod/domain/GameMap.java new file mode 100644 index 0000000..23cb5c4 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/GameMap.java @@ -0,0 +1,15 @@ +package com.templateMethod.domain; + +public class GameMap { + private int[][] map; + private Position center; + + public GameMap(int size) { + this.map = new int[size][size]; + this.center = new Position(size / 2, size / 2); + } + + public Position getCenter() { + return center; + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/GasResource.java b/chapter8/templateMethod/src/com/templateMethod/domain/GasResource.java new file mode 100644 index 0000000..579fa68 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/GasResource.java @@ -0,0 +1,24 @@ +package com.templateMethod.domain; + +public class GasResource implements BuildStructure { + + private static final int PER_RESOURCE = 5; + private int resource; + + public GasResource(int resource) { + this.resource = resource; + } + + @Override + public void collect() { + if(this.resource == 0) { + System.out.println("자원이 고가되었습니다."); + return; + } + this.resource -= PER_RESOURCE; + + if(this.resource <= 0) { + this.resource = 0; + } + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/MineralResource.java b/chapter8/templateMethod/src/com/templateMethod/domain/MineralResource.java new file mode 100644 index 0000000..f7e84c2 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/MineralResource.java @@ -0,0 +1,24 @@ +package com.templateMethod.domain; + +public class MineralResource implements BuildStructure { + + private static final int PER_RESOURCE = 7; + private int resource; + + public MineralResource(int resource) { + this.resource = resource; + } + + @Override + public void collect() { + if(this.resource == 0) { + System.out.println("자원이 고가되었습니다."); + return; + } + this.resource -= PER_RESOURCE; + + if(this.resource <= 0) { + this.resource = 0; + } + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/Player.java b/chapter8/templateMethod/src/com/templateMethod/domain/Player.java new file mode 100644 index 0000000..a2b5a0f --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/Player.java @@ -0,0 +1,13 @@ +package com.templateMethod.domain; + +public class Player { + private Position position; + + public int calcDistance(Player enemy) { + return position.calculateDistance(enemy.position); + } + + public Position getPosition() { + return position; + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/Position.java b/chapter8/templateMethod/src/com/templateMethod/domain/Position.java new file mode 100644 index 0000000..18d43a9 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/Position.java @@ -0,0 +1,23 @@ +package com.templateMethod.domain; + +public class Position { + int x; + int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } + + public int calculateDistance(Position p) { + return (int)Math.sqrt(Math.pow(this.x - p.x, 2) + Math.pow(this.y - p.y, 2)); + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/unit/Scout.java b/chapter8/templateMethod/src/com/templateMethod/domain/unit/Scout.java new file mode 100644 index 0000000..eea06f9 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/unit/Scout.java @@ -0,0 +1,11 @@ +package com.templateMethod.domain.unit; + +import com.templateMethod.domain.Position; + +public class Scout extends Unit { + + @Override + public void move(Position position) { + System.out.println(position.getX() + " , " + position.getY() + "로 정찰병이 이동합니다"); + } +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/unit/Unit.java b/chapter8/templateMethod/src/com/templateMethod/domain/unit/Unit.java new file mode 100644 index 0000000..aacef3c --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/unit/Unit.java @@ -0,0 +1,9 @@ +package com.templateMethod.domain.unit; + +import com.templateMethod.domain.Position; + +public abstract class Unit { + protected Position position; + + public abstract void move(Position position); +} diff --git a/chapter8/templateMethod/src/com/templateMethod/domain/unit/Warrior.java b/chapter8/templateMethod/src/com/templateMethod/domain/unit/Warrior.java new file mode 100644 index 0000000..cf4aa51 --- /dev/null +++ b/chapter8/templateMethod/src/com/templateMethod/domain/unit/Warrior.java @@ -0,0 +1,11 @@ +package com.templateMethod.domain.unit; + +import com.templateMethod.domain.Position; + +public class Warrior extends Unit { + + @Override + public void move(Position position) { + System.out.println(position.getX() + " , " + position.getY() + "로 전사가 이동합니다"); + } +} diff --git a/chapter8/templateMethod/templateMethod.iml b/chapter8/templateMethod/templateMethod.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/chapter8/templateMethod/templateMethod.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter9/composite/.gitignore b/chapter9/composite/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/chapter9/composite/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/chapter9/composite/.idea/.gitignore b/chapter9/composite/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/chapter9/composite/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/chapter9/composite/.idea/misc.xml b/chapter9/composite/.idea/misc.xml new file mode 100644 index 0000000..211753f --- /dev/null +++ b/chapter9/composite/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/chapter9/composite/.idea/modules.xml b/chapter9/composite/.idea/modules.xml new file mode 100644 index 0000000..9b4c39e --- /dev/null +++ b/chapter9/composite/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/chapter9/composite/.idea/vcs.xml b/chapter9/composite/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/chapter9/composite/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/chapter9/composite/composite.iml b/chapter9/composite/composite.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/chapter9/composite/composite.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/chapter9/composite/src/com/composite/Main.java b/chapter9/composite/src/com/composite/Main.java new file mode 100644 index 0000000..af15c23 --- /dev/null +++ b/chapter9/composite/src/com/composite/Main.java @@ -0,0 +1,23 @@ +package com.composite; + +import com.composite.composite.CompoundGraphic; +import com.composite.composite.GraphicTools; +import com.composite.domain.Circle; +import com.composite.domain.Dot; + +public class Main { + public static void main(String[] args) { + CompoundGraphic compoundGraphicA = new CompoundGraphic(); + compoundGraphicA.add(new Dot(1, 4)); + compoundGraphicA.add(new Dot(3, 7)); + compoundGraphicA.add(new Circle(1, 4, 7)); + + CompoundGraphic compoundGraphicB = new CompoundGraphic(); + compoundGraphicB.add(new Dot(3, 5)); + compoundGraphicB.add(new Dot(2, 6)); + compoundGraphicB.add(new Circle(3, 10, 12)); + + GraphicTools tools = new GraphicTools(compoundGraphicA.getChilds(), compoundGraphicB.getChilds()); + tools.draw(); + } +} diff --git a/chapter9/composite/src/com/composite/composite/CompoundGraphic.java b/chapter9/composite/src/com/composite/composite/CompoundGraphic.java new file mode 100644 index 0000000..3153dfe --- /dev/null +++ b/chapter9/composite/src/com/composite/composite/CompoundGraphic.java @@ -0,0 +1,36 @@ +package com.composite.composite; + +import com.composite.domain.Graphic; + +import java.util.ArrayList; +import java.util.List; + +public class CompoundGraphic implements Graphic { + List childs = new ArrayList<>(); + + public void add(Graphic child) { + childs.add(child); + } + + public void remove(Graphic child) { + childs.remove(child); + } + + @Override + public void move(int x, int y) { + for(Graphic child : childs) { + child.move(x, y); + } + } + + @Override + public void draw() { + for(Graphic child : childs) { + child.draw(); + } + } + + public List getChilds() { + return childs; + } +} diff --git a/chapter9/composite/src/com/composite/composite/GraphicTools.java b/chapter9/composite/src/com/composite/composite/GraphicTools.java new file mode 100644 index 0000000..c00fd7f --- /dev/null +++ b/chapter9/composite/src/com/composite/composite/GraphicTools.java @@ -0,0 +1,23 @@ +package com.composite.composite; + +import com.composite.domain.Graphic; + +import java.util.ArrayList; +import java.util.List; + +public class GraphicTools { + + List compoundGraphic = new ArrayList<>(); + + public GraphicTools(List... compoundGraphic) { + for (List graphics : compoundGraphic) { + this.compoundGraphic.addAll(graphics); + } + } + + public void draw() { + for (Graphic graphic : compoundGraphic) { + graphic.draw(); + } + } +} diff --git a/chapter9/composite/src/com/composite/domain/Circle.java b/chapter9/composite/src/com/composite/domain/Circle.java new file mode 100644 index 0000000..6dc6297 --- /dev/null +++ b/chapter9/composite/src/com/composite/domain/Circle.java @@ -0,0 +1,16 @@ +package com.composite.domain; + +public class Circle extends Dot { + + private int radius; + + public Circle(int x, int y, int radius) { + super(x, y); + this.radius = radius; + } + + @Override + public void draw() { + System.out.println("중점 [ " + x + ", " + y + "]과 반지름 " + radius + " 를 가진 원 그리기"); + } +} diff --git a/chapter9/composite/src/com/composite/domain/Dot.java b/chapter9/composite/src/com/composite/domain/Dot.java new file mode 100644 index 0000000..763db1f --- /dev/null +++ b/chapter9/composite/src/com/composite/domain/Dot.java @@ -0,0 +1,25 @@ +package com.composite.domain; + +public class Dot implements Graphic { + + protected int x; + protected int y; + + public Dot(int x, int y) { + this.x = x; + this.y = y; + } + + @Override + public void move(int x, int y) { + System.out.println("점 좌표를 : " + "[ " + x + ", " + y + "] 만큼 이동시킵니다."); + this.x += x; + this.y += y; + } + + @Override + public void draw() { + System.out.println("== 점 그리기 =="); + System.out.println(x + " , " + y); + } +} diff --git a/chapter9/composite/src/com/composite/domain/Graphic.java b/chapter9/composite/src/com/composite/domain/Graphic.java new file mode 100644 index 0000000..f7aab79 --- /dev/null +++ b/chapter9/composite/src/com/composite/domain/Graphic.java @@ -0,0 +1,7 @@ +package com.composite.domain; + +public interface Graphic { + + void move(int x, int y); + void draw(); +} diff --git a/prototype/prototype/prototype/.gitignore b/prototype/prototype/prototype/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/prototype/prototype/prototype/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/prototype/prototype/prototype/.idea/.gitignore b/prototype/prototype/prototype/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/prototype/prototype/prototype/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/prototype/prototype/prototype/.idea/gradle.xml b/prototype/prototype/prototype/.idea/gradle.xml new file mode 100644 index 0000000..14746e7 --- /dev/null +++ b/prototype/prototype/prototype/.idea/gradle.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/prototype/prototype/prototype/.idea/misc.xml b/prototype/prototype/prototype/.idea/misc.xml new file mode 100644 index 0000000..6a8d183 --- /dev/null +++ b/prototype/prototype/prototype/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/prototype/prototype/prototype/.idea/vcs.xml b/prototype/prototype/prototype/.idea/vcs.xml new file mode 100644 index 0000000..c2365ab --- /dev/null +++ b/prototype/prototype/prototype/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/prototype/prototype/prototype/build.gradle b/prototype/prototype/prototype/build.gradle new file mode 100644 index 0000000..d706506 --- /dev/null +++ b/prototype/prototype/prototype/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group = 'com.designpattern' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation platform('org.junit:junit-bom:5.9.1') + testImplementation 'org.junit.jupiter:junit-jupiter' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/prototype/prototype/prototype/gradle/wrapper/gradle-wrapper.jar b/prototype/prototype/prototype/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/prototype/prototype/prototype/gradle/wrapper/gradle-wrapper.jar differ diff --git a/prototype/prototype/prototype/gradle/wrapper/gradle-wrapper.properties b/prototype/prototype/prototype/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..8656f9b --- /dev/null +++ b/prototype/prototype/prototype/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sun Jul 30 00:29:02 KST 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/prototype/prototype/prototype/gradlew b/prototype/prototype/prototype/gradlew new file mode 100755 index 0000000..1b6c787 --- /dev/null +++ b/prototype/prototype/prototype/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/prototype/prototype/prototype/gradlew.bat b/prototype/prototype/prototype/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/prototype/prototype/prototype/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/prototype/prototype/prototype/settings.gradle b/prototype/prototype/prototype/settings.gradle new file mode 100644 index 0000000..3aba1d9 --- /dev/null +++ b/prototype/prototype/prototype/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'prototype' + diff --git a/prototype/prototype/prototype/src/main/java/com/prototype/Circle.java b/prototype/prototype/prototype/src/main/java/com/prototype/Circle.java new file mode 100644 index 0000000..17f4250 --- /dev/null +++ b/prototype/prototype/prototype/src/main/java/com/prototype/Circle.java @@ -0,0 +1,33 @@ +package com.prototype; + +import java.util.Objects; + +public class Circle extends Shape { + private int radius; + + public Circle(int x, int y, String color, int radius) { + super(x, y, color); + this.radius = radius; + } + + public Circle(Circle target) { + super(target); + if (target != null) { + this.radius = target.radius; + } + } + + @Override + public Shape clone() { + return new Circle(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + Circle circle = (Circle) o; + return radius == circle.radius; + } +} diff --git a/prototype/prototype/prototype/src/main/java/com/prototype/Main.java b/prototype/prototype/prototype/src/main/java/com/prototype/Main.java new file mode 100644 index 0000000..7f9d9d8 --- /dev/null +++ b/prototype/prototype/prototype/src/main/java/com/prototype/Main.java @@ -0,0 +1,42 @@ +package com.prototype; + +import java.util.ArrayList; +import java.util.List; + +public class Main { + public static void main(String[] args) { + List shapes = new ArrayList<>(); + List shapesCopy = new ArrayList<>(); + + Circle circle = new Circle(10, 20, "red", 15); + shapes.add(circle); + + Circle copyCircle = (Circle) circle.clone(); + shapesCopy.add(copyCircle); + + Rectangle rectangle = new Rectangle(0, 0, "blue", 10, 20); + shapes.add(rectangle); + + Rectangle copyRectangle = (Rectangle) rectangle.clone(); + copyRectangle.changeWidth(30); + shapesCopy.add(copyRectangle); + + compare(shapes, shapesCopy); + } + + private static void compare(List shapes, List shapesCopy) { + + for (int i = 0; i < shapes.size(); i++) { + if (shapes.get(i) != shapesCopy.get(i)) { + System.out.println(i + ": Shapes are different objects (yay!)"); + if (shapes.get(i).equals(shapesCopy.get(i))) { + System.out.println(i + ": And they are identical (yay!)"); + } else { + System.out.println(i + ": But they are not identical (booo!)"); + } + } else { + System.out.println(i + ": Shape objects are the same (booo!)"); + } + } + } +} diff --git a/prototype/prototype/prototype/src/main/java/com/prototype/Rectangle.java b/prototype/prototype/prototype/src/main/java/com/prototype/Rectangle.java new file mode 100644 index 0000000..b0d3760 --- /dev/null +++ b/prototype/prototype/prototype/src/main/java/com/prototype/Rectangle.java @@ -0,0 +1,39 @@ +package com.prototype; + + +public class Rectangle extends Shape { + private int width; + private int height; + + public Rectangle(int x, int y, String color, int width, int height) { + super(x, y, color); + this.width = width; + this.height = height; + } + + public Rectangle(Rectangle target) { + super(target); + if (target != null) { + this.width = target.width; + this.height = target.height; + } + } + + @Override + public Shape clone() { + return new Rectangle(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + Rectangle rectangle = (Rectangle) o; + return width == rectangle.width && height == rectangle.height; + } + + public void changeWidth(int width) { + this.width = width; + } +} diff --git a/prototype/prototype/prototype/src/main/java/com/prototype/Shape.java b/prototype/prototype/prototype/src/main/java/com/prototype/Shape.java new file mode 100644 index 0000000..e1d17b7 --- /dev/null +++ b/prototype/prototype/prototype/src/main/java/com/prototype/Shape.java @@ -0,0 +1,33 @@ +package com.prototype; + +import java.util.Objects; + +public abstract class Shape { + private int x; + private int y; + private String color; + + public Shape(int x, int y, String color) { + this.x = x; + this.y = y; + this.color = color; + } + + public Shape(Shape target) { + if (target != null) { + this.x = target.x; + this.y = target.y; + this.color = target.color; + } + } + + public abstract Shape clone(); + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Shape shape = (Shape) o; + return x == shape.x && y == shape.y && Objects.equals(color, shape.color); + } +}