헤드 퍼스트 디자인 패턴 | 에릭 프리먼 | 한빛미디어- 교보ebook

14가지 GoF 필살 패턴!, 경력과 세대를 넘어 오랫동안 객체지향 개발자의 성장을 도와준 디자인 패턴 교과서의 화려한 귀환! 》 2005년부터 디자인 패턴 도서 분야 부동의 1위 》 디자인 패턴의 고

ebook-product.kyobobook.co.kr

패턴 개를 결합한다고 해서 무조건 복합 패턴이 아니다.

복합 패턴이라면 여러 가지 문제의 일반적인 해결법을 제시해야 한다.

 

기본형

public class Exam001Basic {
	//인터페이스
	static interface Quackable{
		void quack();
	}
	static class MallardDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class RedheadDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class DuckCall implements Quackable{
		public void quack() {
			System.out.println("꽉꽉");			
		}
	}
	static class RubberDuck implements Quackable{
		public void quack() {
			System.out.println("삑삑");			
		}
	}
	
	static class DuckSimulator{
		void simulate() {
			//인터페이스로 변수 다루기
			Quackable mallardDuck = new MallardDuck();
			Quackable redheadDuck = new RedheadDuck();
			Quackable duckCall = new DuckCall();
			Quackable rubberDuck = new RubberDuck();
			
			System.out.println("\n오리 시뮬레이션 게임");
			
			simulate(mallardDuck);
			simulate(redheadDuck);
			simulate(duckCall);
			simulate(rubberDuck);
		}
		
		//인터페이스로 메서드 인자로 다루기
		private void simulate(Quackable duck) {
			duck.quack();
		}
	}
	
	public static void main(String[] args) {
		DuckSimulator duckSimulator = new DuckSimulator();
		duckSimulator.simulate();
		duckSimulator.simulate(new DuckCall());
	}
}
오리 시뮬레이션 게임
꽥꽥
꽥꽥
꽉꽉
삑삑
꽉꽉

어댑터 추가

public class Exam002Adapter {
	//인터페이스
	static interface Quackable{
		void quack();
	}
	static class MallardDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class RedheadDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class DuckCall implements Quackable{
		public void quack() {
			System.out.println("꽉꽉");			
		}
	}
	static class RubberDuck implements Quackable{
		public void quack() {
			System.out.println("삑삑");			
		}
	}
	
	//어댑터 패턴
	static class Goose{
		void honk() {
			System.out.println("끾끾");
		}
	}
	static class GooseAdapter implements Quackable{
		Goose goose;
		public GooseAdapter(Goose goose) {
			this.goose = goose;
		}
		public void quack() {
			goose.honk();
		}
	}
	
	static class DuckSimulator{
		void simulate() {
			//인터페이스로 변수 다루기
			Quackable mallardDuck = new MallardDuck();
			Quackable redheadDuck = new RedheadDuck();
			Quackable duckCall = new DuckCall();
			Quackable rubberDuck = new RubberDuck();
			Quackable gooseAdapter = new GooseAdapter(new Goose());
			
			System.out.println("\n오리 시뮬레이션 게임");
			
			simulate(mallardDuck);
			simulate(redheadDuck);
			simulate(duckCall);
			simulate(rubberDuck);
			simulate(gooseAdapter);
		}
		
		//인터페이스로 메서드 인자로 다루기
		private void simulate(Quackable duck) {
			duck.quack();
		}
	}
	
	public static void main(String[] args) {
		DuckSimulator duckSimulator = new DuckSimulator();
		duckSimulator.simulate();
		duckSimulator.simulate(new DuckCall());
	}
}
오리 시뮬레이션 게임
꽥꽥
꽥꽥
꽉꽉
삑삑
끾끾
꽉꽉

데코레이터 패턴 적용하기

public class Exam003Decorator {
	//인터페이스
	static interface Quackable{
		void quack();
	}
	static class MallardDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class RedheadDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class DuckCall implements Quackable{
		public void quack() {
			System.out.println("꽉꽉");			
		}
	}
	static class RubberDuck implements Quackable{
		public void quack() {
			System.out.println("삑삑");			
		}
	}
	
