>웹 프론트엔드 >JS 튜토리얼 >자바스크립트 디자인 패턴 추천_자바스크립트 기술에 대한 간략한 토론

자바스크립트 디자인 패턴 추천_자바스크립트 기술에 대한 간략한 토론

WBOY
WBOY원래의
2016-05-16 18:43:171057검색

제가 아까 "자바스크립트 디자인 패턴"을 여러분과 공유하고 싶다고 말한 기억이 납니다. 제가 아직 글을 쓰지 못한 이유는 제가 최근 일과 여행으로 너무 바빠서가 아닙니다. (오?) 요즘 드디어 빈말을 잘 할 시간이 됐네요.
디자인 패턴을 논의하기 전에 이미 스크립트 프로그래밍에 대한 기초가 있는지 확인하시기 바랍니다. 이에 대해 잘 모른다면 제가 오래 전에 쓴 "A"라는 글을 확인해 보시기 바랍니다. JavaScript 객체지향 프로그래밍에 대한 간략한 이야기'를 참조하세요. 다음 기사를 읽어보세요. .
디자인 패턴에 관해서라면 먼저 '인터페이스 디자인'에 집중해야 합니다. 인터페이스 디자인은 패턴 자체보다 디자인 패턴에 있어서 매우 중요한 의미를 갖기 때문입니다. 직관을 위해 먼저 인터페이스 정의의 형식을 소개하겠습니다.

코드 복사 코드는 다음과 같습니다. 🎜>
var 인터페이스 = new Interface("interface",[["getName",1],["getAge",1]])

볼 수 있습니다. 인터페이스 함수에는 두 개의 매개변수, 즉 인터페이스 메소드가 2차원 배열로 정의되어 있어야 합니다. 위의 예에서는 getName과 getAge라는 두 가지 인터페이스 메소드가 정의되어 있습니다. 두 메소드 모두 인터페이스에 대한 이해를 돕기 위해 인터페이스 함수의 구현 코드를 자세히 살펴보겠습니다.

코드 복사 코드는 다음과 같습니다.
함수 인터페이스(이름,메서드){
if (arguments.length !=2){
console.log("매개변수는 2개여야 합니다.")
}
this.name =
this.methods = [] ;
if(methods.length<1){
console.log("두 번째 매개변수는 빈 배열일 수 없습니다.")
}
for(var i=0;len=methods. length,iif(typeofmethods[i][0] !== 'string'){
console.log("첫 번째 매개변수 데이터 유형은 문자열이어야 합니다.")
}
if(methods[i][1] && typeofmethods[i][1] !== 'number'){
console.log("두 번째 매개변수의 데이터 유형은 정수여야 합니다. " );
}
if(methods[i].length == 1){
methods[i][1] = 0;
}
this.methods.push(methods [ i]);
}
}

인터페이스 함수의 정의 규칙을 코드에서 확인하는 것은 어렵지 않습니다. [1] 인터페이스 함수는 두 개의 매개변수만 포함할 수 있습니다. , 첫 번째 매개변수는 인터페이스 이름, 두 번째 매개변수는 2차원 배열입니다. [2] 두 번째 매개변수는 빈 배열이 될 수 없습니다. [3] 메소드 매개변수의 첫 번째 매개변수는 문자열 유형이어야 하며, 메소드 이름, 두 번째 매개변수를 정의합니다. 매개변수는 정수형이어야 하며 메소드의 매개변수 개수를 정의하는 데 사용됩니다. [4] 메소드에서 메소드의 매개변수 개수가 0인 경우 생략할 수 있습니다.
다음으로, 클래스를 구축하고 앞서 정의한 인터페이스를 상속해야 합니다. 그러면 어떻게 해야 할까요? 다음 코드를 참조하세요.

코드 복사 코드는 다음과 같습니다. var ioldfish = function(name,age){
this. 이름 = 이름;
this.age = 나이
Interface.regImplement(this,interface)
}
ioldfish.prototype.getName = function(){
alert(this.name) );
};
ioldfish.prototype.getAge = function(){
alert(this.age)
}
var fishwl = new ioldfish("老鱼",27 );
fishwl.getName();


Interface.regImplement는 인터페이스 사양에 따라 ioldfish 클래스 코드를 만드는 것입니다. Firebug 콘솔에서는 예외가 발생합니다.
이 메소드의 구체적인 구현 코드를 살펴보세요:



