Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Spring Cloud Netflix
- JPA
- multipart테스트
- intellij 핵심 단축키
- vue.js
- 자바 ORM 표준 JPA 프로그래밍 정리
- git
- #docker compose
- 리눅스
- CompletableFuture
- 리팩토링 2판
- ksql
- ksqldb
- @Transactional Propagation
- 백명석님
- 자바 ORM 표준 JPA 프로그래밍
- 원격 브랜 삭제
- IntelliJ
- Linux
- java
- javascript case
- @TransactionalEventListener
- aws
- findTopBy
- Stream
- intellij 즐겨찾기
- 친절한 SQL 튜닝
- intellij favorites
- 마이크로 서비스
- HandlerMethodArgumentResolver
Archives
- Today
- Total
시그마 삽질==six 시그마
컴퍼지트 패턴(Composite pattern) 본문
'Java 객체 지향 디자인 패턴' 책을 구입하시길 추천드립니다.
책 구입을 원하시는분은 요기를 클릭하시면 됩니다.
하단의 내용은 제가 예전에 읽었던 내용을 요약 정리한 것입니다.
In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes a group of objects that are treated the same way as a single instance of the same type of object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.
Source: https://en.wikipedia.org/wiki/Composite_pattern
컴퍼지트 패턴은 부분-전체의 관계를 갖는 객체들을 정의할때 사용하는 패턴이다
Component: 구체적인 부분, 즉 Leaf 클래스와 전체에 해당하는 Composite 클래스에 공통 인터페이스를 정의한다
Leaf: 구체적인 부분 클래스로 Composite 객체의 부품으로 설정한다
Composite: 전체 클래스로 복수개의 Component를 갖도록 정의한다
컴퓨터의 전력량을 계산하는 로직이다
public class Computer {
private Body body ;
private Keyboard keyboard ;
private Monitor monitor ;
public void addBody(Body body) { this.body = body ; }
public void addKeyboard(Keyboard keyboard) { this.keyboard = keyboard ; }
public void addMonitor(Monitor monitor) { this.monitor = monitor ; }
public int getPrice() {
int bodyPrice = body.getPrice() ;
int keyboardPrice = keyboard.getPrice() ;
int monitorPrice = monitor.getPrice() ;
return bodyPrice + keyboardPrice + monitorPrice ;
}
public int getPower() {
int bodyPower = body.getPower() ;
int keyboardPower = keyboard.getPower() ;
int monitorPower = monitor.getPower() ;
return bodyPower + keyboardPower + monitorPower ;
}
}
public class Body {
private int price ;
private int power;
public Body(int power, int price) {
this.power = power ;
this.price = price ;
}
public int getPrice() { return price ; }
public int getPower() { return power; }
}
public class Keyboard {
private int price ;
private int power;
public Keyboard(int power, int price) {
this.power = power ;
this.price = price ;
}
public int getPrice() {
return price ;
}
public int getPower() {
return power;
}
}
public class Monitor {
private int price ;
private int power;
public Monitor(int power, int price) {
this.power = power ;
this.price = price ;
}
public int getPrice() { return price ; }
public int getPower() { return power; }
}
public class Client {
public static void main(String[] args) {
// 컴퓨터의 부품으로 Body, Keyboard, Monitor 객체를 생성함
Body body = new Body(100, 70) ;
Keyboard keyboard = new Keyboard(5, 2) ;
Monitor monitor = new Monitor(20, 30) ;
// Computer 객체를 생성하고 부품 객체들을 설정함
Computer computer = new Computer() ;
computer.addBody(body) ;
computer.addKeyboard(keyboard) ;
computer.addMonitor(monitor) ;
//컴퓨터의 가격과 전력 소비량을 구함
int computerPrice = computer.getPrice() ;
int computerPower = computer.getPower() ;
System.out.println("Computer Power: " + computerPower + " W") ;
System.out.println("Computer Price: " + computerPrice + " 만원") ;
}
}
만약 요기서 컴퓨터 클래스의 부품으로 Speaker 클래스를 추가한다면? 또는 Mouse 클래스를 추가한다면?
새로운 객체 참조를 컴퓨터 클래스에 추가하고, setter 메서드인 add 메서드 추가,getPrice 메서드 추가해야함
문제의 핵심은 Computer 클래스에 속한 부품의 구체적인 객체를 가리키게 되면 OCP를 위반하게 됨
즉 Computer 클래스가 Monitor,Body, Keyboard,Speaker 객체들을 직접 가리키면 이러한 부품의 변화에 따라 Computer 클래스의 코드도 변할 수 밖에 없음
그러므로 구체적인 부품들을 일반화한 클래스를 정의하고 이를 Computer 클래스가 가리키게 하는것이 올바른 설계임
public abstract class ComputerDevice {
public abstract int getPrice() ;
public abstract int getPower() ;
}
public class Computer extends ComputerDevice {
private List<ComputerDevice> components = new ArrayList<ComputerDevice>() ;
public void addComponent(ComputerDevice component) {
components.add(component) ;
}
public void removeComponent(ComputerDevice component) {
components.remove(component) ;
}
public int getPrice() {
int price = 0 ;
for ( ComputerDevice component: components )
price += component.getPrice() ;
return price ;
}
public int getPower() {
int power = 0 ;
for ( ComputerDevice component: components )
power += component.getPower() ;
return power ;
}
}
public class Body extends ComputerDevice {
private int price ;
private int power;
public Body(int power, int price) {
this.power = power ;
this.price = price ;
}
public int getPrice() {
return price ;
}
public int getPower() {
return power;
}
}
public class Keyboard extends ComputerDevice {
private int price ;
private int power;
public Keyboard(int power, int price) {
this.power = power ;
this.price = price ;
}
public int getPrice() {
return price ;
}
public int getPower() {
return power;
}
}
public class Monitor extends ComputerDevice {
private int price ;
private int power;
public Monitor(int power, int price) {
this.power = power ;
this.price = price ;
}
public int getPrice() {
return price ;
}
public int getPower() {
return power;
}
}
public class Client {
public static void main(String[] args) {
Computer computer = new Computer() ;
Body body = new Body(100, 70) ;
Keyboard keyboard = new Keyboard(5, 2) ;
Monitor monitor = new Monitor(20, 30) ;
computer.addComponent(body) ;
computer.addComponent(keyboard) ;
computer.addComponent(monitor) ;
int computerPrice = computer.getPrice() ;
int computerPower = computer.getPower() ;
System.out.println("Computer Power: " + computerPower + " W") ;
System.out.println("Computer Price: " + computerPrice + " 만원") ;
}
}
컴포지트 패턴의 단골 예시는 디렉토리와 파일이다
public abstract class AbstractFile {
private String name ;
private int depth = 0 ;
public AbstractFile(String name) { this.name = name ; }
public String getName() { return name; }
public void setDepth(int depth) { this.depth = depth ; }
public int getDepth() { return depth ; }
public abstract int getSize() ;
public abstract void print() ;
}
public class Directory extends AbstractFile {
private List<AbstractFile> files = new ArrayList<AbstractFile>();
public Directory( String name ) { super(name) ; }
public void addEntry(AbstractFile entry) {
entry.setDepth(getDepth()+1) ;
files.add(entry) ;
}
public void removeEntry(AbstractFile entry) {
files.remove(entry) ;
}
public int getSize() {
int totalSize = 0 ;
for (AbstractFile entry: files) totalSize += entry.getSize();
return totalSize;
}
public void print() {
for ( int i = 0 ; i < getDepth() ; i ++ )
System.out.print("\t") ;
System.out.println("[Directory] " + getName() + ", Size: " + getSize()) ;
for ( AbstractFile entry: files ) entry.print() ;
}
}
public class File extends AbstractFile {
private int size ;
public File( String name, int size ) {
super(name) ;
this.size = size ;
}
public int getSize() { return size ; }
public void print() {
for ( int i = 0 ; i < getDepth() ; i ++ )
System.out.print("\t") ;
System.out.println("[File] " + getName() + ", Size: " + size) ;
}
}
public class Client {
public static void main(String[] args) {
Directory dir1 = new Directory("root") ;
Directory dir2 = new Directory("Dir1") ;
File f1 = new File("f1", 100) ;
File f2 = new File("f2", 200) ;
File f3 = new File("f3", 300) ;
File f4 = new File("f4", 400) ;
dir1.addEntry(f1) ;
dir1.addEntry(dir2) ;
dir2.addEntry(f2) ;
dir2.addEntry(f3) ;
dir1.addEntry(f4) ;
dir1.print() ;
}
}
'프로그래밍 > 디자인패턴' 카테고리의 다른 글
Facade pattern (0) | 2020.04.30 |
---|---|
옵저버 패턴(Observer Pattern) (0) | 2020.04.25 |
데코레이터 패턴(Decorator pattern) (0) | 2020.04.24 |
스테이트 패턴(State pattern) (0) | 2020.04.24 |
전략 패턴(Strategy Pattern) (0) | 2020.04.24 |
Comments