	//어댑터 패턴
	static class Goose{
		void honk() {
			System.out.println("끾끾");
		}
	}
	static class GooseAdapter implements Quackable{
		Goose goose;
		public GooseAdapter(Goose goose) {
			this.goose = goose;
		}
		public void quack() {
			goose.honk();
		}
	}
	
	//데코레이터
	static class QuackCounter implements Quackable{
		Quackable duck;
		//이 클래스의 모든 인스턴스가 공유하는 변수
		static int count = 0;

		public QuackCounter(Quackable duck) {
			this.duck = duck;
		}

		public void quack() {
			++count;
			duck.quack();
		}
		
		static int getQuacks() {
			return count;
		}
		
	}
	
	static class DuckSimulator{
		void simulate() {
			//인터페이스로 변수 다루기
			Quackable mallardDuck = new QuackCounter(new MallardDuck());
			Quackable redheadDuck = new QuackCounter(new RedheadDuck());
			Quackable duckCall = new QuackCounter(new DuckCall());
			Quackable rubberDuck = new QuackCounter(new RubberDuck());
			Quackable gooseAdapter = new GooseAdapter(new Goose());
			
			System.out.println("오리 시뮬레이션 게임");
			
			simulate(mallardDuck);
			simulate(redheadDuck);
			simulate(duckCall);
			simulate(rubberDuck);
			simulate(gooseAdapter);
			
			System.out.println("오리가 소리낸 횟수 : "+QuackCounter.getQuacks());;
			
		}
		
		//인터페이스로 메서드 인자로 다루기
		private void simulate(Quackable duck) {
			duck.quack();
		}
	}
	
	public static void main(String[] args) {
		DuckSimulator duckSimulator = new DuckSimulator();
		duckSimulator.simulate();
	}
}
오리 시뮬레이션 게임
꽥꽥
꽥꽥
꽉꽉
삑삑
끾끾
오리가 소리낸 횟수 : 4

추상 팩터리 추가

public class Exam004AbstractFactory {
	//인터페이스
	static interface Quackable{
		void quack();
	}
	static class MallardDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class RedheadDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class DuckCall implements Quackable{
		public void quack() {
			System.out.println("꽉꽉");			
		}
	}
	static class RubberDuck implements Quackable{
		public void quack() {
			System.out.println("삑삑");			
		}
	}
	
	//어댑터 패턴
	static class Goose{
		void honk() {
			System.out.println("끾끾");
		}
	}
	static class GooseAdapter implements Quackable{
		Goose goose;
		public GooseAdapter(Goose goose) {
			this.goose = goose;
		}
		public void quack() {
			goose.honk();
		}
	}
	
	//데코레이터
	static class QuackCounter implements Quackable{
		Quackable duck;
		//이 클래스의 모든 인스턴스가 공유하는 변수
		static int count = 0;

		public QuackCounter(Quackable duck) {
			this.duck = duck;
		}

		public void quack() {
			++count;
			duck.quack();
		}
		
		static int getQuacks() {
			return count;
		}
		
	}
	
	//추상 팩토리
	abstract static class AbstractDuckFactory{
		public abstract Quackable createMallardDuck();
		public abstract Quackable createRedheadDuck();
		public abstract Quackable createDuckCall();
		public abstract Quackable createRubberDuck();
	}
	
	//팩토리 군
	static class DuckFactory extends AbstractDuckFactory{
		public Quackable createMallardDuck() {
			return new MallardDuck();
		}
		public Quackable createRedheadDuck() {
			return new RedheadDuck();
		}
		public Quackable createDuckCall() {
			return new DuckCall();
		}
		public Quackable createRubberDuck() {
			return new RubberDuck();
		}
	}
	//와...추상 팩토리 패턴을 이런 식으로 사용하네
	static class CountingDuckFactory extends AbstractDuckFactory{
		public Quackable createMallardDuck() {
			return new QuackCounter(new MallardDuck());
		}
		public Quackable createRedheadDuck() {
			return new QuackCounter(new RedheadDuck());
		}
		public Quackable createDuckCall() {
			return new QuackCounter(new DuckCall());
		}
		public Quackable createRubberDuck() {
			return new QuackCounter(new RubberDuck());
		}
	}
	