코드 복사 코드는 다음과 같습니다. Interface.regImplement = function(object){
if(arguments.length<2){
console.log("인터페이스 상속 매개변수는 2보다 작을 수 없습니다.")
}
for(var i=1;len = 인수.길이,ivar 인터페이스 = 인수[i]
if(interface.constructor !== 인터페이스){
console.log(" 세 번째 매개변수는 인터페이스 인스턴스로 시작해야 합니다.")
}
for(var j=0;len=interface.methods.length,jvar 메소드 = 인터페이스.메소드 [j][0];
if(!object[메서드] || typeof 객체[메서드] !=="function" || 객체[메서드].getParameters().length !== interface.methods[j ][1]){
console.log("" 메소드 "메소드 인터페이스가 일치하지 않습니다.")
}
}
}
}


이 코드를 해석하면 다음을 쉽게 찾을 수 있습니다. [1] Interface.regImplement 상속된 인터페이스 함수의 매개변수에는 세 번째 매개변수가 있는 경우 매개변수가 인터페이스 인터페이스의 인스턴스여야 합니다. [2] 인터페이스 인터페이스의 메소드를 탐색하여 새 클래스의 메소드와 하나씩 일치시킵니다. 인터페이스 사양을 상속받은 클래스에 메소드가 누락된 것이 발견되면 오류 메시지가 발생합니다. [3] 인터페이스도 매개변수 개수와 일치합니다. 인터페이스 메서드의 매개변수 개수가 새 클래스의 메서드 개수와 일치하지 않으면 오류 메시지가 발생합니다.
여기에서는 메소드의 매개변수 수를 일치시키기 위해 getParameters() 메소드를 사용합니다. 함수를 기반으로 확장을 작성합니다.
코드 복사 코드는 다음과 같습니다.

Function.prototype.getParameters = function(){
var str = this.toString( );
var paramStr = str.slice (str.indexOf("(") 1,str.indexOf(")")).replace(/s*/g,''); 🎜>return (paramStr.length ==0 ? [] : paramStr.split(","))
}
catch(err){
console.log("잘못된 함수")
}
}


다음으로 인터페이스 함수, Interface.regImplement 함수, Function.prototype.getParameters 함수를 인터페이스.js 파일에 통합하여 새로 생성된 ioldfish 클래스를 디버깅할 수 있습니다. . 클래스에 getAge 메소드가 없으면 어떤 일이 발생하는지 확인하세요. 초보자에게는 다양한 상황을 시뮬레이션하여 이해도를 높이는 것이 좋습니다! 인터페이스 디자인을 완전히 이해했다고 확신한다면 나를 따라오세요.
자바스크립트 디자인 패턴 싱글톤 모드
싱글 모드 싱글톤: 엄밀히 말하면 패턴이 전혀 없지만, 알리페이의 많은 구성요소들이 쉽게 디자인되어 있습니다. 싱글턴 패턴을 통해 사실 이 패턴은 "JavaScript 객체지향 프로그래밍에 대한 간략한 이야기"에서 프로토타입 상속을 설명할 때 이미 사용된 적이 있습니다. 여기서는 게으른 단량체에 초점을 맞춰 간단히 언급하겠습니다. 이것은 모든 사용자에게 필요한 것은 아니며 단지 필요합니다. 특정 상황에서는 사용되는 구성 요소가 매우 좋은 최적화 효과를 가지며 사용자가 구성 요소를 트리거할 때까지 구성 요소의 인스턴스화를 연기할 수 있습니다.


var ioldfish = {
name: '老鱼',
age:27,
getName:function(){
alert(name)
},
getAge:function(){
alert(age); ;
}
}


위의 예는 내 모든 데이터를 ioldfish 객체 리터럴에 통합하여 모듈을 구성하는 동시에 네임스페이스 역할로 기능하는 가장 간단한 단일 모드입니다. .


