[노트 재 구성 03] 대상 간 이전 특성

28162 단어 대상
머리말
대상 을 대상 으로 설계 하 는 과정 에서 '책임 을 거기에 두 기로 결정 했다' 는 것 은 가장 중요 한 일이 아니 더 라 도 가장 중요 한 일 중 하나 이다.이 사상 은 사실 유형 에 대해 비교적 중요 하 다. js 에서 함수 가 어떤 직책 을 완성 해 야 하 는 지, 그리고 함수 가 자신의 일 을 하지 말고 다른 함수 의 일 을 해 야 한다.
js 에서 흔히 한 가지 유형 만 있 습 니 다. 대상 을 대상 으로 하 는 사상 은 사실 어렵 습 니 다. 일정한 공력 이 없 으 면 잘 활용 하지 못 합 니 다. 저도 많은 js 를 배우 고 있 습 니 다. 사실은 한 가지 유형 만 있 습 니 다. 하나의 플러그 인 은 하나의 유형 입 니 다. 그리고 이런 유형 은 가짜 입 니 다. 계승, 봉 장 된 신 마 는 이해 하기 가 쉽 지 않 기 때문에 길이 아직 멀 습 니 다!
이전 함수
우리 프로그램 에 함수 가 있 으 면 주 류 의 다른 클래스 와 더 많은 교류 (후 자 를 호출 하거나 후자 에 의 해 호출) 가 있 으 면 이 함수 가 가장 자주 인용 하 는 클래스 에서 유사 한 행 위 를 가 진 새로운 함 수 를 만 들 고 오 랜 함 수 를 단순 한 위탁 함수 로 만 들 거나 기 존 함 수 를 제거 합 니 다.
이전 함 수 는 이론 을 재 구성 하 는 버팀목 이다. 만약 에 한 종류 가 너무 많은 행 위 를 하거나 다른 종류 와 너무 많은 합작 을 하여 고도 로 결합 하면 우 리 는 이전 함수 PS 가 필요 하 다. 사실은 한 페이지 응용 에서 MVC 의 구 조 는 이런 상황 을 발견 할 수 있다. 뒤에 우리 가 코드 를 만들어 서 보 자.
우리 프로그램 에는 이러한 함수 가 있 습 니 다. 다른 대상 을 사용 하 는 횟수 가 자신의 횟수 보다 많 습 니 다. 이사 할 때 이것 이 함수 귀속 의 중요 한 근거 입 니 다.
예 를 들 어 '계좌' 를 나타 내 는 Account 류 를 이용 하여 설명 합 니 다.
 1 var AccountType = function () {};
 2 AccountType.prototype = {
 3     isPremium: function () { return true; }
 4 };
 5 var Account = function () {
 6     this._type = new AccountType();
 7     this._daysOverdran;
 8 };
 9 Account.prototype = {
10     overdraftCharge: function () {
11         if (this._type.isPremium()) {
12             var result = 10;
13             if (this._daysOverdran > 7) result += (this._daysOverdrawn - 7) * 0.85;
14             return result;
15         } else {
16             return this._daysOverdran * 1.75;
17         }
18     },
19     bankCharge: function () {
20         var result = 4.5;
21         if (this._daysOverdran > 0) result += this.overdraftCharge();
22         return result;
23     }
24 };