	static class DuckSimulator{
		void simulate(AbstractDuckFactory duckFactory) {
			//인터페이스로 변수 다루기
			Quackable mallardDuck = duckFactory.createMallardDuck();
			Quackable redheadDuck = duckFactory.createRedheadDuck();
			Quackable duckCall = duckFactory.createDuckCall();
			Quackable rubberDuck = duckFactory.createRubberDuck();
			Quackable gooseAdapter = new GooseAdapter(new Goose());
			
			System.out.println("오리 시뮬레이션 게임");
			
			simulate(mallardDuck);
			simulate(redheadDuck);
			simulate(duckCall);
			simulate(rubberDuck);
			simulate(gooseAdapter);
			
			System.out.println("오리가 소리낸 횟수 : "+QuackCounter.getQuacks());;
			
		}
		
		//인터페이스로 메서드 인자로 다루기
		private void simulate(Quackable duck) {
			duck.quack();
		}
	}
	
	public static void main(String[] args) {
		DuckSimulator duckSimulator = new DuckSimulator();
		AbstractDuckFactory duckFactory = new CountingDuckFactory();
		duckSimulator.simulate(duckFactory);
	}
}
오리 시뮬레이션 게임
꽥꽥
꽥꽥
꽉꽉
삑삑
끾끾
오리가 소리낸 횟수 : 4

컴포지트 패턴 추가

import java.util.ArrayList;
import java.util.List;

public class Exam005Composite {
	//인터페이스
	static interface Quackable{
		void quack();
	}
	static class MallardDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class RedheadDuck implements Quackable{
		public void quack() {
			System.out.println("꽥꽥");
		}
	}
	static class DuckCall implements Quackable{
		public void quack() {
			System.out.println("꽉꽉");			
		}
	}
	static class RubberDuck implements Quackable{
		public void quack() {
			System.out.println("삑삑");			
		}
	}
	
	//어댑터 패턴
	static class Goose{
		void honk() {
			System.out.println("끾끾");
		}
	}
	static class GooseAdapter implements Quackable{
		Goose goose;
		public GooseAdapter(Goose goose) {
			this.goose = goose;
		}
		public void quack() {
			goose.honk();
		}
	}
	
	//데코레이터
	static class QuackCounter implements Quackable{
		Quackable duck;
		//이 클래스의 모든 인스턴스가 공유하는 변수
		static int count = 0;

		public QuackCounter(Quackable duck) {
			this.duck = duck;
		}

		public void quack() {
			++count;
			duck.quack();
		}
		
		static int getQuacks() {
			return count;
		}
		
	}
	
	//추상 팩토리
	abstract static class AbstractDuckFactory{
		public abstract Quackable createMallardDuck();
		public abstract Quackable createRedheadDuck();
		public abstract Quackable createDuckCall();
		public abstract Quackable createRubberDuck();
	}
	
	//팩토리 군
	static class DuckFactory extends AbstractDuckFactory{
		public Quackable createMallardDuck() {
			return new MallardDuck();
		}
		public Quackable createRedheadDuck() {
			return new RedheadDuck();
		}
		public Quackable createDuckCall() {
			return new DuckCall();
		}
		public Quackable createRubberDuck() {
			return new RubberDuck();
		}
	}
	//와...추상 팩토리 패턴을 이런 식으로 사용하네
	static class CountingDuckFactory extends AbstractDuckFactory{
		public Quackable createMallardDuck() {
			return new QuackCounter(new MallardDuck());
		}
		public Quackable createRedheadDuck() {
			return new QuackCounter(new RedheadDuck());
		}
		public Quackable createDuckCall() {
			return new QuackCounter(new DuckCall());
		}
		public Quackable createRubberDuck() {
			return new QuackCounter(new RubberDuck());
		}
	}
	
	//컴포지트 패턴
	static class Flock implements Quackable{
		private final List<Quackable> quackers = new ArrayList<>();
		
		public void add(Quackable quackable) {
			quackers.add(quackable);
		}
		@Override
		public void quack() {
			//반복자패턴
			for(Quackable quackable : quackers) {
				quackable.quack();
			}
		}
	}
	
	static class DuckSimulator{
		