var ioldfish =(function(){
var name = '老鱼';
var age = 27;
return{
getName:function(){
alert(name);
getAge: function() {
alert(age);
}
}
})()


첫 번째 단일 본문을 간단히 수정하고 클로저를 사용합니다. 이름을 변경하면 age는 정적 개인 변수가 되어 인스턴스화될 때 메모리에 항상 하나의 복사본만 있도록 보장하며 이는 단일 모드의 정의에 더 부합합니다.
다음은 게으른 단량체에 초점을 맞췄습니다. 이제 게으른 단량체를 구현하는 방법을 살펴보겠습니다.



코드 복사 코드는 다음과 같습니다. var ioldfish = (function(){
var UniqueInstance;
var name = '老鱼';
var age = 27;
함수 생성자(){
return{
getName:function(){
alert(name)
},
getAge:function(){
alert (나이);
}
}
}
return{
isInstance:function(){
if(uniqueInstance == null){
uniqueInstance = constructor();
}
return UniqueInstance;
}
}
})()
ioldfish.isInstance().getName();
위 구조는 명백히 공개 및 비공개입니다. 전용 변수 UniqueInstance(클래스가 인스턴스화되었는지 식별)와 전용 메서드 생성자는 공용 메서드 isInstance(개인 메서드 생성자에 정의된 메서드를 호출할 수 있음)를 반환합니다. , 형식: ioldfish .isInstance().getName(); 먼저 isInstance() 메서드를 통해 인스턴스화되었는지 확인한 다음 getName() 메서드를 통해 클로저에 있는 전용 변수 이름을 가져옵니다. 이 모드에는 여전히 많은 응용 프로그램 시나리오가 있습니다. 페이지에 로드해야 하지만 모든 사용자가 이를 사용할 수 없는 큰 달력 컨트롤을 접한 적이 있습니까? 인가요...
Javascript Design Pattern Factory Mode Factory
Factory Mode Factory: 먼저 추상 클래스를 생성한 후 이 추상 클래스를 기반으로 하위 클래스를 파생시키고, 하위 클래스에 팩토리 메소드를 생성하여 인스턴스화를 연기합니다. 솔직히 말해서 자바스크립트에서 팩토리 패턴을 적용하는 것은 좀 무리가 있습니다. 결국 자바스크립트는 자바처럼 하드코딩으로 인한 어려움이 없습니다. 패턴을 따르고, 패턴 때문에 패턴을 피합니다.
극단적인 예로, 탭 전환 및 드롭다운 목록과 같은 구성 요소에 위치 지정, 페이딩, 지연 및 기타 효과를 추가하려면 먼저 이러한 구성 요소에 대한 인터페이스를 정의할 수 있습니다.
var Iwidget = new Interface("iwidget ",[["addEffect"]]);
이후 파생 하위 클래스가 상속할 수 있도록 이 인터페이스를 정의합니다. 인터페이스는 addEffect 메서드를 정의합니다. 인터페이스 메서드가 구현된 후에는 호출하는 학생이 주의를 기울일 필요가 없습니다. addEffect 메소드의 코드 구현을 위한 것입니다.
코드 복사 코드는 다음과 같습니다.

var Widget = function(){};
Widget.prototype={
fire:function(model){
var widget = this.createWidget(model);
//일부 학생들은 하위 클래스가 인터페이스 메서드를 정의해야 하는 이유를 물었습니다.
widget.addEffect();
return widget;
},
show:function(){
//코드 구현 표시
},
hide: function( ){
//코드별 구현 숨기기
},
createWidget:function(model){
alert('추상 클래스, 인스턴스화할 수 없음')
}
} ;

위의 예에서는 먼저 추상 클래스 Widget을 파생 하위 클래스의 상위 클래스로 정의합니다. 두 가지 유형의 구성 요소 모두 컨테이너를 숨기고 표시하는 것을 고려하면 상위 클래스에 미리 정의되어 있습니다. 하위 클래스 상속을 위한 메소드 표시 및 숨기기.
코드 복사 코드는 다음과 같습니다.

var xTab = function(){};
확장(xTab,Widget);
xTab.prototype.createWidget = function(model){
var widget
switch(model){
case 'position':
widget = new xTabPosition();
break
case 'anim':
widget = new xTabAnim()
case 'delay':
기본값:
widget = new xTabDelay();
}
};
var dropDown = function(){}
extend(dropDown,Widget)
dropDown.prototype.createWidget ){
var widget
switch(model){
case 'position':
widget = new dropDownPosition()
case 'anim':
widget = new dropDownAnim();
break;
case 'delay':
widget = new dropDownDelay()


하위 클래스 xTab 및 dropDown은 상위 클래스를 상속하고 createWidget 메서드를 다시 작성합니다. 이러한 인스턴스를 생성하는 클래스가 인터페이스에서 합의된 addEffect 메서드를 구현하는 한, 서로 다른 하위 클래스는 서로 다른 인스턴스를 생성합니다. , 메소드 코드를 구현하는 방법은 모두 동일하므로 원하는 대로 조정하면 됩니다.



코드 복사
코드는 다음과 같습니다. var xTabPosition = function(){}; xTabPosition.prototype ={ addEffect:function(){
//특정 구현 코드
}
}
var dropDownPosition = function(){}; .prototype = {
addEffect:function(){
//특정 구현 코드
}
}
var dropDownInstance = new dropDown()
dropDownInstance.fire('position) ');


비유하자면, 이러한 효과를 버블 구성 요소에 추가해야 하는 경우 동일한 패턴을 따르면 됩니다. 이 시점에서 이 디자인 패턴은 클래스 간의 결합을 크게 줄이고 다양한 보조 작업을 구현할 수 있음을 분명히 알 수 있습니다. 특정 상호 작용 요구 사항에 따라 다르지만 필연적으로 코드 구현의 복잡성이 증가합니다. 실제로 이 모드는 Java와 다르며 클래스 이름을 하드 코딩하는 목적이 없습니다. 그의 디자인 아이디어를 배우십시오. 따라서 위의 예는 단지 참고용일 뿐입니다. 어른이 주변에 있지 않는 한 아이들은 따라해서는 안 됩니다.
JavaScript 매니아들에게 더 가치 있는 것은 팩토리 패턴에서 언급된 "캐싱(메모이제이션) 메커니즘"일 것입니다. 책에서는 이 기능을 설명하기 위해 XHR 객체를 생성하는 예를 제공하지만 효과는 분명 충분하지 않습니다. 당연히...
memoization 명사 설명: 함수의 각 실행 결과를 키-값 쌍에 넣습니다(상황에 따라 배열을 사용할 수도 있음). 값 쌍은 해당 실행 값이 이미 있는 경우 값이 직접 반환됩니다. 그렇지 않은 경우 함수 본문의 평가 부분이 실제로 실행됩니다. 분명히, 특히 키-값 쌍에서 값을 찾는 것은 함수를 실행하는 것보다 훨씬 빠릅니다.
재귀 호출 중에 메모의 힘이 더 잘 드러날 수 있습니다. 다음은 전형적인 피보나치 수열입니다. fib(20)은 fib 메서드를 21891번 실행합니다. fib(40)인 경우 331160281번 실행됩니다.
코드 복사 코드는 다음과 같습니다.

function fib(n) {
if (n < 2) {
return n;
}
return fib(n - 1) fib(n - 2)
}

보자 다시 사용하는 방법 메모이제이션을 구현하려면:
코드 복사 코드는 다음과 같습니다.

var iterMemoFib = (function() {
var 캐시 = [1, 1];
var fib = function(n) {
if (n >= 캐시.길이) {
// 재귀를
for (var i = 캐시.길이; i <= n; i ) {
cache[i] = 캐시[i - 2] 캐시[i - 1]; }
}
return 캐시[n-1];
}
return fib;
})()

memoize를 사용하여 함수 프로토타입 확장 물론, 자주 실행되지 않는 일부 기능의 경우 캐시할 필요가 없습니다.

코드 복사 코드는 다음과 같습니다.
Function.prototype.memoize = function() {
var pad = {} ;
var self = this; var obj = 인수 .length > 0 ? 인수[i] : null;
var memoizedFn = function() {
// 매개변수를 배열로 저장합니다. 키로, 함수 실행 결과를 값으로 캐시합니다.
var args = []
for (var i = 0; i args[i] = 인수[i];
}
if (!(args in pad)) {
pad[args] = self.apply(obj, 인수)
}
return pad[ args];
}
memoizedFn.unmemoize = function() {
return self;
}
rememoizedFn;
}
Function.prototype.unmemoize = function() {
alert("메모되지 않은 함수를 메모 해제하려고 합니다.");
return null;


사용법: fib.memoize(); Javascript 디자인 패턴
구성 모드: 이 디자인 패턴을 사용하여 개체를 결합합니다. 속성과 메서드를 추가하고 리프 개체를 반복적으로 일괄 처리하여 결합된 개체의 속성과 메서드를 얻습니다. 예를 들어 이제 은행 유형별로 온라인 뱅킹과 만화 뱅킹으로 구분되어 표시 여부를 구성할 수 있는 은행 목록을 동적으로 생성하려고 합니다. 조합 모드를 사용하여 이를 달성하는 방법은 무엇입니까?
첫 번째 단계는 먼저 인터페이스를 정의하는 것입니다. 특정 유형의 뱅크 또는 심지어 특정 뱅크가 표시될 수 있는지 여부를 구성 가능하게 만들기 위해 먼저 showBank와 hideBank라는 두 가지 인터페이스에 동의하기 때문입니다.
var IcardItem = new Interface("icardItem",[["showBank"],["hideBank"]])
다음으로 카드의 조합 개체를 정의하고 기본 메서드 추가, 제거를 설정합니다. 조합 객체 getChild. 이 클래스는 IcardItem 인터페이스 클래스를 상속하므로 showBank 및 hideBank라는 두 가지 인터페이스 메서드도 정의합니다.




코드 복사
코드는 다음과 같습니다.

var cardMain = function(id){
this.cards = [];
this.element = document.createElement("div");
this.element.id = id;
Interface.regImplement(this,IcardItem);
};
cardMain.prototype = {
add:function(카드){
this.cards.push(카드);
this.element.appendChild(card.getElement());
},
remove:function(card){
for(i=0;len=this.cards.length,iif(cards[i] == 카드){
this.cards.splice(i,1);
휴식;
}
this.element.removeChild(card.getElement());
}
},
getChild:function(i){
return this.cards[i];
},
getElement:function(){
return this.element;
},
showBank:function(){
this.element.style.display ="block";
for(i=0;len=this.cards.length,ithis.cards[i].showBank();
}
},
hideBank:function(){
this.element.style.display ="none";
for(i=0;len=this.cards.length,ithis.cards[i].hideBank();
}
}
};

然后결정义叶子对象类bankLogo사용以创建银行logo,这里银行logoduc以带class的a标签标识:
제조시대 代码如下:

varbankLogo = function(bankClassName){
this.element = document.createElement("a");
this.element.className = 은행클래스이름;
Interface.regImplement(this,IcardItem);
};
bankLogo.prototype ={
showBank:function(){
this.element.style.display ="block";
},
hideBank:function(){
this.element.style.display ="none";
},
getElement:function(){
return this.element;
}
};

最后设置一个单体对象,将操作银行的个模块,方便调用:
复代码 代码如下:

var BankAction ={
bankList:[],
addBank:function(card){
this.bankList.push(card) ;
},
innerBank:function(conId){
for(i=0;len=this.bankList.length,ivar cardObj =this.bankList[i ].getElement();
}
document.getElementById(conId).appendChild(cardObj);
}
};

到了实现环节了,实例化生成一个包含所有卡的最外层容器,然后根据,卡类分别生成一个放置银行卡와卡은 일반적으로 즐거운 여행이며, 最后生成各银行卡的实例,并按层级关系shape成DOM结构:
复代码 代码如下:

var 은행 DivT = new cardMain("PayCard");//创建最외부层容器
var ebankCard = new cardMain("ebankCard");//创建网银类银行卡容器
var ktCard = new cardMain("ktCard" );//创建卡通类银行卡容器
var ccbBank = newbankLogo('Ebank-CMB');//创建招行银行卡
var abcBank = newbankLogo('Ebank-ABC');//创建农行银行卡
var abcKtBank = newbankLogo('Kt-ABC');//创建卡通农行卡
ebankCard.add(ccbBank);
ebankCard.add(abcBank);
ktCard.add(abcKtBank);
bankDivT.add(ebankCard);
bankDivT.add(ktCard);
BankAction.addBank(bankDivT);
BankAction.innerBank("bankList");

将动态生成银行列表, DOM结构形如:
复system代码 代码如下:











조합 모드 애플리케이션은 사용자 인터페이스를 동적으로 생성할 때 매우 좋은 선택입니다. 응집력 있는 코드를 크게 단순화하고 유지 관리성을 향상시킬 수 있습니다. 그러나 결국 리프 개체가 많은 경우에도 재귀에는 성능 문제가 있으므로 주의해서 사용해야 합니다.
자바스크립트 디자인 패턴의 데코레이터 패턴
데코레이터 패턴: 새 하위 클래스를 만들지 않고도 객체에 대한 새 함수를 만들 수 있습니다. 예: 잔액 결제와 결합된 Alipay 체크아웃 빨간 봉투의 애플리케이션 시나리오입니다.
 var Ieconomics = new Interface("ieconomics",[["getPrice"]]);
먼저 컴포넌트 클래스를 생성하고, 컴포넌트를 기반으로 인스턴스화된 객체가 데코레이터 클래스에 매개변수로 전달됩니다. 데코레이터가 구성 요소의 다양한 메서드를 호출할 수 있도록 합니다.
코드 복사 코드는 다음과 같습니다.

 vareconomic = function(){
Interface.regImplement(this,Ieconomics);
economic.prototype={
getPrice:function(){
//코드 구현
}


그런 다음 파생 데코레이터 옵션 클래스의 상위 클래스로 데코레이터 추상 클래스를 만듭니다.


vareconomicsDecorator = function(economic){
this.economic =economic;
this.regImplement(economic,Ieconomics)
}; EconomicsDecorator.prototype={
getPrice:function(){
return this.economic.getPrice();
}
}


마지막으로 위 내용을 바탕으로 추상 클래스, 파생 데코레이터 옵션 클래스 생성:


코드 복사 코드는 다음과 같습니다. //빨간 봉투 장식 또는 옵션 클래스
var 쿠폰 = function(economic){
//추상 클래스로 장식된 생성자 호출
economicsDecorator.call(this,economic)
}; 🎜>extend( 쿠폰, 쿠폰Decorator);
coupon.prototype=function(){
//getPrice 메소드 다시 작성
getPrice:function(){
return this.economic.getPrice() - this.getCoupon() ;
},
getCoupon:function(){
//빨간 봉투의 총 가격을 가져오는 구체적인 구현
}
}; myCoupon = neweconomic();
myCoupon = new 쿠폰(myCoupon);


먼저 myCoupon 구성요소의 인스턴스를 구현하는 것은 매우 간단합니다. 데코레이터 옵션 클래스 쿠폰에 대한 매개변수로 개체를 지정합니다. 두 코드 줄 모두에서 myCoupon 변수에 값을 할당했음을 알 수 있습니다. 이는 둘 다 동일한 인터페이스 클래스를 구현하고 서로 바꿔 사용할 수 있기 때문입니다.
이것을 본 주의깊은 학생들은 쿠폰 클래스에 getCoupon 메소드를 추가했음을 알 수 있을 것입니다. 현재로서는 문제가 없지만 계속해서 쇼핑 쿠폰 데코레이터 옵션 클래스를 생성한 다음 빨간색을 사용하면 어떨까요? 봉투를 같이?



코드 복사
코드는 다음과 같습니다. //쇼핑바우처 데코레이터 옵션 클래스 var 바우처 = function(경제적){ economicsDecorator.call(this,economic);
extend(voucher,couponDecorator)
voucher.prototype=function(){
getPrice :function(){
return this.getPrice() - this.getVoucher();
},
getVoucher:function(){
//총 가격을 가져오는 구체적인 구현 쿠폰
}
};
var myCoupon = neweconomic();
myCoupon = 새 쿠폰(myCoupon)
myCoupon = 새 쿠폰(myCoupon);
여기서 이 시나리오에서는 getCoupon 메소드를 더 이상 찾을 수 없습니다. 이는 바우처가 myCoupon을 장식할 때 해당 상위 클래스인economicsDecorator에 getCoupon 메소드가 포함되어 있지 않기 때문에 당연히 얻을 수 없기 때문입니다.
데코레이터 추상 클래스인economicsDecorator를 분석하여 myCoupon에 대한 참조를 매개변수로 전달하고 이 매개변수를 사용하여 몇 가지 작은 작업을 수행하고 새로 추가된 메서드를 얻을 수 있습니다.
 



코드 복사


코드는 다음과 같습니다.

 vareconomicsDecorator = function(economic){
this.economic =economic;
this.interface = Ieconomics;
for(var k in this.economic){
if( typeof this.economic[key] !== "function"){
continue;
var i
for(i = 0;len = this.interface.methods.length,i < len; i ) {
//이 메소드가 인터페이스 클래스에 포함되어 있는지 비교하여 포함되어 있으면 다음 메소드를 반환
if(key == this.interface.methods[i][0] ) {
break ;
}
}
if(i < this.interface.methods.length)
continue
var decorator = this
//정의됨 익명 함수 호출 새 메소드 사용
(function(methodName) {
decorator[methodName] = function() {
return decorator.economic[methodName]();
};
}) (키);
}
}
this.regImplement(economic,Ieconomics)
}
economicsDecorator.prototype={
getPrice:function(){
return this.economic.getPrice();
}
};

위 코드를 보면 데코레이터 추상 클래스를 일부 수정했습니다. 옵션 클래스에 새 메소드가 정의되면 데코레이터 추상 클래스에서 동적으로 정의될 수 있습니다. 다음은 데코레이터 패턴 사용에 대한 아이디어입니다. 프로젝트가 아직 개발 중이기 때문에 데모는 아직 제공되지 않습니다. 상세한 디자인을 당신과 함께합니다.
Javascript 디자인 패턴의 브리지 모드
브리지 모드: 추상화와 구현을 분리하여 독립적으로 변경할 수 있습니다. 실제로 이는 매우 간단합니다. API와 특정 이벤트 사이에 브리지를 추가하여 API와 이를 사용하는 클래스 및 개체 간의 결합을 줄입니다.
사실 브릿지 모드는 대부분의 학생들에게 낯설지 않습니다. 다음 this.getName은 브릿지 메소드로 내부 프라이빗 변수에 액세스하여 구현됩니다. 외부 커뮤니케이션과 내부 커뮤니케이션을 연결하는 다리.

코드 복사 코드는 다음과 같습니다.
var ioldfish = function(){
var name = 'Old Fish';
this.getName = function(){
alert(name);
}
}

가장 일반적으로 사용되는 브리지 모드는 이벤트 리스너 콜백 함수입니다. 사용자 정보를 얻기 위한 API 인터페이스 함수는 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.
function getUserInfo(userid,callback){
asyncRequest('GET','userInfo?userid=' userid,function(resp){
callback(resp.responseText);
})
}

다음으로 해야 할 일은 이 API와 이벤트 트리거 사이의 브리지 관계를 설정하는 것입니다.
addEvent(element,'click',bridgeMethod); function bridgeMethod(e) {
getUserInfo(this.userid,function(){
//콜백 함수 구현 코드
})
}
요소가 클릭된 객체는 getIserInfo가 아니지만 새로운 브리지 메소드인 bridgeMethod가 생성됩니다. 이러한 브리징 계층을 통해 API 인터페이스 기능과 클릭 이벤트가 상대적으로 독립적이므로 API 적용 범위가 크게 넓어집니다.
Javascript 디자인 패턴 어댑터 패턴
어댑터 패턴: 예를 들어 시스템을 유지 관리합니다. 이전에는 항상 프로토타입 프레임워크를 사용했지만 이제는 두 프레임워크 간에 전환하는 방법을 도입할 계획입니다.
, 예를 들어 프로토타입의 $ 메소드를 YUI의 get 메소드로 변환하는 방법:


function $(){};
function YAHOO.util.Dom.get=function(el){};
function 프로토타입ToYuiAdapter(){
return YAHOO .util.Dom.get(인수)
}


프로토타입에서 yui의 get 메소드를 사용하려면 다음 문만 작성하면 됩니다.
 $ = 프로토타입ToYuiAdapter;
이 경우 프로토타입에서 YUI의 get 메소드를 사용할 수 있습니다. 저는 이 모델을 별로 좋아하지 않기 때문에 자세히 설명하지는 않겠습니다. 사실 저는 이 모델을 사용할 필요가 전혀 없다고 생각합니다. 이 모드를 사용하지 않으려면 절박한 상황에서 임시 솔루션으로만 사용할 수 있습니다.
자바스크립트 디자인 패턴 파사드 모드, 관찰자 ​​모드
파사드 모드: 모든 스크립트 프레임워크에서 사용해야 합니다. 프레임워크에 정의된 메소드를 찾아 살펴보세요. YUI 등의 setStyle 메소드로 사용됩니다. 여기서는 자세히 설명할 것이 없습니다.
관찰자 패턴: JavaScript에서 이 디자인 패턴을 적용하는 것은 더 무리한 것 같습니다. 따라서 다른 사람들이 오해할 수 있는 내용을 피하기 위해 여기서는 다루지 않겠습니다. 조언 좀 부탁드립니다.
이 블로그 포스팅을 하루 종일 했는데, 아직 쓰고 싶은 게 많은 것 같습니다. 마음속에 있는 내용을 깔끔하게 정리하기가 쉽지 않은 것 같습니다. 나중에, 계속 지켜봐 주시기 바랍니다!
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.