这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
出现
设计模式是有经验的开发人员在开发过程中,遇到了问题,然后用最佳的方法去解决这些问题,这些方法就是一个个的设计模式。
前人栽树 后人乘凉,前人总结了那么多好方法,我们也应该尽早了解这些方法,在开发的时候,尽量先有个整体的思想,看看哪些方法能适用,避免日后实在难以维护再进行大改,既不敢去动原来代码,又浪费时间。
设计模式有几个原则
开闭原则在程序需要进行拓展的时候,不能去修改原有的代码来到这个新公司的时候,发现没有使用外面的组件库,基本都是自己手撸的,业务又总是多变的,我老想着反正源码就在这,直接在上面加个属性去判断就好了,这个就不太符合这个原则了。
说几个
创建型模式
单例模式\
什么时候使用?
想要节省资源
好处
减少全局变量,全局对象被污染问题
限制类实例化次数只能一次,一个类只有一个实例,减少了内存的开销
问题
不能继承
下面是一个简单的实现
class Single {
constructor(name,password){
this.name = name
this.password = password
}
static getInstance(name,password){
if(!this.instance)this.instance = new Single(name,password)
return this.instance
}
}
let instance1 = Single.getInstance('name','111')
let instance2 = Single.getInstance('age','18')
console.log(obj1===obj2) // true
工厂模式\
什么时候使用?
我们明确地计划不同条件下创建不同实例时。
好处:
解决了代码复用性问题,减少页面的中的冗余代码。
两个问题:
可读性问题,不知道这个函数具体是要来当什么用的,用于功能函数还是工厂模式。
空间性问题:里面的function 不是通用的,不同的存储空间,每次调用都会创建。
Vue.component()也是是工厂模式的实现
下面是一个简单的实现
// 入口
function createPerson(name, age) {
//加工过程
var obj = {};
obj.name = name;
obj.age = age;
obj.info = function () {
console.log(obj.name, obj.age);
}
// 出口
return obj;
}
var p1 = createPerson('xiaopei' , 26);
p1.info();
var p2 = createPerson('xiaoqiangh' , 25);
p2.info();
console.log(p1.info == p2.info) // false
构造模式:
什么时候使用?
需要生成的对象具有复杂的内部结构
好处:
解决了工厂模式的可读性,建造者独立,易扩展
问题:
实例必须有共同点,范围有限制
工厂模式空间性问题还在
下面是一个简单的实现
function CreatePerson(name, age) {
this.name = name;
this.age = age;
this.info = function () {
console.log(this.name, this.age);
}
}
var p1 = new CreatePerson('xiaopei' , 26);
p1.info();
var p2 = new CreatePerson('xiaoqiangh' , 25);
p2.info();
console.log(p1.info == p2.info) // false
构造函数和普通函数的唯一区别,在于调用它们的方式不同。
原型模式
什么时候使用?
在开发中很少只用到原型模式
好处:
性能提高。
解决了工厂模式的空间性问题
所有实例都共享属性和方法
问题:
共享是一个优点,同时也是一个缺点,属性的类型为引用类型的时候,对它的增删改都是同一个地址。改一个就等于改多个
下面是一个简单的实现
function CreatePerson() {}
CreatePerson.prototype.name = '';
CreatePerson.prototype.age = 0;
CreatePerson.prototype.play = []
CreatePerson.prototype.info = function () {
console.log(this.name, this.age,this.play);
}
var p1 = new CreatePerson();
p1.name = 'xiaopei'
p1.play.push('game')
p1.info(); // xiaopei 0 ["game"]
var p2 = new CreatePerson();
p2.name = 'xiaoqiang'
p2.info(); // xiaoqiang 0 ["game"]
console.log(p1.info == p2.info) // true
根据上面创建型模式的问题,说一个
结构型模式
组合模式
什么时候使用?
创建自定义类型最常见的方式,就是组合模式。
好处:
即解决了可读性问题,又解决了空间占用问题
改变实例的属性,并不影响其它实例的属性
支持向构造函数传递参数。
问题:
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则(这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。)。
下面是一个简单的实现
function CreatePerson() {
this.name = '';
this.age = 0;
this.play = []
}
CreatePerson.prototype.info = function () {
console.log(this.name, this.age,this.play);
}
var p1 = new CreatePerson();
p1.name = 'xiaopei'
p1.play.push('game')
p1.info(); // xiaopei 0 ["game"]
var p2 = new CreatePerson();
p2.name = 'xiaoqiang'
p2.info(); // xiaoqiang 0 []
console.log(p1.info == p2.info) // true