		void simulate(AbstractDuckFactory duckFactory) {
			//인터페이스로 변수 다루기
			Quackable mallardDuck = duckFactory.createMallardDuck();
			Quackable redheadDuck = duckFactory.createRedheadDuck();
			Quackable duckCall = duckFactory.createDuckCall();
			Quackable rubberDuck = duckFactory.createRubberDuck();
			Quackable gooseAdapter = new GooseAdapter(new Goose());
			
			System.out.println("오리 시뮬레이션 게임: 무리 (컴포지트패턴)");
			
			Flock flockOfDucks = new Flock();
			//다양한 오리
			flockOfDucks.add(mallardDuck);
			flockOfDucks.add(redheadDuck);
			flockOfDucks.add(duckCall);
			flockOfDucks.add(rubberDuck);
			flockOfDucks.add(gooseAdapter);
			
			Flock flockOfMallards = new Flock();
			
			//물오리
			flockOfMallards.add(duckFactory.createMallardDuck());
			flockOfMallards.add(duckFactory.createMallardDuck());
			flockOfMallards.add(duckFactory.createMallardDuck());
			flockOfMallards.add(duckFactory.createMallardDuck());

			//오리군에 물오리군을 추가
			flockOfDucks.add(flockOfMallards);
			
			System.out.println("\n오리 시뮬레이션 게임 : 전체 무리");
			simulate(flockOfDucks);
			System.out.println("\n오리 시뮬레이션 게임 : 물오리 무리");
			simulate(flockOfMallards);
			
			System.out.println("\n오리가 소리 낸 횟수 : " + QuackCounter.getQuacks());
			
		}
		
		//인터페이스로 메서드 인자로 다루기
		private void simulate(Quackable duck) {
			duck.quack();
		}
	}
	
	public static void main(String[] args) {
		DuckSimulator duckSimulator = new DuckSimulator();
		//데코레이터 객체를 생산하는 추상팩토리
		AbstractDuckFactory duckFactory = new CountingDuckFactory();
		duckSimulator.simulate(duckFactory);
	}
}
오리 시뮬레이션 게임: 무리 (컴포지트패턴)

오리 시뮬레이션 게임 : 전체 무리
꽥꽥
꽥꽥
꽉꽉
삑삑
끾끾
꽥꽥
꽥꽥
꽥꽥
꽥꽥

오리 시뮬레이션 게임 : 물오리 무리
꽥꽥
꽥꽥
꽥꽥
꽥꽥

오리가 소리 낸 횟수 : 12

옵저버 패턴 추가

import java.util.ArrayList;
import java.util.List;

public class Exam006Observer {
	
	static class MallardDuck implements Quackable{
		Observable observable;
		
		public MallardDuck() {
			observable = new Observable(this);
		}
		
		public void quack() {
			System.out.println("꽥꽥");
			notifyObservers();
		}

		public void registerObserver(Observer observer) {
			observable.registerObserver(observer);
		}
		public void notifyObservers() {
			observable.notifyObservers();
		}
		public void removeObserver(Observer observer) {
			observable.removeObserver(observer);
		}
		public String toString() {
			return "물오리";
		}
	}
	static class RedheadDuck implements Quackable{
		Observable observable;
		
		public RedheadDuck() {
			observable = new Observable(this);
		}
		public void quack() {
			System.out.println("꽥꽥");
			notifyObservers();
		}

		@Override
		public void registerObserver(Observer observer) {
			observable.registerObserver(observer);
		}
		public void notifyObservers() {
			observable.notifyObservers();
		}
		public void removeObserver(Observer observer) {
			observable.removeObserver(observer);
		}
		public String toString() {
			return "붉은오리";
		}
	}
	static class DuckCall implements Quackable{
		Observable observable;
		public DuckCall() {
			observable = new Observable(this);
		}
		public void quack() {
			System.out.println("꽉꽉");	
			notifyObservers();
		}

		public void registerObserver(Observer observer) {
			observable.registerObserver(observer);
		}
		public void notifyObservers() {
			observable.notifyObservers();
		}
		public void removeObserver(Observer observer) {
			observable.removeObserver(observer);
		}
		public String toString() {
			return "오리호출";
		}
	}
	static class RubberDuck implements Quackable{
		Observable observable;
		
