SlideShare uma empresa Scribd logo
1 de 10
Chapter 8-2
데이터 체계화
- JuL-
마법 숫자를 기호 상수로 전환
(Replace Magic Number with Symbolic Constant)
• 마법 숫자는 특수한 값을 갖는 숫자를 일컫는 용어로 , 여러 곳에서 논리적으로 같은
숫자를 참조해야 할 경우가 많은데 , 수정해야 할 상황이 오면 끔찍한 일이 발생한다 .
• 즉 , 상수를 하드코딩하지 말자 .
class TestA{
public boolean isOverFlow(int curCount){
if(curCount > 10){
return true;
}
return false;
}
}
class TestB{
public int getMaxCount(){
return 10;
}
}
class TestA{
public boolean isOverFlow(int curCount){
if(curCount >
CommonConst.MAX_COUNT){
return true;
}
return false;
}
}
class TestB{
public int getMaxCount(){
return CommonConst.MAX_COUNT;
}
}
interface CommonConst{
public int MAX_COUNT = 10;
}
필드 캡슐화
(Encapsulate Field)
• 데이터는 절대로 public 으로 선언하면 안된다 . 반드시 private 형태에서 setter,
getter 를만들어 사용해야 한다 .
• 얼핏 생각하기엔 , publi 으로 하든 , setter, getter 를 만들든 외부에서 값을 변경할 수
있는 것은 매한가지 아닌가 라고 생각할 수 있지만 , 실제 코딩을 해보면 그렇지 않다
는 것을 느낄 수 있다 . 예를 들어 , 아래와 같은 사소한 실수를 미연에 방지할 수도 있
고 , 무엇보다 변수를 호출하거나 세팅할 때 일괄 처리해야 할 코드가 추가될 경우 해
당 변수의 setter, getter 를 수정하는 것만으로 대응할 수 있다 .
class MyObject{
public int mId = -1;
}
MyObject myObj = new MyObject();
myObj.mId = 2; // 빌드에러 없이 컴파일 된
후 엄청난 side effect 를 마주하게 됨 .
class MyObject{
private int mId = -1;
public int getId(){
return mId;
}
public void setId(int id){
mId = id;
}
}
MyObject myObj = new MyObject();
myObj.mId = 2; // 빌드 에러 발생
컬렉션 캡슐화
(Encapsulate Collection)
• 컬렉션 ( 배열 , 리스트 , 세트 , 벡터 ) 의 getter 는 객체 자체를 반환해서는 안된다 .
• Java 는 기본적으로 pass by value 지만 , object 를 pass 할 때는 object 의 reference 가
value 로써 passing 된 다는 것을 기억하자 .
• Thread safe 한 컬렉션 객체를 만들기에도 더 용이하다 .
public void foo(Dog d) {
d.getName().equals("Max"); // true
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
Dog aDog = new Dog("Max");
foo(aDog);
aDog.getName().equals("Max"); // true
public void foo(Dog d) {
d.getName().equals("Max"); // true
d.setName("Fifi");
}
Dog aDog = new Dog("Max");
foo(aDog);
aDog.getName().equals("Fifi"); // true
레코드를 데이터 클래스로 전환
(Replace Record with Data Class)
• 프로그래밍 환경에서 흔히 사용되는 레코드 구조를 덤 데이터 개체로
전환한다 .
• 덤 데이터란 , 데이터가 거의 들어 있지 않은 객체로 , 기능 추가 없이
데이터에 public 속성이나 읽기 / 쓰기 메서드로 접근할 수 있다 . 프로
그래머 입장에선 객체지향 프로그래밍 개념의 정통적 개념에 위배된
다 . 패턴 / 안티패턴의 사용은 캡슐화에 완전히 위배된다 .
분류 부호를 클래스로 전환
(ReplaceType Code with Class)
• 숫자형 분류번호를 별도의 클래스로 전환하면 코드가 상당히 이해하기
쉬워진다 .
• 책이 집필된 시점의 java version 엔 enum type 이 없어서인지 enum
type 같은 class 를 별도로 만들어서 설명하고 있다 . 참고만하고 그냥
enum type 을 쓰면 될듯 ?
public enum Blood {
O(1), A(2), B(3), AB(4);
private int value = 0;
Blood(int i) { value = i; }
public int getNumber() { return value; }
public static Blood get(int value) {
if (value == O.getNumber())
return O;
else if (value == A.getNumber())
return A;
else if (value == B.getNumber())
return B;
else if (value == AB.getNumber())
return AB;
return AB;
}
}
분류 부호를 하위클래스로 전환
(ReplaceType Code with SubClasses)
• 분류 부호가 클래스 기능에 영향을 줘서 클래스로 전환 기법을 사용할
수 없을 경우 재정의를 통해 조금씩 다른 기능을 처리하게 한다 .
• 이와 같이 이 기법은 다형성을 가능케하는
사전작업으로 시행할 때가 많다 .
public class Employee {
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN =
1;
static final int MANAGER = 2;
Employee (int type) {
_type = type;
}
}
public class Engineer extends Employee {
protected Engineer(int type) {
super(type);
}
@Override
public int get_type() {
return Engineer.ENGINEER;
}
}
public abstract class Employee {
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
protected Employee(int type) {
_type = type;
}
public static Employee createEmployee(int type) {
// if(type == ENGINEER) return new Engineer(type);
// else return new Employee(type);
switch (type) {
case ENGINEER:
return new Engineer(type);
case SALESMAN:
return new Manager(type);
case MANAGER:
return new Manager(type);
default:
throw new IllegalArgumentException(“Incorrect Type Code”);
}
}
abstract int get_type();
}
분류 부호를 상태 / 전략 패턴으로 전환
(ReplaceType Code with State/Strategy)
• 이 기법은 “분류 부호를 하위클래스로 전환"과 비슷하지만 , 분류 부호
가 객체 수명주기 동안 변할 때나 다른 이유로 하위클래스로 만들 수 없
을 때 사용한다 .
class Employee {
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
Employee (int type) {
_type = type;
}
int payAmount() {
switch (_type) {
case ENGINEER:
return _monthlySalary;
case SALESMAN:
return _monthlySalary + _commission;
case MANAGER:
return _monthlySalary + _bonus;
default:
throw new RuntimeException("Incorrect Employee");
}
}
분류 부호를 상태 / 전략 패턴으로 전환
(ReplaceType Code with State/Strategy)
class Engineer extends EmployeeType {
int getTypeCode () {
return Employee.ENGINEER;
}
}
class Manager extends EmployeeType {
int getTypeCode () {
return Employee.MANAGER;
}
}
class Salesman extends EmployeeType {
int getTypeCode () {
return Employee.SALESMAN;
}
}
class EmployeeType...
static EmployeeType newType(int code) {
switch (code) {
case ENGINEER:
return new Engineer();
case SALESMAN:
return new Salesman();
case MANAGER:
return new Manager();
default:
throw ..
}
}
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;
}
class Employee...
int getType() {
return _type.getTypeCode();
}
void setType(int arg) {
_type = EmployeeType.newType(arg);
}
int payAmount() {
switch (getType()) {
case EmployeeType.ENGINEER:
return _monthlySalary;
case EmployeeType.SALESMAN:
return _monthlySalary + _commission;
case EmployeeType.MANAGER:
return _monthlySalary + _bonus;
default:
throw new RuntimeException("Incorrect Employee");
}
}
하위클래스를 필드로 전환
(Replace Subclass with Fields)
• 단순히 상수 메서드만 존재하는 하위클래스는 상위클래스의 필드로 전
환하고 , 하위클래스는 완전히 삭제하면 된다 .
abstract class Person {
abstract boolean isMale();
abstract char getCode();
...
}
class Male extends Person {
boolean isMale() {
return true;
}
char getCode() {
return 'M';
}
}
class Female extends Person {
boolean isMale() {
return false;
}
char getCode() {
return 'F';
}
}
abstract class Person {
private final boolean _isMale;
private final char _code;
static Person createMale(){
return new Person(true, 'M');
}
static Person createFemale(){
return new Person(false, ‘F');
}
...
}

Mais conteúdo relacionado

Mais procurados

Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Circulus
 
자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개beom kyun choi
 
7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성HyeonSeok Choi
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Circulus
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple OverviewKim Hunmin
 
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitiveNAVER D2
 
[devil's camp] - 알고리즘 대회와 STL (박인서)
[devil's camp] - 알고리즘 대회와 STL (박인서)[devil's camp] - 알고리즘 대회와 STL (박인서)
[devil's camp] - 알고리즘 대회와 STL (박인서)NAVER D2
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409Yong Joon Moon
 
[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features SummaryChris Ohk
 
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...Young-Beom Rhee
 
프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oopYoung-Beom Rhee
 
씹고 뜯고 맛보고 즐기는 스트림 API
씹고 뜯고 맛보고 즐기는 스트림 API씹고 뜯고 맛보고 즐기는 스트림 API
씹고 뜯고 맛보고 즐기는 스트림 APIArawn Park
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리ETRIBE_STG
 

Mais procurados (20)

Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
 
자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개
 
7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple Overview
 
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
 
5 swift 기초함수
5 swift 기초함수5 swift 기초함수
5 swift 기초함수
 
[devil's camp] - 알고리즘 대회와 STL (박인서)
[devil's camp] - 알고리즘 대회와 STL (박인서)[devil's camp] - 알고리즘 대회와 STL (박인서)
[devil's camp] - 알고리즘 대회와 STL (박인서)
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
자바스크립트 클래스의 프로토타입(prototype of class)
자바스크립트 클래스의  프로토타입(prototype of class)자바스크립트 클래스의  프로토타입(prototype of class)
자바스크립트 클래스의 프로토타입(prototype of class)
 
파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
Java8 람다
Java8 람다Java8 람다
Java8 람다
 
Tdd 4장
Tdd 4장Tdd 4장
Tdd 4장
 
Just java
Just javaJust java
Just java
 
[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary[C++ Korea 2nd Seminar] C++17 Key Features Summary
[C++ Korea 2nd Seminar] C++17 Key Features Summary
 
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
 
프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop프론트엔드스터디 E05 js closure oop
프론트엔드스터디 E05 js closure oop
 
씹고 뜯고 맛보고 즐기는 스트림 API
씹고 뜯고 맛보고 즐기는 스트림 API씹고 뜯고 맛보고 즐기는 스트림 API
씹고 뜯고 맛보고 즐기는 스트림 API
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리
 

Destaque

이윤서의 자기소개
이윤서의 자기소개이윤서의 자기소개
이윤서의 자기소개kim inho
 
EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템
EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템
EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템Seokhwan Kim
 
[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용
[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용
[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용현호 김
 
20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사
20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사
20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사Taejoon Yoo
 
20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표
20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표
20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표Taejoon Yoo
 
자기소개Ppt 박은선입니다
자기소개Ppt 박은선입니다자기소개Ppt 박은선입니다
자기소개Ppt 박은선입니다EunSun Park
 
자기소개(SSS발표면접)
자기소개(SSS발표면접)자기소개(SSS발표면접)
자기소개(SSS발표면접)Youngbin Han
 
딥러닝을 이용한 자연어처리의 연구동향
딥러닝을 이용한 자연어처리의 연구동향딥러닝을 이용한 자연어처리의 연구동향
딥러닝을 이용한 자연어처리의 연구동향홍배 김
 
AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)
AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)
AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)Amazon Web Services Korea
 
Introduce Deep learning & A.I. Applications
Introduce Deep learning & A.I. ApplicationsIntroduce Deep learning & A.I. Applications
Introduce Deep learning & A.I. ApplicationsMario Cho
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016Taehoon Kim
 
자기소개서
자기소개서자기소개서
자기소개서summerkim
 
20112602윤병용+자기소개+프리젠테이션
20112602윤병용+자기소개+프리젠테이션20112602윤병용+자기소개+프리젠테이션
20112602윤병용+자기소개+프리젠테이션병용 병용
 
KTH 자기소개, 지훈 PD
KTH 자기소개, 지훈 PDKTH 자기소개, 지훈 PD
KTH 자기소개, 지훈 PDyamoo9
 
자기소개
자기소개자기소개
자기소개parkmunge
 
자기소개(기말과제)
자기소개(기말과제)자기소개(기말과제)
자기소개(기말과제)정원 허
 

Destaque (18)

이윤서의 자기소개
이윤서의 자기소개이윤서의 자기소개
이윤서의 자기소개
 
EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템
EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템
EPG 정보 검색을 위한 예제 기반 자연어 대화 시스템
 
Splunk 교육자료 v1.2
Splunk 교육자료 v1.2Splunk 교육자료 v1.2
Splunk 교육자료 v1.2
 
[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용
[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용
[Pycon 2015] 오늘 당장 딥러닝 실험하기 제출용
 
20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사
20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사
20160203_마인즈랩_딥러닝세미나_05 딥러닝 자연어처리와 분류엔진 황이규박사
 
20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표
20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표
20160203_마인즈랩_딥러닝세미나_03 the game changer 딥러닝 유태준대표
 
자기소개Ppt 박은선입니다
자기소개Ppt 박은선입니다자기소개Ppt 박은선입니다
자기소개Ppt 박은선입니다
 
자기소개(SSS발표면접)
자기소개(SSS발표면접)자기소개(SSS발표면접)
자기소개(SSS발표면접)
 
딥러닝을 이용한 자연어처리의 연구동향
딥러닝을 이용한 자연어처리의 연구동향딥러닝을 이용한 자연어처리의 연구동향
딥러닝을 이용한 자연어처리의 연구동향
 
AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)
AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)
AWS re:Invent 특집(3) – Amazon 인공 지능(AI) 서비스 및 AWS 딥러닝 프레임웍 활용 (윤석찬)
 
Introduce Deep learning & A.I. Applications
Introduce Deep learning & A.I. ApplicationsIntroduce Deep learning & A.I. Applications
Introduce Deep learning & A.I. Applications
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
 
자기소개
자기소개자기소개
자기소개
 
자기소개서
자기소개서자기소개서
자기소개서
 
20112602윤병용+자기소개+프리젠테이션
20112602윤병용+자기소개+프리젠테이션20112602윤병용+자기소개+프리젠테이션
20112602윤병용+자기소개+프리젠테이션
 
KTH 자기소개, 지훈 PD
KTH 자기소개, 지훈 PDKTH 자기소개, 지훈 PD
KTH 자기소개, 지훈 PD
 
자기소개
자기소개자기소개
자기소개
 
자기소개(기말과제)
자기소개(기말과제)자기소개(기말과제)
자기소개(기말과제)
 

Semelhante a Refactoring - Chapter 8.2

테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)Suwon Chae
 
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It종빈 오
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장tedypicker
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍Young-Beom Rhee
 
12장 상속 (고급)
12장 상속 (고급)12장 상속 (고급)
12장 상속 (고급)유석 남
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선daewon jeong
 
안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법mosaicnet
 
[2011 04 11]mock_object 소개
[2011 04 11]mock_object 소개[2011 04 11]mock_object 소개
[2011 04 11]mock_object 소개Jong Pil Won
 
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자Donghyeok Kang
 
Game Design patterns, Visitor, State, FSM pattern
Game Design patterns, Visitor, State, FSM patternGame Design patterns, Visitor, State, FSM pattern
Game Design patterns, Visitor, State, FSM patternYoung Ha Kim
 
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)JiandSon
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GDG Korea
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택JinTaek Seo
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initializationEunjoo Im
 
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원탑크리에듀(구로디지털단지역3번출구 2분거리)
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part oneJi Hun Kim
 
5장 객체와클래스
5장 객체와클래스5장 객체와클래스
5장 객체와클래스SeoYeong
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 

Semelhante a Refactoring - Chapter 8.2 (20)

테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
 
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
 
06장 함수
06장 함수06장 함수
06장 함수
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
 
12장 상속 (고급)
12장 상속 (고급)12장 상속 (고급)
12장 상속 (고급)
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선
 
안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법안드로이드 설계코드 노하우 및 개발방법
안드로이드 설계코드 노하우 및 개발방법
 
[2011 04 11]mock_object 소개
[2011 04 11]mock_object 소개[2011 04 11]mock_object 소개
[2011 04 11]mock_object 소개
 
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
Java Annotation과 MyBatis로 나만의 ORM Framework을 만들어보자
 
강의자료4
강의자료4강의자료4
강의자료4
 
Game Design patterns, Visitor, State, FSM pattern
Game Design patterns, Visitor, State, FSM patternGame Design patterns, Visitor, State, FSM pattern
Game Design patterns, Visitor, State, FSM pattern
 
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initialization
 
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
[IT기술칼럼#2] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원
 
읽기 좋은 코드가 좋은 코드다 Part one
읽기 좋은 코드가 좋은 코드다   Part one읽기 좋은 코드가 좋은 코드다   Part one
읽기 좋은 코드가 좋은 코드다 Part one
 
5장 객체와클래스
5장 객체와클래스5장 객체와클래스
5장 객체와클래스
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 

Refactoring - Chapter 8.2

  • 2. 마법 숫자를 기호 상수로 전환 (Replace Magic Number with Symbolic Constant) • 마법 숫자는 특수한 값을 갖는 숫자를 일컫는 용어로 , 여러 곳에서 논리적으로 같은 숫자를 참조해야 할 경우가 많은데 , 수정해야 할 상황이 오면 끔찍한 일이 발생한다 . • 즉 , 상수를 하드코딩하지 말자 . class TestA{ public boolean isOverFlow(int curCount){ if(curCount > 10){ return true; } return false; } } class TestB{ public int getMaxCount(){ return 10; } } class TestA{ public boolean isOverFlow(int curCount){ if(curCount > CommonConst.MAX_COUNT){ return true; } return false; } } class TestB{ public int getMaxCount(){ return CommonConst.MAX_COUNT; } } interface CommonConst{ public int MAX_COUNT = 10; }
  • 3. 필드 캡슐화 (Encapsulate Field) • 데이터는 절대로 public 으로 선언하면 안된다 . 반드시 private 형태에서 setter, getter 를만들어 사용해야 한다 . • 얼핏 생각하기엔 , publi 으로 하든 , setter, getter 를 만들든 외부에서 값을 변경할 수 있는 것은 매한가지 아닌가 라고 생각할 수 있지만 , 실제 코딩을 해보면 그렇지 않다 는 것을 느낄 수 있다 . 예를 들어 , 아래와 같은 사소한 실수를 미연에 방지할 수도 있 고 , 무엇보다 변수를 호출하거나 세팅할 때 일괄 처리해야 할 코드가 추가될 경우 해 당 변수의 setter, getter 를 수정하는 것만으로 대응할 수 있다 . class MyObject{ public int mId = -1; } MyObject myObj = new MyObject(); myObj.mId = 2; // 빌드에러 없이 컴파일 된 후 엄청난 side effect 를 마주하게 됨 . class MyObject{ private int mId = -1; public int getId(){ return mId; } public void setId(int id){ mId = id; } } MyObject myObj = new MyObject(); myObj.mId = 2; // 빌드 에러 발생
  • 4. 컬렉션 캡슐화 (Encapsulate Collection) • 컬렉션 ( 배열 , 리스트 , 세트 , 벡터 ) 의 getter 는 객체 자체를 반환해서는 안된다 . • Java 는 기본적으로 pass by value 지만 , object 를 pass 할 때는 object 의 reference 가 value 로써 passing 된 다는 것을 기억하자 . • Thread safe 한 컬렉션 객체를 만들기에도 더 용이하다 . public void foo(Dog d) { d.getName().equals("Max"); // true d = new Dog("Fifi"); d.getName().equals("Fifi"); // true } Dog aDog = new Dog("Max"); foo(aDog); aDog.getName().equals("Max"); // true public void foo(Dog d) { d.getName().equals("Max"); // true d.setName("Fifi"); } Dog aDog = new Dog("Max"); foo(aDog); aDog.getName().equals("Fifi"); // true
  • 5. 레코드를 데이터 클래스로 전환 (Replace Record with Data Class) • 프로그래밍 환경에서 흔히 사용되는 레코드 구조를 덤 데이터 개체로 전환한다 . • 덤 데이터란 , 데이터가 거의 들어 있지 않은 객체로 , 기능 추가 없이 데이터에 public 속성이나 읽기 / 쓰기 메서드로 접근할 수 있다 . 프로 그래머 입장에선 객체지향 프로그래밍 개념의 정통적 개념에 위배된 다 . 패턴 / 안티패턴의 사용은 캡슐화에 완전히 위배된다 .
  • 6. 분류 부호를 클래스로 전환 (ReplaceType Code with Class) • 숫자형 분류번호를 별도의 클래스로 전환하면 코드가 상당히 이해하기 쉬워진다 . • 책이 집필된 시점의 java version 엔 enum type 이 없어서인지 enum type 같은 class 를 별도로 만들어서 설명하고 있다 . 참고만하고 그냥 enum type 을 쓰면 될듯 ? public enum Blood { O(1), A(2), B(3), AB(4); private int value = 0; Blood(int i) { value = i; } public int getNumber() { return value; } public static Blood get(int value) { if (value == O.getNumber()) return O; else if (value == A.getNumber()) return A; else if (value == B.getNumber()) return B; else if (value == AB.getNumber()) return AB; return AB; } }
  • 7. 분류 부호를 하위클래스로 전환 (ReplaceType Code with SubClasses) • 분류 부호가 클래스 기능에 영향을 줘서 클래스로 전환 기법을 사용할 수 없을 경우 재정의를 통해 조금씩 다른 기능을 처리하게 한다 . • 이와 같이 이 기법은 다형성을 가능케하는 사전작업으로 시행할 때가 많다 . public class Employee { private int _type; static final int ENGINEER = 0; static final int SALESMAN = 1; static final int MANAGER = 2; Employee (int type) { _type = type; } } public class Engineer extends Employee { protected Engineer(int type) { super(type); } @Override public int get_type() { return Engineer.ENGINEER; } } public abstract class Employee { private int _type; static final int ENGINEER = 0; static final int SALESMAN = 1; static final int MANAGER = 2; protected Employee(int type) { _type = type; } public static Employee createEmployee(int type) { // if(type == ENGINEER) return new Engineer(type); // else return new Employee(type); switch (type) { case ENGINEER: return new Engineer(type); case SALESMAN: return new Manager(type); case MANAGER: return new Manager(type); default: throw new IllegalArgumentException(“Incorrect Type Code”); } } abstract int get_type(); }
  • 8. 분류 부호를 상태 / 전략 패턴으로 전환 (ReplaceType Code with State/Strategy) • 이 기법은 “분류 부호를 하위클래스로 전환"과 비슷하지만 , 분류 부호 가 객체 수명주기 동안 변할 때나 다른 이유로 하위클래스로 만들 수 없 을 때 사용한다 . class Employee { private int _type; static final int ENGINEER = 0; static final int SALESMAN = 1; static final int MANAGER = 2; Employee (int type) { _type = type; } int payAmount() { switch (_type) { case ENGINEER: return _monthlySalary; case SALESMAN: return _monthlySalary + _commission; case MANAGER: return _monthlySalary + _bonus; default: throw new RuntimeException("Incorrect Employee"); } }
  • 9. 분류 부호를 상태 / 전략 패턴으로 전환 (ReplaceType Code with State/Strategy) class Engineer extends EmployeeType { int getTypeCode () { return Employee.ENGINEER; } } class Manager extends EmployeeType { int getTypeCode () { return Employee.MANAGER; } } class Salesman extends EmployeeType { int getTypeCode () { return Employee.SALESMAN; } } class EmployeeType... static EmployeeType newType(int code) { switch (code) { case ENGINEER: return new Engineer(); case SALESMAN: return new Salesman(); case MANAGER: return new Manager(); default: throw .. } } static final int ENGINEER = 0; static final int SALESMAN = 1; static final int MANAGER = 2; } class Employee... int getType() { return _type.getTypeCode(); } void setType(int arg) { _type = EmployeeType.newType(arg); } int payAmount() { switch (getType()) { case EmployeeType.ENGINEER: return _monthlySalary; case EmployeeType.SALESMAN: return _monthlySalary + _commission; case EmployeeType.MANAGER: return _monthlySalary + _bonus; default: throw new RuntimeException("Incorrect Employee"); } }
  • 10. 하위클래스를 필드로 전환 (Replace Subclass with Fields) • 단순히 상수 메서드만 존재하는 하위클래스는 상위클래스의 필드로 전 환하고 , 하위클래스는 완전히 삭제하면 된다 . abstract class Person { abstract boolean isMale(); abstract char getCode(); ... } class Male extends Person { boolean isMale() { return true; } char getCode() { return 'M'; } } class Female extends Person { boolean isMale() { return false; } char getCode() { return 'F'; } } abstract class Person { private final boolean _isMale; private final char _code; static Person createMale(){ return new Person(true, 'M'); } static Person createFemale(){ return new Person(false, ‘F'); } ... }