이 프로그램 에 몇 가지 새로운 계 좌 를 가입 하면 각각 자신의 '당좌대월 금액 계산 규칙' 이 있 기 때문에 overdraft Charge 는 Account Type 으로 이전 해 야 할 수도 있 습 니 다.
어떻게
우선, 우 리 는 overdraft Charge 가 사용 하 는 모든 특성 을 관찰 하고 그 특성 들 이 그 와 함께 이사 할 수 있 는 지 를 고려 해 야 한다.
이 프로그램 에서dayOverdrawn 은 남 습 니 다. 이 값 은 계 정 에 따라 달라 지기 때문에 조 정 된 코드 는 다음 과 같 습 니 다.
 1 var AccountType = function () {};
 2 AccountType.prototype = {
 3     isPremium: function () { return true; },
 4     overdraftCharge: function (account) {
 5         if (this.isPremium()) {
 6             var result = 10;
 7             if (account.getDaysOverdran() > 7) result += (account.getDaysOverdran() - 7) * 0.85;
 8             return result;
 9         } else {
10             return account.getDaysOverdran() * 1.75;
11         }
12     }
13 };
14 var Account = function () {
15     this._type = new AccountType();
16     this._daysOverdran;
17 };
18 Account.prototype = {
19     bankCharge: function () {
20         var result = 4.5;
21         if (this._daysOverdran > 0) result += this._type.overdraftCharge(this);
22         return result;
23     }
24 };

여기에 도 days Overdrawn 을 매개 변수 로 전송 할 수 있 습 니 다. 하지만 뒤에 여러 필드 가 들 어 오 면 코드 를 바 꿔 야 하기 때문에 대상 에 게 직접 전달 하 세 요.
필드 이동
이전 필드 는 재 js 프로그램 에서 더 많이 사용 할 수 있 습 니 다. 우리 프로그램 에서 어떤 필드 가 자신의 클래스 이외 의 클래스 에 여러 번 사용 되면
대상 클래스 에 필드 를 새로 만 들 고 원본 필드 의 모든 사용 자 를 수정 하여 새 필드 를 사용 하도록 합 니 다.
왜 그 랬 어 요?
유형 간 이동 상태 와 행 위 는 재 구성 과정 에서 없어 서 는 안 될 조치 이다. 시스템 이 발전 함 에 따라 우 리 는 자신 이 새로운 유형 이 필요 하고 기 존의 업무 책임 을 새로운 유형 으로 이동 해 야 한 다 는 것 을 알 게 될 것 이다.
그러나 이번 주 는 합 리 적 이 고 정확 한 디자인 결정 으로 보 였 고 다음 주 에 틀 릴 수도 있 는 상황 도 아니 었 다.
만약 우리 가 한 필드 가 다른 종류 에 지나치게 많이 사용 되 는 것 을 발견 한다 면, 우 리 는 그 를 버 려 야 한다.
범례
우리 위의 예 를 들 어 봅 시다.
1 var Account = function () {
2     this._type = new AccountType();
3     this._interestRate;
4 };
5 Account.prototype = {
6     interestForAmount_days: function (amount, days) {
7         return this._interestRate * amount * days / 365;
8     }
9 };

우 리 는 지금 금 리 를 표시 하 는interestRate 를 Account Type 류 로 옮 겼 습 니 다. 현재 몇 가지 함수 가 그 를 인용 하고 있 습 니 다. interest ForAmountdays 는 그 중의 하나 입 니 다.
그래서 저 희 는 지금 Account Type 에interestRate 필드 와 해당 함수, 다음은 재 구성 코드 입 니 다.
 1 var AccountType = function () {
 2     this._interestRate;
 3 };
 4 AccountType.prototype = {
 5     getInterestRate: function () {
 6         return this._interestRate;
 7     }
 8 };
 9 var Account = function () {
10     this._type = new AccountType();
11 };
12 Account.prototype = {
13     interestForAmount_days: function (amount, days) {
14         return this.type.getInterestRate() * amount * days / 365;
15     }
16 };

