독립된 기능을 가진 부속들을 모아 하나의 결과물로 만드는 걸 Composition
이라 부른다.
Composition
은 사용된 부속들이 가진 고유한 속성이 바뀌지 않는다Assemble
은 처음부터 하나하나가 특성을 가지지 않는다.우리는 Domain을 분해하여 각각 Component로 분리한 다음, Composition하고 싶다.
‘복잡한 현실 세계를 어떻게 Decomposition할 것인가?’
Functional을 기능적이 아니라 함수적이라 해석해도 무방하다.
Functional decomposition는 개발 용어 이전에 수학적 용어이기도 하다.
flow
로 바라보고 기능을 분해할 수 있다는 입장.Lazy Binding
을 통해 구상형을 바라보게 하기 위한 수단이다.public class Paper {
public Paper(boolean isClient) {
this.isClient = isClient;
}
public final boolean isClient;
Library library = new Library("vueJS");
Language language = new Language("kotlinJS");
Programmer programmer;
Server server = new Server("test");
Language backEndLanguage = new Language("java");
Language frontEndLanguage = new Language("kotlinJS");
private Programmer backEndProgrammer;
private Programmer frontEndProgrammer;
public void setBackEndProgrammer(Programmer programmer) {
if (!isClient)
backEndProgrammer = programmer;
}
public void setFrontEndProgrammer(Programmer programmer) {
if (!isClient)
frontEndProgrammer = programmer;
}
public void setProgrammer(Programmer programmer) {
if (isClient)
this.programmer = programmer;
}
}
public class Programmer {
public Programmer(Boolean isFrontEnd) {
this.isFrontEnd = isFrontEnd;
}
public final boolean isFrontEnd;
private Language frontLanguage;
private Library frontLibrary;
private Server server;
private Language backEndLanguage;
public Program makeProgram(Paper paper) {
if (isFrontEnd) {
frontLanguage = paper.getFrontEndLanguage();
frontLibrary = paper.getFrontEndLibrary();
} else {
this.server = paper.getServer();
this.backEndLanguage = paper.getBackEndLanguage();
}
return isFrontEnd ? makeFrontEndProgram() : makeBackEndProgram();
}
private Program makeFrontEndProgram() {
return new Program();
}
private Program makeBackEndProgram() {
return new Program();
}
}
Programmer는 isFrontEnd를 통해 두 가지 상태로 나눠진다.
추상화의 크기가 다르면 단계가 맞지 않아서 인식하기 어렵다.
boolean을 통해 모든 개발자를 통합한 추상형을 만들었다.
ADT는 형끼리 결합할 수 없다.
public class Paper {
public Paper(boolean isClient) {
this.isClient = isClient;
}
public final boolean isClient;
Library library = new Library("vueJS");
Language language = new Language("kotlinJS");
Programmer programmer;
Server server = new Server("test");
Language backEndLanguage = new Language("java");
Language frontEndLanguage = new Language("kotlinJS");
private Programmer backEndProgrammer;
private Programmer frontEndProgrammer;
public void setBackEndProgrammer(Programmer programmer) {
if (!isClient) {
backEndProgrammer = programmer;
}
}
public void setFrontEndProgrammer(Programmer programmer) {
if (!isClient) {
frontEndProgrammer = programmer;
}
}
public void setProgrammer(Programmer programmer) {
if (isClient) {
this.programmer = programmer;
}
}
// 추가 된 메서드
public Language getFrontEndLanguage() {
return isClient ? language : frontEndLanguage;
}
public Library getFrontEndLibrary() {
return isClient ? library : null;
}
public Server getServer() {
return isClient ? null : server;
}
public Language getBackEndLanguage() {
return isClient ? null : backEndLanguage;
}
}
public class Director {
private Map<String, Paper> projects = new HashMap<>();
public void addProject(String name, Paper paper) {
projects.put(name, paper);
}
public void runProject(String name) {
if (!projects.containsKey(name)) {
throw new RuntimeException("no project");
}
Paper paper = projects.get(name);
if (paper instanceof ServerClient) {
ServerClient project = (ServerClient) paper;
Programmer frontEnd = new FrontEnd(), backEnd = new BackEnd();
project.setFrontEndProgrammer(frontEnd);
project.setBackEndProgrammer(backEnd);
Program client = frontEnd.makeProgram(project);
Program server = backEnd.makeProgram(project);
deploy(name, client, server);
} else if (paper instanceof Client) {
Client project = (Client) paper;
Programmer frontEnd = new FrontEnd();
project.setProgrammer(frontEnd);
deploy(name, frontEnd.makeProgram(project));
}
}
private void deploy(String projectName, Program... programs) {
}
}