개요
클래스는 대다수 언어가 제공하는 기본적인 빌딩 블록
클래스는 데이터와 함수를 하나의 공유 환경으로 묶어 그중 일부를 외부에 제공한다.
함수 호출 시 인수로 전달되는 공통 데이터를 중심으로 작동하는 함수들을 클래스 하나로 묶는다.
클래스로 묶으면 함수들 간 공통 환경을 명확히 표현할 수 있다.
클래스로 묶을 때 장점은 클라이언트가 객체의 핵심 데이터를 변경할 수 있고, 파생 객체들을 일관되게 관리할 수 있다.
함수들을 중첩함수로 묶는도 되지만, 클래스를 지원하는 언어라면 클래스로 묶는다.
만약 클래스를 지원하지 않는 언어라는 '함수를 객체처럼 패턴' 사용을 고려한다.
//함수를 객체처럼 function Cat(name){ return { name : name, getName : function(){return name;}, setName : function(arg){name=arg}, sound : function(){sound(name);} }; function sound(name){console.log(name + " 냐아아아옹");} } var cat = Cat('나비'); cat.sound(); cat.setName('배추나비'); cat.sound(); /// 나비 냐아아아옹 배추나비 냐아아아옹 |
예시
마시는 차를 정부에서 수돗물처럼 제공한다고 가정, 차 계량기를 읽어서 측정값을 기록 계산하는 코드
//측정값 let reading={customer : "ivan", quantity:10, month:5, uear:2017}; //클라이언트1 const aReading = acquireReading(); const baseCharge = baseRate(aReading.month, aReading.year) * aReading.quantity; //클라이언트2 const aReading2 = acquireReading(); const baseCharge2 = baseRate(aReading2.month, aReading2.year) * aReading2.quantity; const taxableCharge2 = Math.max(0,base-taxTreshold(aReading2.year)); //클라이언트3 const aReading3 = acquireReading(); const basicChargeAmount3 = calculateBaseCharge(aReading3); function calculateBaseCharge(aReading){ return baseRate(aReading.month, aReading.year); } |
//레코드를 클래스로 캡슐화 class Reading{ constructor(data){ this._customer = data.customer; this._quantity = data.quantity; this._month = data.month; this._year = data.year; } get customer(){return this._customer;} get quantity(){return this._quantity;} get month(){return this._month;} get year(){return this._year;} } |
//클라이언트3 const rawReading = acquireReading(); const aReading3 = new Reading(rawReading); const basicChargeAmount = aReading3.calculateBaseCharge; //레코드를 클래스로 캡슐화 class Reading{ constructor(data){ this._customer = data.customer; this._quantity = data.quantity; this._month = data.month; this._year = data.year; } get customer(){return this._customer;} get quantity(){return this._quantity;} get month(){return this._month;} get year(){return this._year;} //함수 옮김 get calculateBaseCharge(){ return baseRate(this.month, this.year); } } |
const rawReading = acquireReading(); const aReading3 = new Reading(rawReading); const basicChargeAmount = aReading3.baseCharge; class Reading{ constructor(data){ this._customer = data.customer; this._quantity = data.quantity; this._month = data.month; this._year = data.year; } get customer(){return this._customer;} get quantity(){return this._quantity;} get month(){return this._month;} get year(){return this._year;} //알맞은 이름 짓기 get baseCharge(){ return baseRate(this.month, this.year); } } |
//클라이언트1 const rawReading = acquireReading(); const aReading = new Reading(rawReading); const baseCharge = aReading.baseRate; //클라이언트2 const rawReading2 = acquireReading(); const aReading2 = new Reading(rawReading); const taxableCharge2 = Math.max(0,aReading2.baseRate-taxTreshold(aReading2.year)); //클라이언트는 aReading.baseRate 이렇게 호출한다. 이게 필드인지 함수호출로 계산된 값인지 구분할 수없다. 이를 단일 접근 원칙이라 한다. |
//클라이언트2 const rawReading2 = acquireReading(); const aReading2 = new Reading(rawReading); const taxableCharge2 = taxableChargeFn() ; //함수로 추출 function taxableChargeFn() { return Math.max(0, aReading2.baseRate - taxTreshold(aReading2.year)); } |
//측정값 let reading={customer : "ivan", quantity:10, month:5, uear:2017}; //클라이언트1 const rawReading = acquireReading(); const aReading = new Reading(rawReading); const baseCharge = aReading.baseRate; //클라이언트2 const rawReading2 = acquireReading(); const aReading2 = new Reading(rawReading); const taxableCharge2 = aReading2.taxableCharge; //클라이언트3 const rawReading3 = acquireReading(); const aReading3 = new Reading(rawReading3); const basicChargeAmount = aReading3.baseCharge; class Reading{ constructor(data){ this._customer = data.customer; this._quantity = data.quantity; this._month = data.month; this._year = data.year; } get customer(){return this._customer;} get quantity(){return this._quantity;} get month(){return this._month;} get year(){return this._year;} get baseCharge(){ return baseRate(this.month, this.year); } get taxableCharge() { return Math.max(0, this.baseRate - taxTreshold(aReading2.year)); } } |
'IT책, 강의 > 리팩터링' 카테고리의 다른 글
06 - 기본적인 리펙터링 - 단계 쪼개기 (0) | 2023.07.24 |
---|---|
06 - 기본적인 리펙터링 - 여러 함수를 변환 함수로 묶기 (0) | 2023.07.23 |
06 - 기본적인 리펙터링 - 변수 이름 바꾸기 (0) | 2023.07.21 |
06 - 기본적인 리펙터링 - 매개변수 객체 만들기 (0) | 2023.07.20 |
06 - 기본적인 리펙터링 - 변수 캡슐화하기 (0) | 2023.07.19 |