		public RubberDuck() {
			observable = new Observable(this);
		}
		
		public void quack() {
			System.out.println("삑삑");
			notifyObservers();
		}

		public void registerObserver(Observer observer) {
			observable.registerObserver(observer);
		}
		public void notifyObservers() {
			observable.notifyObservers();
		}
		public void removeObserver(Observer observer) {
			observable.removeObserver(observer);
		}
		public String toString() {
			return "고무오리";
		}
	}
	
	//어댑터 패턴
	static class Goose{
		void honk() {
			System.out.println("끾끾");
		}
		public String toString() {
			return "거위";
		}
	}
	static class GooseAdapter implements Quackable{
		Goose goose;
		Observable observable;

		public GooseAdapter(Goose goose) {
			this.goose = goose;
			observable = new Observable(this);
		}
		public void quack() {
			goose.honk();
			notifyObservers();
		}
		public void registerObserver(Observer observer) {
			observable.registerObserver(observer);
		}
		public void notifyObservers() {
			observable.notifyObservers();
		}
		public void removeObserver(Observer observer) {
			observable.removeObserver(observer);
		}
		public String toString() {
			return "오리인척하는 거위";
		}
	}
	
	//데코레이터
	static class QuackCounter implements Quackable{
		Quackable duck;
		//이 클래스의 모든 인스턴스가 공유하는 변수
		static int count = 0;
		
		public QuackCounter(Quackable duck) {
			this.duck = duck;
		}

		public void quack() {
			++count;
			duck.quack();
		}
		
		static int getQuacks() {
			return count;
		}

		public void registerObserver(Observer observer) {
			duck.registerObserver(observer);
		}
		public void notifyObservers() {
			duck.notifyObservers();
		}
		public void removeObserver(Observer observer) {
			duck.removeObserver(observer);
		}
		@Override
		public String toString() {
			return duck.toString();
		}
	}
	
	//추상 팩토리
	abstract static class AbstractDuckFactory{
		public abstract Quackable createMallardDuck();
		public abstract Quackable createRedheadDuck();
		public abstract Quackable createDuckCall();
		public abstract Quackable createRubberDuck();
	}
	
	//팩토리 군
	static class DuckFactory extends AbstractDuckFactory{
		public Quackable createMallardDuck() {
			return new MallardDuck();
		}
		public Quackable createRedheadDuck() {
			return new RedheadDuck();
		}
		public Quackable createDuckCall() {
			return new DuckCall();
		}
		public Quackable createRubberDuck() {
			return new RubberDuck();
		}
	}
	//와...추상 팩토리 패턴을 이런 식으로 사용하네
	static class CountingDuckFactory extends AbstractDuckFactory{
		public Quackable createMallardDuck() {
			return new QuackCounter(new MallardDuck());
		}
		public Quackable createRedheadDuck() {
			return new QuackCounter(new RedheadDuck());
		}
		public Quackable createDuckCall() {
			return new QuackCounter(new DuckCall());
		}
		public Quackable createRubberDuck() {
			return new QuackCounter(new RubberDuck());
		}
	}
	
	//컴포지트 패턴
	static class Flock implements Quackable{
		private final List<Quackable> ducks = new ArrayList<>();
		
		public void add(Quackable quackable) {
			ducks.add(quackable);
		}
		@Override
		public void quack() {
			//반복자패턴
			for(Quackable quackable : ducks) {
				quackable.quack();
			}
		}
		@Override
		public void registerObserver(Observer observer) {
			for(Quackable duck : ducks) {
				duck.registerObserver(observer);
			}
		}
		public void notifyObservers() {	}
		public void removeObserver(Observer observer) {
			for(Quackable duck : ducks) {
				duck.registerObserver(observer);
			}
		}
		public String toString() {
			return "오리무리";
		}
	}
	
	//옵저버 패턴
	static interface QuackObservable{//주제
		void registerObserver(Observer observer);
		void removeObserver(Observer observer);
		void notifyObservers();
	}
	//인터페이스 + 옵저버 기능 추가
	static interface Quackable extends QuackObservable{
		void quack();
	}

	static class Observable implements QuackObservable{
		List<Observer> observers = new ArrayList<>();
		QuackObservable duck;
		
