티스토리 뷰
복합패턴 - 여러 패턴을 함께 사용하는 것
복합 패턴 예제
- 오리 시뮬레이션 게임
public interface Quackable {
public void quack();
}
public class MallardDuck implements Quackable {
public void quack() {
System.out.println("꽥꽥");
}
}
public class DuckCall implements Quackable {
public void quack() {
System.out.println("꽉꽉");
}
}
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
void simulate() {
Quackable mallardDuck = new MallardDuck();
Quackable duckCall = new DuckCall();
System.out.println("\n오리 시뮬레이션 게임");
simulate(mallardDuck);
simulate(duckCall);
}
void simulate(Quackable duck) {
duck.quack();
}
}
거위를 추가하려고함
-> 어댑터 패턴(호환성 인터페이스)을 사용
public class Goose {
public void honk() {
System.out.println("끽끽");
}
}
public class GooseAdapter implements Quackable {
Goose goose;
public GooseAdapter(Goose goose) {
this.goose = goose;
}
public void quack() {
goose.honk();
}
}
오리 시뮬레이터에도 거위 추가
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
void simulate() {
Quackable mallardDuck = new MallardDuck();
Quackable duckCall = new DuckCall();
Quackable goose = new GooseAdapter(new Goose()); // Goose를 어댑터로 감싸줌
System.out.println("\n오리 시뮬레이션 게임");
simulate(mallardDuck);
simulate(duckCall);
simulate(goose); // 거위지만 오리 메소드 실행 가능
}
void simulate(Quackable duck) {
duck.quack();
}
오리가 소리를 낸 횟수를 count 하려고 함
-> 오리가 소리를 낸 횟수를 count 하기 위해 데코레이터 패턴(객체에 기능추가) 사용
// 데코레이터 클래스 QuackCounter
public class QuackCounter implements Quackable {
Quackable duck;
static int numberOfQuacks; // 모든 객체에서 count해야해서 정적 static 사용
public QuackCounter(Quackable duck) {
this.duck = duck;
}
public void quack() {
duck.quack();
numberOfQuacks++;
}
public static int getQuacks() {
return numberOfQuacks;
}
}
Quackable을 채택하는 QuackCounter
Quackable 객체를 생성할때 QuackCounter 데코레이터로 감싸줌.
데코레이터의 quack() 메소드 실행시 -> 소리냄 + count 동작을 하도록 함
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
simulator.simulate();
}
void simulate() {
Quackable mallardDuck = new QuackCounter(new MallardDuck());
Quackable duckCall = new QuackCounter(new DuckCall());
// Quackable을 데코레이터로 감싸 줌
Quackable goose = new GooseAdapter(new Goose());
System.out.println("\n오리 시뮬레이션 게임");
simulate(mallardDuck);
simulate(duckCall);
simulate(goose);
System.out.println("오리가 소리 낸 횟수 : " + QuackCounter.getQuacks() + " 번");
}
void simulate(Quackable duck) {
duck.quack();
}
}
새로운 행동을 추가 하기위해선 데코레이터로 감싸야함
-> 모든 오리를 데코레이터로 감싸려고 함
-> 팩토리 패턴 사용
-> 여러 오리의 종류를 생산해야 하므로
-> 추상 팩토리 패턴을 사용하여 캡슐화
public abstract class AbstractDuckFactory {
public abstract Quackable createMallardDuck();
public abstract Quackable createDuckCall();
}
public class DuckFactory extends AbstractDuckFactory {
// 각 메소드는 Quackable 객체를 만들고
// 시뮬레이터는 뭐가 만들어지는지는 모르며,
// Quackable형태가 리턴되는것만 알게 됨
public Quackable createMallarDuck() {
return new MallardDuck();
}
public Quackable createDuckCall() {
return new DuckCall();
}
}
public class CountingDuckFactory extends AbstractDuckFactory {
public Quackable createMallardDuck() {
return new QuackCounter(new MallardDuck());
}
public Quackable createDuckCall() {
return new QuackCounter(new DuckCall());
}
}
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory); // simulate에 전달할 팩토리 생성 후 전달
}
void simulate(AbstractDuckFactory duckFactory) {
Quackable mallardDuck = duckFactory.createMallardDuck();
Quackable duckCall = duckFactory.createDuckCall();
// 팩토리 메소드에서 객체 생성 해줌
Quackable goose = new GooseAdapter(new Goose());
System.out.println("\n오리 시뮬레이션 게임");
simulate(mallardDuck);
simulate(duckCall);
simulate(goose)
System.out.println("오리가 소리 낸 횟수 : " + QuackCounter.getQuacks() + " 번");
}
void simulate(Quackable duck) {
duck.quack();
}
}
CountingDuckFactory를 사용하면
모든 오리를 데코레이터로 확실하게 감쌀 수 있음.
오리를 1마리씩 관리하는것보다 컴포지트 패턴을 사용하여
무리로 관리하면 좋음
public class Flock implements Quackable {
List<Quackable> quackers = new ArrayList<Quackable>();
public void add(Quackable quacker) {
quackers.add(quacker);
}
public void quack() {
Iterator<Quackable> it = quackers.iterator(); // 반복자 패턴
while (it.hasNext()) {
Quackable quacker = it.next(); // 순환문
quacker.quack();
}
}
}
public class DuckSimulator {
// main 메소드
void simulate(AbstractDuckFactory duckFactory) {
Quackable redheadDuck = duckFactory.createRedheadDuck();
Quackable duckCall = duckFactory.createDuckCall();
Quackable rubberDuck = duckFactory.createRubberDuck();
Quackable gooseDuck = duckFactory.createGoose();
System.out.println("\n오리 시뮬레이션 게임 : 무리 (+컴포지트)");
Flock flockOfDucks = new Flock(); // 오리 무리
flockOfDucks.add(redheadDuck);
flockOfDucks.add(duckCall);
flockOfDucks.add(rubberDuck);
flockOfDucks.add(gooseDuck);
Flock flockOfMallards = new Flock(); // 물오리 무리 (물오리만 포함)
// 물오리 무리 생성
Quackable mallardOne = duckFactory.createMallardDuck();
Quackable mallardTwo = duckFactory.createMallardDuck();
Quackable mallardThree = duckFactory.createMallardDuck();
Quackable mallardFour = duckFactory.createMallardDuck();
flockOfMallards.add(mallardOne);
flockOfMallards.add(mallardTwo);
flockOfMallards.add(mallardThree);
flockOfMallards.add(mallardFour);
flockOfDucks.add(flockOfMallards); // 물오리 무리를 오리 무리에 추가
System.out.println("오리 시뮬레이션 게임 : 전체 무리");
simulate(flockOfDucks);
System.out.println("오리 시뮬레이션 게임 : 물오리 무리");
simulate(flockOfMallards);
System.out.println("오리가 소리 낸 횟수 : " + QuackCounter.getQuacks() + " 번");
}
void simulate(Quackable duck) {
duck.quack();
}
}
오리 각각 1마리의 행동을 관찰하고 싶음. (어떤 오리가 소리를 내었는지)
-> 옵저버 패턴을 사용
옵저버블 인터페이스
// QuackObservable 인터페이스
public interface QuackObservable { // Quackable를 다른 객체에서 관측하고자 함
public void registerObserver(Observer observer); // 옵저버 등록 메소드
public void notifyObservers(); // 옵저버 알림 메소드
}
// 모든 Quackable에서 이 인터페이스를 구현하도록 해야함
public interface Quackable extends QuackObservable {
public void quack();
}
옵저버 인터페이스
public interface Observer {
// 소리를 내는 QuackObservable를 인자로 전달받는 update 메소드
public void update(QuackObservable duck);
}
public class Quackologist implements Observer {
public void update(QuackObservable duck) {
System.out.println("꽥꽥학자 : " + duck + "가 소리냈다.");
}
}
Observable에서 Quackable이 관찰 대상이 될 때 필요한 기능을 정의함.
Observable 객체를 다른 클래스에 넣은 다음 필요한 작업을 Observable에 위임하려고 함.
public class Observable implements QuackObservable {
List<Observer> observers = new ArrayList<Observer>();
// 생성자의 인자로 Observer 객체를 써서 관측할 객체를 전달함
QuackObservable duck;
public Observable(QuackObservable duck) {
this.duck = duck;
}
public void registerObserver(Observer observer) { // 옵저버 등록
observers.add(observer);
}
public void notifyObservers() {
Iterator<Observer> it = observers.iterator();
while (it.hasNext()) {
Observer observer = it.next(); // 연락 돌리는 코드
observer.update(duck);
}
}
}
Observer 보조 객체와 Quackable 클래스 결합해주기
public class MallardDuck implements Quackable {
Observable observable; // Quackable에 Observable 변수 생성
public MallardDuck() {
this.observable = new Observable(this);
// 생성자에서 Observable 객체를 만들고
// MallardDuck 객체의 레퍼런스를 인자로 전달
}
public void quack() {
System.out.println("꽥꽥");
notifyObservers(); // quack() 호출되면 옵저버들에게 알려줌
}
// QuackObservable 에서 정의한 메소드, 보조 객체에 떠넘김
public void registerObserver(Observer observer) {
this.observable.registerObserver(observer);
}
// QuackObservable 에서 정의한 메소드, 보조 객체에 떠넘김
public void notifyObservers() {
this.observable.notifyObservers();
}
}
void simulate(AbstractDuckFactory duckFactory) {
// 오리 팩토리와 오리 생성
// 오리 무리 생성
Quackologist quackologist = new Quackologist();
flockOfDucks.registerObserver(quackologist);
simulate(flockOfDucks);
System.out.println("오리가 소리 낸 횟수 : " + QuackCounter.getDuckCnt() + " 번");
}
- Total
- Today
- Yesterday
- swift excel read
- swift 엑셀 읽기
- 엔디소프트 레이세이
- swift get excel
- focus timer 어플
- llm csv
- rag 기반 llm
- swift network refactoring
- swift network module
- swift urlsession 공통화
- swift urlcomponent encode
- swift urlsession module
- rag 기반 llm 챗봇
- swift 네트워크 모듈화
- 레디세이
- swift filemanager excel
- swift urlsession refactoring
- filemanager excel read
- swift 자간
- 공부 타이머 어플
- chatgpt rag llm
- rag llm pdf
- llm pdf rag
- swift urlsession network module
- swift queryitem encode
- swift filemanager get excel
- swift 엑셀 가져오기
- swift network 공통화
- readysay
- 레디세이 어플
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |