종종 코드로 비슷한 것들을 만들어내야 할 때가 있습니다.
그럴 때 서브 클래스를 활용 할 수 있습니다.
이번에는 아래 코드를
function createEmployee(name, type) {
return new Employee(name,type);
}
아래 코드로 바꿉니다
function createEmployee(name, type) {
switch (type) {
case "engineer": return new Engineer(name);
case "salesman": return new Salesman(name);
case "manager": return new Manager(name);
}
}
위의 코드처럼 타입을 넣으면 되긴 합니다.
하지만 이렇게 서브 클래스를 사용하면 2가지 것이 가능합니다
첫번째는 조건문에서 다형성을 활용할 수 있게 됩니다 - Replace Conditional with Polymorphism
두번째는 서브 클래스로 만들어서 필드를 이동시킬 수 있습니다. - Push down fields 를 사용 할 수 있습니다.
수행 절차
type 코드 부분을 encapsulate 합니다.
type 코드에 대한 서브 클래스를 만듭니다.
조건문 로직을 만듭니다.
테스트
서브 클래스를 만드는 것을 반복하고 조건문에 추가합니다
type 코드를 지웁니다
테스트
push down fields 와 replace conditional with polymorphism 을 사용합니다.
코드를 통해서 더 살펴보겠습니다.
class Employee {
constructor(name, type) {
this.validateType()
...
}
}
class EmployeeType {
get capitlaizedName() {
....
}
}
class Engineer extends EmployeeType {
}
class Salesman extends EmployeeType {
}
class Manager extends EmployeeType {
}
EmployeeType 클래스를 만들고
서브 클래스들을 만듭니다.
그리고 호출하는 부분에서 아래 코드처럼 사용하면 됩니다.
function createEmployee(name, type) {
switch (type) {
case "engineer": return new Engineer(name);
case "salesman": return new Salesman(name);
case "manager": return new Manager(name);
}
}
Example. Using Indirect Inheritence
간접적인 상속과 함께 사용하기
첫번째 경우로 돌아가서 이번에는 파트타임과 풀타임 직원에 대한 서브 클래스를 가지고 있다고 가정한다.
이번에는 Employee 의 서브 클래스를 낼 수 없다.
그리고 이렇게 하는 또 다른 이유는 Employee의 type을 바꿀 수 있는 가능성을 남겨두기 위함이다.
class Employee {
constructor(name, type) {...}
validateType(arg) {
...
}
get type() { return this._type }
get type(arg) { this._type = arg; }
get capitalizedType() {
return this._type ....
}
toString() {
....
}
}
이번에는 먼저 Replace Primitive with Object 를 사용한다.
class EmployeeType {
constructor(aString) {
...
}
toString() { ... }
}
class Employee {
constructor(name, type) {...}
validateType(arg) {
...
}
get typeString() { return this._type }
get type(arg) { this._type = arg; }
get capitalizedType() {
return this.typeString.charAt(0).toUpperCase() + this._typeString.subStr...;
}
toString() {
return this._type.toString();
}
}
capitalized 타입 등에서 참조해서 접근하도록 변경한다.
그리고 replace type code with subclasses 를 적용한다.
class Employee {
...
set type(arg) { this._type = Employee.createEmployeeType(arg); }
static createEmployeeType(aString) {
switch (aString) {
case "engineer": return new Engineer();
case "manager": return new Manager();
case "salesman": return new Salesman();
default: throw new Error();
}
}
...
}
class EmployeeType {
}
class Engineer extends EmployeeType {
}
class Salesman extends EmployeeType {
}
class Manager extends EmployeeType {
}
비어있는 EmployeeType 이 있는데 이건 그대로 둔다.
코드 자체의 설명을 돕는다.
그리고 EmployeeType 안에 로직을 추가하면 전체 서브클래스에 추가 할 수 있는 좋은 부분도 된다.
class EmployeeType {
get capitlaizedName() {
....
}
}
class Engineer extends EmployeeType {
}
class Salesman extends EmployeeType {
}
class Manager extends EmployeeType {
}
'JavaScript│Node js' 카테고리의 다른 글
Javascript/Typescript 스택, 큐, 힙, 정렬 (0) | 2020.02.26 |
---|---|
Nestjs 사용하고 느낀점 (2) | 2020.01.10 |
Nestjs 외부 모듈에 정의된 타입 사용하기 (0) | 2020.01.09 |
마틴 파울러 리팩토링 Push down field (0) | 2020.01.03 |
마틴 파울러 리팩토링 Replace Query with Parameter (0) | 2020.01.02 |
댓글