		public Observable(QuackObservable duck) {
			this.duck = duck;
		}
		public void registerObserver(Observer observer) {
			observers.add(observer);
		}
		public void removeObserver(Observer observer) {
			observers.remove(observer);
		}
		public void notifyObservers() {
			for(Observer observer : observers) {
				observer.update(duck);
			}
		}
		public String toString() {
			return observers.toString();
		}
	}
	static interface Observer{
		void update(QuackObservable duck);
	}
	static class Quackologist implements Observer{
		public void update(QuackObservable duck) {
			System.out.println("꽥꽥학자 : "+duck+"가 방금 소리냈다.") ;
		}
		public String toString() {
			return "꽥꽥학자";
		}
	}
	static class MrKim implements Observer{
		public void update(QuackObservable duck) {
			System.out.println("경수가 관찰중인 : " + duck);
		}
	}
	
	
	static class DuckSimulator{
		
		void simulate(AbstractDuckFactory duckFactory) {
			//인터페이스로 변수 다루기
			Quackable redheadDuck = duckFactory.createRedheadDuck();
			Quackable duckCall = duckFactory.createDuckCall();
			Quackable rubberDuck = duckFactory.createRubberDuck();
			Quackable gooseAdapter = new GooseAdapter(new Goose());
			
			
			Flock flockOfDucks = new Flock();
			//다양한 오리
			flockOfDucks.add(redheadDuck);
			flockOfDucks.add(duckCall);
			flockOfDucks.add(rubberDuck);
			flockOfDucks.add(gooseAdapter);
			
			Flock flockOfMallards = new Flock();
			
			//물오리
			flockOfMallards.add(duckFactory.createMallardDuck());
			flockOfMallards.add(duckFactory.createMallardDuck());
			flockOfMallards.add(duckFactory.createMallardDuck());
			flockOfMallards.add(duckFactory.createMallardDuck());

			//오리군에 물오리군을 추가
			flockOfDucks.add(flockOfMallards);
			
			System.out.println("\n오리 시뮬레이션 게임(옵저버)");
			Quackologist quackologist = new Quackologist();
			MrKim mrKim = new MrKim();
			flockOfDucks.registerObserver(quackologist);
			flockOfDucks.registerObserver(mrKim);
			
			simulate(flockOfDucks);
			
			System.out.println("\n오리가 소리 낸 횟수 : " + QuackCounter.getQuacks());
			
		}
		
		//인터페이스로 메서드 인자로 다루기
		private void simulate(Quackable duck) {
			duck.quack();
		}
	}
	
	public static void main(String[] args) {
		DuckSimulator duckSimulator = new DuckSimulator();
		//데코레이터 객체를 생산하는 추상팩토리
		AbstractDuckFactory duckFactory = new CountingDuckFactory();
		duckSimulator.simulate(duckFactory);
	}
}
오리 시뮬레이션 게임(옵저버)
꽥꽥
꽥꽥학자 : 붉은오리가 방금 소리냈다.
경수가 관찰중인 : 붉은오리
꽉꽉
꽥꽥학자 : 오리호출가 방금 소리냈다.
경수가 관찰중인 : 오리호출
삑삑
꽥꽥학자 : 고무오리가 방금 소리냈다.
경수가 관찰중인 : 고무오리
끾끾
꽥꽥학자 : 오리인척하는 거위가 방금 소리냈다.
경수가 관찰중인 : 오리인척하는 거위
꽥꽥
꽥꽥학자 : 물오리가 방금 소리냈다.
경수가 관찰중인 : 물오리
꽥꽥
꽥꽥학자 : 물오리가 방금 소리냈다.
경수가 관찰중인 : 물오리
꽥꽥
꽥꽥학자 : 물오리가 방금 소리냈다.
경수가 관찰중인 : 물오리
꽥꽥
꽥꽥학자 : 물오리가 방금 소리냈다.
경수가 관찰중인 : 물오리

오리가 소리 낸 횟수 : 7

복합 패턴에서 가장 유명한 것은 MVC 패턴

  • Model (옵저버 패턴)
  • Controller(전략 패턴)
  • View(컴포지트 패턴)

+ Recent posts