공장 모델의 도입 전에, 우리는 디자인 패턴 무엇을 이해할 필요가? 설계 원리는 무엇입니까?
디자인 패턴 :
우리는 문제, 종종 한 방향으로 만 해결하면 일반적으로 우리가 일반적으로 해결하기 위해 다양한 방법이 있지만 확실히 다양하고 효율적인 솔루션이 될 것입니다, 소프트웨어 개발이 솔루션은 우리가 디자인 전화 모드;
디자인 패턴은 고정 된 공식이 아니라 아이디어는 문제 해결 아이디어이며, 디자인 패턴의 적절한 사용, 당신은 재사용을 달성하고 코드의 유지 보수성을 향상시킬 수 있습니다;
디자인 원칙 :
일반적으로 많은 것들을, 일부 사양 제약이있을 것이다; 소프트웨어 개발의 과정에서, 우리는 개발 사양으로 원칙을 디자인 할 수 있지만 따를 필요는 없지만, 다음, 우편 번호 유지 보수를 수행하지 않습니다 아주 나쁜 될 것이다 재사용;
에 따라 설계 원칙은 코드 재사용 성, 견고성, 유지 보수가 더 좋을 것입니다하지만 우리가 높은 결합, 낮은 커플 링 코드를 작성 도움이 될 수 있습니다;
어떤 디자인 패턴 :
프로그램에서 우리는 보통 분류에 따라, 23 개 디자인 패턴으로 간주된다 :
유형을 만들기 :
-
- 추상 팩토리 패턴
- 공장 방법 패턴
- 빌더 모드
- 프로토 타입 모드
- 싱글
구조 :
-
- 어댑터 모드
- 브리지 모드
- 결합 모드
- 데코레이터 패턴
- Facade 패턴
- 플라이급
- 프록시 모드
행동 :
-
- 의무 체인.
- 이름 지정 패턴
- 통역 패턴
- 반복자 패턴
- 중개 모델
- 메멘토 패턴
- 옵저버 패턴
- 주 모드
- 전략 모드
- 방문자 패턴
- 템플릿 메소드 패턴
어떤 디자인 원칙은 다음과 같습니다 :
첫 번째 영어 단어에 따르면 우리가 분류에 따라, SOLID 설계 원리, 설계 원칙 다섯 종류의 총이라고합니다 :
1, S (단일 책임의 원칙) - 단일 책임 원칙
프로그램 또는 클래스 나 메소드가 기능이 너무 복잡하면, 우리는 열려 분할합니다 할 수있는 단 한 가지이며, 각각의 방법은 독립을 유지, 커플 링의 정도를 감소;
2, O (개방 - 폐쇄 원칙) - 개방 - 폐쇄 원칙
확장 오픈, 변경, 폐쇄, 새로운 요구를 추가, 우리가 소스 코드를 수정하기보다는, 새로운 코드를 추가하는 것입니다 할 필요가;
例如:我们在使用vue框架的时候,有很多第三方插件我们可以去使用,在使用的时候我们通常都是直接在vue-cli中增加引入代码,而非去修改vue源码来达到支持某种功能的目的;
3、L(Liskov Substitution Principle, LSP)——李氏置换原则
子类能覆盖父类,父类能出现的地方子类就能出现;(在JS中没有类概念,使用较少)
4、I (Interface Segregation Principle)——接口独立原则
保持接口的单一独立,类似于单一原则,不过接口独立原则更注重接口;(在JS中没有接口概念)
5、D(Dependence Inversion Principle ,DIP)——依赖倒置原则
面向接口编程,依赖于抽象而不依赖于具体,使用方只关注接口而不需要关注具体的实现;(JS中没有接口概念)
作为前端开发人员来说,我们用的最多的设计原则是S(单一职责原则).O(开放封闭原则),所以在程序设计的时候我们重点关注这两个即可 ;
设计模式——工厂模式:
所谓工厂模式就是像工厂一样重复的产生类似的产品,工厂模式只需要我们传入正确的参数,就能生产类似的产品;
工厂模式根据抽象程度依次分为简单工厂模式、工厂方法模式、抽象工厂模式;
简单工厂模式:
在我们的生活中很多时候就有这样的场景,像在网站中有的页面是需要根据账号等级来决定是否有浏览权限的;账号等级越高可浏览的就越多,反之就越少;
// JS设计模式之简单工厂 function factory(role){ function superAdmin(){ this.name="超级管理员"; this.viewPage=["首页","发现页","通讯录","应用数据","权限管理"]; } function admin(){ this.name="管理员"; this.viewPage=["首页","发现页","通讯录","应用数据"]; } function user(){ this.name="普通用户"; this.viewPage=["首页","发现页","通讯录"]; } switch(role){ case "superAdmin": return new superAdmin(); break; case "admin": return new admin(); break; case "user": return new user(); break; } } let superAdmin = factory("superAdmin"); console.log(superAdmin); let admin = factory("admin"); console.log(admin); let user = factory("user"); console.log(user);
上述代码中,factory就是一个工厂,factory有三个函数分别是对应不同的产品,switch中有三个选项,这三个选项相当于三个模具,当匹配到其中的模具之后,将会new一个构造函数去执行生产工厂中的function;但是我们发现上面的简单工厂模式会有一定的局限性,就是如果我们需要去添加新的产品的时候,我们需要去修改两处位置(需要修改function和switch)才能达到添加新产品的目的;
下面我们将简单工厂模式进行改良:
// JS设计模式之简单工厂改良版 function factory(role){ function user(opt){ this.name = opt.name; this.viewPage = opt.viewPage; } switch(role){ case "superAdmin": return new user({name:"superAdmin",viewPage:["首页","发现页","通讯录","应用数据","权限管理"]}); break; case "admin": return new user({name:"admin",viewPage:["首页","发现页","通讯录","应用数据"]}); break; case "normal": return new user({name:"normal",viewPage:["首页","发现页","通讯录"]}); } } let superAdmin = factory("superAdmin"); console.log(superAdmin); let admin = factory("admin"); console.log(admin); let normal = factory("normal"); console.log(normal);
经过上面的修改之后,我们工厂里面的函数相当于一个万能摸具,switch里面给我什么,我就加工成什么样的;自然就解决了添加商品需要修改两处代码的问题;
工厂方法模式:
工厂方法模式是将创建对象的工作推到子类中进行;也就是相当于工厂总部不生产产品了,交给下辖分工厂进行生产;但是进入工厂之前,需要有个判断来验证你要生产的东西是否是属于我们工厂所生产范围,如果是,就丢给下辖工厂来进行生产,如果不行,那么要么新建工厂生产要么就生产不了;
// JS设计模式之工厂方法模式 function factory(role){ if(this instanceof factory){ var a = new this[role](); return a; }else{ return new factory(role); } } factory.prototype={ "superAdmin":function(){ this.name="超级管理员"; this.viewPage=["首页","发现页","通讯录","应用数据","权限管理"]; }, "admin":function(){ this.name="管理员"; this.viewPage=["首页","发现页","通讯录","应用数据"]; }, "user":function(){ this.name="普通用户"; this.viewPage=["首页","发现页","通讯录"]; } } let superAdmin = factory("superAdmin"); console.log(superAdmin); let admin = factory("admin"); console.log(admin); let user = factory("user"); console.log(user);
工厂方法模式关键核心代码就是工厂里面的判断this是否属于工厂,也就是做了分支判断,这个工厂只做我能生产的产品,如果你的产品我目前做不了,请找其他工厂代加工;
抽象工厂模式:
如果说上面的简单工厂和工厂方法模式的工作是生产产品,那么抽象工厂模式的工作就是生产工厂的;
举个例子:代理商找工厂进行合作,但是工厂没有实际加工能力来进行代加工某产品;无奈又签署了合同,这时,工厂上面的集团公司就出面了,集团公司承认该工厂是该集团下属公司,所以集团公司就重新建造一个工厂来进行代加工某商品以达到履行合约;
//JS设计模式之抽象工厂模式 let agency = function(subType, superType) { //判断抽象工厂中是否有该抽象类 if(typeof agency[superType] === 'function') { function F() {}; //继承父类属性和方法 F.prototype = new agency[superType] (); console.log(F.prototype); //将子类的constructor指向子类 subType.constructor = subType; //子类原型继承父类 subType.prototype = new F(); } else { throw new Error('抽象类不存在!') } } //鼠标抽象类 agency.mouseShop = function() { this.type = '鼠标'; } agency.mouseShop.prototype = { getName: function(name) { // return new Error('抽象方法不能调用'); return this.name; } } //键盘抽象类 agency.KeyboardShop = function() { this.type = '键盘'; } agency.KeyboardShop.prototype = { getName: function(name) { // return new Error('抽象方法不能调用'); return this.name; } } //普通鼠标子类 function mouse(name) { this.name = name; this.item = "买我,我线长,玩游戏贼溜" } //抽象工厂实现鼠标类的继承 agency(mouse, 'mouseShop'); //子类中重写抽象方法 // mouse.prototype.getName = function() { // return this.name; // } //普通键盘子类 function Keyboard(name) { this.name = name; this.item = "行,你买它吧,没键盘看你咋玩"; } //抽象工厂实现键盘类的继承 agency(Keyboard, 'KeyboardShop'); //子类中重写抽象方法 // Keyboard.prototype.getName = function() { // return this.name; // } //实例化鼠标 let mouseA = new mouse('联想'); console.log(mouseA.getName(), mouseA.type,mouseA.item); //联想 鼠标 //实例化键盘 let KeyboardA = new Keyboard('联想'); console.log(KeyboardA.getName(), KeyboardA.type,KeyboardA.item); //联想 键盘
抽象工厂模式一般用于严格要求以面向对象思想进行开发的超大型项目中,我们一般常规的开发的话一般就是简单工厂和工厂方法模式会用的比较多一些;
大白话解释:简单工厂模式就是你给工厂什么,工厂就给你生产什么;
工厂方法模式就是你找工厂生产产品,工厂是外包给下级分工厂来代加工,需要先评估一下能不能代加工;能做就接,不能做就找其他工厂;
抽象工厂模式就是工厂接了某项产品订单但是做不了,上级集团公司新建一个工厂来专门代加工某项产品;