* 디자인 패턴 구성
- 패턴 이름 및 유형
- 설계 의도를 표현하며 한 두 단어로 설계 문제와 해법 서술
- 문제 및 배경
- 해결해야할 문제와 그 배경 설명하며 언제 패턴 사용하는지 서술
- 해결
- 설계 구성 요소와 그 요소들 간 관계, 책임, 협력관계 서술
- 사례
- 간단한 적용 사례 서술
- 결과
- 디자인 패턴 적용해서 얻는 결과와 장단점 서술
- 샘플코드
- 패턴이 적용된 원시 코드 기술
* GoF(Gang of Four) 디자인 패턴
목적 | 생성 패턴 | 구조 패턴 | 행위 패턴 | |
암기 | FSABP | ABCD2FP | T2I2C2S2MVO | |
의미 | 객체 생성방식 결정 | 객체 조직화 | 객체 행위를 조직, 관리, 연합 | |
범위 | 클래스 |
Factory method | Adapter | Template method Interpereter |
객체 | Singleton Abstract factory Builder Prototype |
Bridge Composite Decorator Facade Fly weight Proxy |
Iterator Command Chain of Resposibility State Strategy Mediator Memento Visitor Observer |
① 생성패턴(Creation Pattern) : 객체 인스턴스 생성 위한 클래스 정의와 객체 생성 방식 구조화 캡슐화 방법 등 제공
종류 | 개념 |
Factory method | - 객체 생성하기 위한 인터페이스 따로 정의하며 어떤 클래스에서 객체 생성하는 일을 서브 클래스가 담당하도록 함 - Virtual-Constructor 패턴 |
Singleton | - 지정한 클래스 인스턴스가 반드시 한 개만 존재하도록 함 |
Abstract factory | - 구체적인 클래스 지정 않고 관련성 갖는 객체들 집합을 생성하거나 서로 독립적인 객체들 집합 생성할 수 있는 인터페이스 제공 |
Builder | - 복잡한 객체 생성하는 방법과 표현하는 방법 정의하는 클래스를 별도로 분리해 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차 제공 |
Prototype | - 원본이 되는 인스턴스 사용하여 생성할 객체 종류 명시하고, 견본 복사해서 새로운 객체 생성 |
* Factory method 예
interface Pizza {
public void prepare();
public void bake();
public void box();
}
abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type); // factory method 사용
pizza.prepare();
pizza.bake();
pizza.box();
return pizza;
}
// factory method
abstract Pizza createPizza(String type);
}
class NYPizzaStore extends PizzaStore {
@Override
Pizza createPizza(String type) {
if ("cheese".equals(type)) {
return new NYStyleCheesePizza();
} else if ("pepperoni".equals(type)) {
return new NYStylePepperoniPizza();
}
return null;
}
}
class ChicagoPizzaStore extends PizzaStore {
@Override
Pizza createPizza(String type) {
if ("cheese".equals(type)) {
return new ChicagoStyleCheesePizza();
} else if ("pepperoni".equals(type)) {
return new ChicagoStylePepperoniPizza();
}
return null;
}
}
//사용
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
Pizza pizza1 = chicagoStore.orderPizza("pepperoni");
* Singleton 예
- 전역변수 사용 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴
public class Printer {
// 외부에 제공할 자기 자신의 인스턴스
private static Printer printer = null;
private Printer() { }
// 자기 자신의 인스턴스를 외부에 제공
public static Printer getPrinter(){
if (printer == null) {
// Printer 인스턴스 생성
printer = new Printer();
}
return printer;
}
public void print(String str) {
System.out.println(str);
}
}
public class User {
private String name;
public User(String name) { this.name = name; }
public void print() {
Printer printer = printer.getPrinter();
printer.print(this.name + " print using " + printer.toString());
}
}
public class Client {
private static final int USER_NUM = 5;
public static void main(String[] args) {
User[] user = new User[USER_NUM];
for (int i = 0; i < USER_NUM; i++) {
// User 인스턴스 생성
user[i] = new User((i+1))
user[i].print();
}
}
}
* Abstract factory 예
// 피자 원재료를 생산하는 팩토리 인터페이스
interface PizzaIngredientFactory {
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
public Veggies[] createVeggies();
public Pepperoni createPepperoni();
public Clams createClams();
}
// 뉴욕 피자 가게
public class NYPizzaStore extends PizzaStore {
protected Pizza createPizza(String item) {
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if (item.equals("cheese")) {
// 치즈 피자
pizza = new CheesePizza(ingredientFactory); // 팩토리를 주입한다
pizza.setName("New York Style Cheese Pizza");
} else if (item.equals("veggie")) {
// 야채 피자
pizza = new VeggiePizza(ingredientFactory);
pizza.setName("New York Style Veggie Pizza");
} else if (item.equals("clam")) {
// 조개 피자
pizza = new ClamPizza(ingredientFactory);
pizza.setName("New York Style Clam Pizza");
} else if (item.equals("pepperoni")) {
// 페퍼로니 피자
pizza = new PepperoniPizza(ingredientFactory);
pizza.setName("New York Style Pepperoni Pizza");
}
return pizza;
}
}
* Builder 예
/* Builder 인터페이스 */
class MazeBuilder {
public :
virtual void BuildMaze() { }
virtual void BuildRoom(int room) { }
virtual void BuildDoor(int roomFrom, int roomTo) { }
virtual Maze* GetMaze() { return 0; }
protected :
MazeBuilder();
}
/* 표준적인 방, 문, 미로를 만드는 Builder 구현체 */
class StandardMazeBuilder : public MazeBuilder {
public :
StandardMazeBuilder();
virtual void BuildMaze();
virtual void BuildRoom(int);
virtual void BuildDoor(int, int);
Virtual Maze* GetMaze();
private :
Direction CommonWall(Room*, Room*);
Maze* _currentMaze;
};
/* 미로는 만들지 않고 방과 문의 숫자를 세는 Builder 구현체 */
class CountingMazeBuilder : public MazeBuilder {
public :
CountingMazeBuilder();
virtual void BuildMaze();
virtual void BuildRoom(int);
virtual void BuildDoor(int, int);
virtual void AddWall(int, Direction);
void GetCount(int &, int &) const;
private :
int _doors;
int _rooms;
}
/* 기본 미로를 만드는 Director */
Maze* MazeGame::CreateMaze(MazeBuilder& builder) {
builder.BuilderMaze();
builder.BuildRoom(1);
builder.BuildRoom(2);
builder.BuildDoor(1, 2);
return builder.GetMaze();
}
/* 복잡한 미로를 만드는 Director */
Maze* MazeGame::CreateComplexMaze(MazeBuilder& builder) {
builder.BuildRoom(1);
// ...
builder.BuildRoom(1001);
return builder.GetMaze();
}
//사용
Maze * maze; /* product */
MazeGame game; /* director */
StandardMazeBuilder builder; /* builder */
game.CreateMaze(builder);
maze = builder.GetMaze();
* Prototype 예
public abstract class Shape implements Cloneable {
protected Type type;
abstract void draw();
@Override
public Object clone() throws CloneNotSupportedException {
Object clone = null;
try {
clone = super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return clone;
}
}
public class Circle extends Shape {
public Circle() {
this.type = Type.CIRCLE;
}
@Override
void draw() {
System.out.println("[Circle]");
}
}
public class ShapeStore {
private static Map<Type, Shape> shapeMap = new HashMap<Type, Shape>();
public void registerShape() {
Rectangle rec = new Rectangle();
Circle cir = new Circle();
Triangle tri = new Triangle();
shapeMap.put(rec.type, rec);
shapeMap.put(cir.type, cir);
shapeMap.put(tri.type, tri);
}
public Shape getShape(Type type) {
return (Shape)shapeMap.get(type).clone();
}
}
public class Main {
public static void main(String[] args) {
ShapeStore manager = new ShapeStore();
manager.registerShape();
Circle cir1 = (Circle)manager.getShape(Type.CIRCLE);
cir1.draw();
Circle cir2 = (Circle)manager.getShape(Type.CIRCLE);
cir2.draw();
Rectangle rec1 = (Circle)manager.getShape(Type.RECTANGLE);
rec1.draw();
Triangle tri1 = (Circle)manager.getShape(Type.TRIANGLE);
tri1.draw();
}
}
320x100
'정보처리기사 > 필기' 카테고리의 다른 글
[정보처리기사 필기 요약] 디자인 패턴(3) - 행위패턴 (0) | 2021.03.02 |
---|---|
[정보처리기사 필기 요약] 디자인 패턴(2) - 구조패턴 (0) | 2021.03.02 |
[정보처리기사 필기 요약] 객체지향 설계원칙 (SOLID) (0) | 2021.03.02 |
[정보처리기사 필기 요약] 객체지향 (0) | 2021.03.02 |
[정보처리기사 필기 요약] 코드의 기능 (0) | 2021.03.02 |
댓글