티스토리 뷰
반응형
1. GoF 디자인 패턴
의도
원형이 되는(prototypical) 인스턴스를 사용하여 생성할 객체의 종류를 명시하고, 이렇게 만든 견본을 복사해서 새로운 객체를 생성하는 것
동기
책에서 나온 예제를 요약하여 설명해보겠습니다. 원래 범용적으로 쓰이던 그래픽 프레임워크가 있는데, 새로 추가하고자 하는 음표와 보표에 대한 클래스를 넣고자 했을 때 그래픽 프레임 워크는 그래픽 관련 클래스를 상속 받은 서브 클래스를 필요로 하게 됩니다. 하지만 이렇게 되면 각 음표마다 클래스를 만들게 되는데 이러한 것을 해결하는 방법 중 하나가 '프로토 타입' 이라고 한다.
기본적으로 원형을 복제하고 setXyz 를 사용하여 값을 변형해 사용하는 방식을 쓴다면 클래스를 더 줄일 수 있다는 장점을 가질 수 있게 된다.
활용성
1. 인스턴스화할 클래스를 런타임에 지정할 때
2. 제품 클래스 계통과 병렬적으로 만드는 팩토리 클래스를 피하고 싶을 때
3. 클래스의 인스턴스들이 서로 다른 상태 조합 중에 어느 하나일 때 원형 패턴을 사용. 미리 원형으로 초기화해 두고, 나중에 이를 복제해서 사용하는 것이 매번 필요한 상태 조합의 값들을 수동적으로 초기화하는 것보다 더 편리할 수도 있다.
결과
1. 런타임에 새로운 제품을 추가하고 삭제할 수 있다.
2. 값들을 다양화함으로써 새로운 객체를 명세한다.(이 부분이 setter에 대한 내용. setter를 통해 원형을 기본으로 두고 그때 상황에 맞게 변수의 값을 지정함으로써 원형과 다른 객체를 얻는 행동)
3. 구조를 다양화함으로써 새로운 객체를 명세할 수 있다.
4. 서브클래스의 수를 줄일 수 있다.
5. 동적으로 클래스에 따라 응용프로그램을 설정할 수 있다.
예시
1. Building.java
public class Building {
private final Room prototypeRoom;
private final Wall prototypeWall;
public Building(Room room, Wall wall){
this.prototypeRoom = room;
this.prototypeWall = wall;
}
public Room makeRoom(){
return prototypeRoom.getInstance();
}
public Wall makeWall(){
return prototypeWall.getInstance();
}
}
Building.java가 'Client'에 해당하는 부분이다. (원형에 자기 자신의 복제를 요청하여 새로운 객체를 생성)
2. Room.java
public interface Room{
Room getInstance();
}
3. Wall.java
public interface Wall{
Wall getInstance();
}
Prototype으로서 자신을 복제하는 데 필요한 인터페이스를 정의
4. NormalWall.java
public class NormalWall implements Wall{
private String direction;
@Override
public String toString() {
return direction+"쪽 "+"벽 입니다!";
}
public void setDirection(String direction) {
this.direction = direction;
}
public NormalWall(){
this("WEST");
}
public NormalWall(String direction){
this.direction = direction;
}
public NormalWall(NormalWall room){ //복사 생성자
this.direction = room.direction;
}
@Override
public NormalWall getInstance() {
return new NormalWall(this);
}
}
NormalWall의 인스턴스처럼 원형으로 사용할 수 있는 객체는 반드시 getInstance() 연산을 제공해야 하고, 객체 복제를 위해 복사 생성자가 있어야 한다.
5.NormalRoom.java
public class NormalRoom implements Room{
private int size;
public void setSize(int size) {
this.size = size;
}
@Override
public String toString() {
return "사이즈가 "+ size+"인 "+"방 입니다!";
}
public NormalRoom(){
this(1);
}
public NormalRoom(int size){
this.size = size;
}
public NormalRoom(NormalRoom room){
this.size = room.size;
}
@Override
public NormalRoom getInstance() {
return new NormalRoom(this);
}
}
Test를 통해 사용하는 법 엿보기
class SimpleTest {
@Test
void test_프로토타입(){
Room room = new NormalRoom();
NormalWall wall = new NormalWall();
Building building = new Building(room,wall); // Client
NormalWall customWall = (NormalWall) building.makeWall();
customWall.setDirection("EAST"); // 원형을 가져와서 변형한다.
NormalRoom customRoom = (NormalRoom) building.makeRoom();
customRoom.setSize(3); // 원형을 가져와서 변형한다.
System.out.println(customWall);
System.out.println(customRoom);
}
}
참고: GoF 디자인 패턴
반응형
'knowledge' 카테고리의 다른 글
[JAVA] [Python] 자바의 상속과 파이썬의 상속 비교 (0) | 2021.11.19 |
---|---|
[JAVA] Adapter 패턴에 대하여 (0) | 2021.11.16 |
[Pattern][Java][Python] Singleton 생성 패턴에 대하여 (0) | 2021.11.04 |
[git] stash 활용 (0) | 2021.10.28 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- env
- 면접
- docker
- ubuntu
- Command Line
- PostgreSQL
- 알고리즘
- 프로그래머스
- postgres
- 2021 KAKAO BLIND RECRUITMENT
- 그래프
- thread
- Java
- Collections
- Python
- BFS
- Spring
- 백준
- dockerignore
- Celery
- docker-compose
- Linux
- setattr
- django
- headers
- 자바
- 파이썬
- DRF
- Pattern
- 카카오
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함