추출 류
어떤 종 류 는 두 가지 유형 으로 해 야 할 일 을 했 습 니 다. 그러면 하나의 종 류 를 새로 만 들 고 관련 필드 와 함 수 를 옮 깁 니 다.
PS: 우 리 는 처음부터 지금까지 알 고 있 습 니 다. 재 구축 의 큰 수단 은 임시 변 수 를 없 애 는 것 이 고 다른 방법 은 직책 분리 입 니 다.
우 리 는 이 말 을 자주 듣는다. 하 나 는 추상 적 이 고 명확 한 책임 을 처리 해 야 하지만 실제 업무 에서 유형 은 계속 확 대 될 것 이다.
우 리 는 여기에 약간의 기능 을 추가 한 후에 거기에 데 이 터 를 추가 하여 특정한 유형 에 새로운 임 무 를 추가 할 때, 너 는 이 책임 을 위해 단독 적 인 유형 을 분리 할 가치 가 없다 고 느 낄 것 이다.
그래서 책임 이 계속 증가 하고 이런 유형 은 결국 점점 복잡 해 질 것 이다. 곧 이런 유형 은 자신 도 읽 고 싶 지 않 을 것 이다.
이런 종 류 는 왕왕 대량의 함수 와 데이터 가 있 기 때문에 이해 하기 어렵다. 이때 우 리 는 어느 부분 을 분리 해 야 하 는 지 를 고려 하고 그것들 을 하나의 단독 종류 에 써 야 한다
만약 이 데이터 들 이 어떤 함수 와 항상 함께 나타 나 고, 어떤 데 이 터 는 항상 동시에 변화 한다 면, 분리 합 시다.
PS: 이렇게 많은 말 을 했 는데 도 아직 비어 있 습 니 다. 코드 를 주세요.
 1 var Person = function () {
 2     this._name;
 3     this._officeAreaCode;
 4     this._officeNumber;
 5 };
 6 Person.prototype = {
 7     getName: function () { return this._name; },
 8     getTel: function () {
 9         return '(' + this._officeAreaCode + ')' + this._officeNumberl;
10     },
11     getOfficeAreaCode: function () {
12         return this._officeAreaCode;
13     },
14     setOfficeAreaCode: function (arg) {
15         this._officeAreaCode = arg;
16     },
17     getOfficeNumber: function () {
18         return this._officeNumber;
19     },
20     setOfficeNumber: function (arg) {
21         this._officeNumber = arg;
22     }
23 };

여기 서 우 리 는 전화번호 와 관련 된 행 위 를 하나의 독립 된 유형 으로 분리 하여 최 적 화 된 코드 를 만 들 수 있다.
 1 var Tel = function () {
 2     this._number;
 3     this._areaCode;
 4 };
 5 Tel.prototype = {
 6     getAreaCode: function () {
 7         return this._areaCode;
 8     },
 9     setAreaCode: function (arg) {
10         this._areaCode = arg;
11     },
12     getNumber: function () {
13         return this._number;
14     },
15     setNumber: function (arg) {
16         this._number = arg;
17     }
18 };
19 var Person = function () {
20     this._name;
21     this.tel = new Tel();
22 };
23 Person.prototype = {
24     getName: function () { return this._name; },
25     getTel: function () {
26         return '(' + this.tel.getAreaCode() + ')' + this.tel.getNumber();
27     }
28 };

생각해 보면 Person 은 물론 Tel 이라는 속성 뿐만 아니 라 Tel 도 다른 동작 이 있 을 수 있 습 니 다. 같이 쓰 면 뒤의 코드 가 팽창 하 는 것 을 예견 할 수 있 습 니 다.
클래스 내 연 화 를 하 다
만약 어떤 종류 가 아무것도 하지 않 았 다 면, 종 류 를 없 애고, 그 가 완성 한 특성 을 다른 종류 로 이동 시 키 는 방법 은 추출 류 와 완전히 상반 된다.
범례 는 위의 코드 를 다시 쓰 는 것 이다.
의뢰 관계 숨 기기
고객 은 하나의 의뢰 를 통 해 다른 대상 을 호출 하고 서버 에 고객 의 모든 함 수 를 만들어 의뢰 관 계 를 숨 깁 니 다.
'포장' 은 대상 의 가장 관건 적 인 특징 이 아니 더 라 도 가장 관건 적 인 특징 중 하나 이다.
포장 은 모든 대상 이 가능 한 한 시스템 의 다른 부분 을 적 게 알 아야 한 다 는 것 을 의미한다. 그러면 다른 곳 이 변 하면 나 에 게 상관 하지 않 는 다 (변 화 는 비교적 쉽게 진행 된다)
범례
본 사례 에서 사람들 은 한 부서 의 유형 이 더 많아 졌 다 고 생각 했다.
 1 var Department = function (manager) {
 2     this._chargeCode;
 3     this._manager = manager;
 4 };
 5 Department.prototype = {
 6     getManager: function () {
 7         return this._manager;
 8     }
 9 };
