* 분류 코드를 하위 클래스로 치환 (Replace Type Code With Subclass)
- 분류코드마다 하위 클래스를 준비해서 하위 클래스 내부에 동작을 서술하면 코드를 깔끔하게 정리할 수 있습니다.
이게 바로 여기서 배우는 분류 코드를 하위 클래스로 치환 리팩토링임.
- 분류코드 마다 다른 동작을 한다면 switch문을 사용하고 싶어짐. 하지만 객체지향 프로그래밍이라면 switch문은 악취가 남.
- 분류 코드를 하위 클래스로 치환 리팩토링은 하위 클래스라는 '구조'를 새로 만들거나, switch문 하나에 모여 있던 '동작'을
하위 클래스로 배분하게 됨.
* 리팩토링 전 코드
package ReplaceTypeCodeWithSubclasses;
public class Shape {
public static final int TYPECODE_LINE = 0;
public static final int TYPECODE_RECTANGLE = 1;
public static final int TYPECODE_OVAL = 2;
private final int _typecode;
private final int _startx;
private final int _starty;
private final int _endx;
private final int _endy;
protected Shape(int typecode, int startx, int starty, int endx, int endy) {
_typecode = typecode;
_startx = startx;
_endx = endx;
_starty = starty;
_endy = endy;
}
public int getTypeCode() {
return _typecode;
}
public String getName() {
switch(_typecode) {
case TYPECODE_LINE:
return "LINE";
case TYPECODE_RECTANGLE:
return "RECTANGLE";
case TYPECODE_OVAL:
return "OVAL";
default:
return null;
}
}
public String toString() {
return "[ "
+ getName() + ", "
+ "(" + _startx + ", " + _starty + ")-"
+ "(" + _endx + ", " + _endy + ") ]";
}
public void draw() {
switch(_typecode) {
case TYPECODE_LINE:
drawLine();
break;
case TYPECODE_RECTANGLE:
drawRectangle();
break;
case TYPECODE_OVAL:
drawOval();
break;
default:
;
}
}
private void drawLine() {
System.out.println("drawLine: " + this.toString());
}
private void drawRectangle() {
System.out.println("drawRectangle: " + this.toString());
}
private void drawOval() {
System.out.println("drawOval: " + this.toString());
}
}
package ReplaceTypeCodeWithSubclasses;
public class Main {
public static void main(String[] args) {
Shape line = new Shape(Shape.TYPECODE_LINE, 0, 0, 100, 200);
Shape rectangle = new Shape(Shape.TYPECODE_RECTANGLE, 10, 20, 30, 40);
Shape oval = new Shape(Shape.TYPECODE_OVAL, 100, 200, 300, 400);
Shape[] shape = {
line, rectangle, oval
};
for (Shape s : shape) {
s.draw();
}
}
}
* 리팩토링 후 코드
package ReplaceTypeCodeWithSubclasses;
public class Main {
public static void main(String[] args) {
Shape line = Shape.createShape(Shape.TYPECODE_LINE, 0, 0, 100, 200);
Shape rectangle = Shape.createShape(Shape.TYPECODE_RECTANGLE, 10, 20, 30, 40);
Shape oval = Shape.createShape(Shape.TYPECODE_OVAL, 100, 200, 300, 400);
Shape[] shape = {
line, rectangle, oval
};
for (Shape s : shape) {
s.draw();
}
}
}
package ReplaceTypeCodeWithSubclasses;
public abstract class Shape {
public static final int TYPECODE_LINE = 0;
public static final int TYPECODE_RECTANGLE = 1;
public static final int TYPECODE_OVAL = 2;
// private final int _typecode;
private final int _startx;
private final int _starty;
private final int _endx;
private final int _endy;
public static Shape createShape(int typecode, int startx, int starty, int endx, int endy) {
switch(typecode) {
case TYPECODE_LINE:
return new ShapeLine(startx, starty, endx, endy);
case TYPECODE_RECTANGLE:
return new ShapeRectangle(startx, starty, endx, endy);
case TYPECODE_OVAL:
return new ShapeOval(startx, starty, endx, endy);
default:
throw new IllegalArgumentException("typecode =" + typecode);
}
}
protected Shape(/*int typecode, */int startx, int starty, int endx, int endy) {
// _typecode = typecode;
_startx = startx;
_endx = endx;
_starty = starty;
_endy = endy;
}
// public int getTypeCode() {
// return _typecode;
// }
public abstract int getTypecode();
public abstract String getName();
// public String getName() {
// switch(_typecode) {
// case TYPECODE_LINE:
// return "LINE";
// case TYPECODE_RECTANGLE:
// return "RECTANGLE";
// case TYPECODE_OVAL:
// return "OVAL";
// default:
// return null;
// }
// }
public String toString() {
return "[ "
+ getName() + ", "
+ "(" + _startx + ", " + _starty + ")-"
+ "(" + _endx + ", " + _endy + ") ]";
}
public abstract void draw();
// public void draw() {
// switch(_typecode) {
// case TYPECODE_LINE:
// drawLine();
// break;
// case TYPECODE_RECTANGLE:
// drawRectangle();
// break;
// case TYPECODE_OVAL:
// drawOval();
// break;
// default:
// ;
// }
// }
// private void drawLine() {
// System.out.println("drawLine: " + this.toString());
// }
//
// private void drawRectangle() {
// System.out.println("drawRectangle: " + this.toString());
// }
//
// private void drawOval() {
// System.out.println("drawOval: " + this.toString());
// }
}
package ReplaceTypeCodeWithSubclasses;
public class ShapeLine extends Shape {
protected ShapeLine(int startx, int starty, int endx, int endy) {
super(startx, starty, endx, endy);
// TODO Auto-generated constructor stub
}
@Override
public int getTypecode() {
// TODO Auto-generated method stub
return Shape.TYPECODE_LINE;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return "LINE";
}
@Override
public void draw() {
// TODO Auto-generated method stub
drawLine();
}
private void drawLine() {
System.out.println("drawLine: " + this.toString());
}
}
package ReplaceTypeCodeWithSubclasses;
public class ShapeOval extends Shape {
protected ShapeOval(int startx, int starty, int endx, int endy) {
super(startx, starty, endx, endy);
// TODO Auto-generated constructor stub
}
@Override
public int getTypecode() {
// TODO Auto-generated method stub
return Shape.TYPECODE_OVAL;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return "OVAL";
}
@Override
public void draw() {
// TODO Auto-generated method stub
drawOval();
}
private void drawOval() {
System.out.println("drawOval: " + this.toString());
}
}
package ReplaceTypeCodeWithSubclasses;
public class ShapeRectangle extends Shape {
protected ShapeRectangle(int startx, int starty, int endx, int endy) {
super(startx, starty, endx, endy);
// TODO Auto-generated constructor stub
}
@Override
public int getTypecode() {
// TODO Auto-generated method stub
return Shape.TYPECODE_RECTANGLE;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return "RECTANGLE";
}
@Override
public void draw() {
// TODO Auto-generated method stub
drawRectangle();
}
private void drawRectangle() {
System.out.println("drawRectangle: " + this.toString());
}
}
에러 코드를 예외로 전환( Replace Error Code with Exception ) (0) | 2020.02.09 |
---|---|
분류 코드를 상태/전략 패턴으로 치환 (0) | 2020.02.08 |
분류 코드를 클래스로 치환( Replace Type Code with Class) 리팩토링 (0) | 2020.01.28 |
클래스 추출(Extract Class) 리팩토링 (0) | 2020.01.28 |
메서드 추출(Extract Method) 리팩토링 (0) | 2020.01.20 |
댓글 영역