10 var Person = function () {
11     this._department;
12 };
13 Person.prototype = {
14     getDepartment: function () {
15         return this._department;
16     }
17 };

만약 고객 이 누군가의 사장 이 누구 인지 알 고 싶다 면, 그 는 반드시 먼저 Department 대상 을 얻어 야 한다.
manager = p.getDepartment().getManager()

이러한 문 제 는 사용자 에 게 Department 의 업무 원 리 를 밝 혀 고객 이 Department 를 통 해 매니저 정 보 를 추적 할 수 있 도록 지정 하고 Department 를 숨 길 수 있다 면 결합 을 줄 일 수 있다 는 것 이다.
여기 의뢰 가 하나 있 습 니 다.
 1 var Department = function (manager) {
 2     this._chargeCode;
 3     this._manager = manager;
 4 };
 5 Department.prototype = {
 6     getManager: function () {
 7         return this._manager;
 8     }
 9 };
10 var Person = function () {
11     this._department;
12 };
13 Person.prototype = {
14     getDepartment: function () {
15         return this._department;
16     },
17     getManager: function () {
18         return this._department.getManager();
19     }
20 };

이렇게 되면 사용 자 는 Department 라 는 물건 이 있 는 지 모른다.
중개인 을 제거 하 다
어떤 종 류 는 간단 한 위탁 동작 을 너무 많이 했 으 니 사용자 간 에 위탁 류 를 호출 하 게 하 세 요.
이것 은 위의 것 과 반대로 되 어 있 으 니 여러분 대조 해 보 세 요.
추가 함수 도입
우 리 는 때때로 서 비 스 를 제공 하 는 클래스 에 함 수 를 추가 해 야 하지만, 우 리 는 이 클래스 를 수정 할 수 없습니다. 그러면 클 라 이언 트 클래스 에 함 수 를 만 들 고, 첫 번 째 매개 변수 형식 으로 서버 클래스 인 스 턴 스 를 전송 합 니 다.
1 var d = new Date(previousEnd.getYear(), previousEnd.getMonth(), previousEnd.getDay() + 1);
2 
3 var d = nextDay(previousEnd);
4 function nextDay(arg) {
5     return new Date(arg.getYear(), arg.getMonth(), arg.getDay() + 1);
6 }

이런 일이 많이 발생 했 습 니 다. 우 리 는 한 가지 유형 을 사용 하고 있 습 니 다. 그 는 많은 서 비 스 를 제공 하고 있 습 니 다. 그러나 우 리 는 갑자기 새로운 유형 이 필요 합 니 다. 이런 유형 은 제공 할 수 없습니다. 그러면 우 리 는 악담 을 하고 소스 코드 를 수정 할 수 있 습 니 다.
만약 원본 코드 를 수정 할 수 없다 면, 우 리 는 클 라 이언 트 에서 함 수 를 보충 해 야 한다.
로 컬 확장 도입
서비스 클래스 에 추가 함 수 를 제공 해 야 하지만, 이 클래스 를 수정 할 수 없습니다. 이 추가 함 수 를 포함 하여 원본 클래스 나 포장 클래스 로 확장 할 수 있 도록 새로운 클래스 를 만 듭 니 다.
이것 은 위 와 비슷 합 니 다. 작은 것 은 신도 용왕 을 보 러 가 야 합 니 다. 그 러 니 잠시 여기 로 오 세 요.

좋은 웹페이지 즐겨찾기