什么是设计模式呢,就是一种编程的思想:代码书写经验,为了应对各种场景经过前任不断的总结,压缩,形成一套有一套的代码书写规范,形成了设计模式;针对特定问题,提出见解而有效的处理方案。
那这种设计模式有多少种呢:工厂模式,单例模式,组合模式,观察者模式,MV*模式,策略模式,代理模式,外观模式。亨元模式,中介者模式,装饰模式,适配器模式。。。。。。等等等
我就说我会的几种:1:单例模式 2.组合模式 3:观察者模式 4:策略模式 5:MVC模式
就先说第一个单例模式:单个实例,多次执行,只有一个对象,就是指如果需要多次创建同一个对象,完成同一件事情,肯定会多次new,真的会产生多个对象,但是没必要。修改成,多次执行,只有一个对象
如:
function Fn(){
if(!Fn.obj){
Fn.obj = {};
}
Fn.obj.sayHello = "hello";
return Fn.obj;
}
var f1 = new Fn();
var f2 = new Fn();
console.log(f1);
console.log(f2);
console.log(f1 === f2); // t
将来准备给Fn的身上添加一个属性,这个属性为对象,但是又不能每次都添加
只有第一次添加,之后都不同添加
判断,如果是第一次,意味着之前没有添加过,默认是undefined,如果不是第一次,意味着什么添加过,那么就是对象
为什么默认情况下,每次new会得到新对象呢?
这里就要补充一下new的特性了:new的原理:
// 1.创建了新对象
// 2.改变了this指向
// 3.修改了原型的指向
// 4.检查当前函数是否主动返回对象,如果没有,则返回第一步创建的新对象
每次new都新创建一个对象,所以这里就不用new了
//利用封装实现
// 需要一个构造函数
function Person(){}
// 封装一个单例模式的调用方式
var f = (function(){
var instance; // 等同于第一种写法中的Fn.obj
return function(){
if(!instance){
instance = new Person();
}
return instance;
}
})();
var p1 = f();
var p2 = f();
console.log(p1);
console.log(p2);
console.log(p1 === p2);
具体怎么用单例模式呢,应用一下:
// 给页面创建一个信息框
// 每次执行,设置新内容
// 信息框只有一个,只是内容在改而已
function Msg(){
this.ele = document.createElement("div");
document.body.appendChild(this.ele);
}
Msg.prototype.init = function(str){
this.ele.innerHTML = str;
}
var singleCase = (function (){
var instance;
return function(text){
if(!instance){
instance = new Msg();
}
instance.init(text);
return instance;
}
})();
var m1 = singleCase("hello");
var m2 = singleCase("world");
console.log(m1===m2);
下面就是组合模式了,顾名思义:组合将多个对象的功能,组成起来,实现批量执行
比如这样一个例子:
先准备一些需要批量执行的功能
class GoHome{
init(){
console.log("到家了,开门");
}
}
class OpenComputer{
init(){
console.log("开电脑");
}
}
class OpenXiaoAi{
init(){
console.log("开音乐");
}
}
然后再组装功能
class Comb{
constructor(){
// 准备容器,用来防止将来组合起来的功能
this.skills = [];
}
// 用来组合的功能,接收要组合的对象
add(task){
// 向容器中填入,将来准备批量使用的对象
this.skills.push(task);
}
// 用来批量执行的功能
action(){
// 拿到容器中所有的对象,才能批量执行
this.skills.forEach( val => {
val.init();
} );
}
}
功能都已经搞完,接下来需要一个容器容下:
var c = new Comb();
提前将,将来要批量操作的对象,组合起来
c.add( new GoHome() );
c.add( new OpenComputer() );
c.add( new OpenXiaoAi() );
等待何时的时机,执行组合器的启动功能
c.action();
在内部,会自动执行所有已经组合起来的对象的功能
// 特点:
// 批量执行
// 启动一个方法,会遍历多个方法,同时执行,有点类似于递归的感觉,所以,组合模式略微耗性能
// 耗性能,但是执行方便
// 目前只是一个基础组合
// 高级组合:组合成树状结构,每个对象下,还会有自己的子对象
// 如果执行了父对象的某个方法,所有的子对象会跟随执行
// 组合模式一般建议使用在动态的html结构上
// 因为组合模式的结构和html的结构,出奇的一致
=========================================================
**观察者模式:就是以观察的角度发现对应的状况,处理问题
// 发布者:发布信息
// 会随时更新自身的信息或状态
// 订阅者:接收信息
// 接收到发布者发布的信息,从而做出对应的改变或执行
// 很方便的实现简单的广播通信,实现一对多的对应关系
// 订阅者可以随时加入或离开**
举个例子:就是简单的广播通信方式:
function Stu(n){
this.name = n;
this.type = function(){
if(Math.random() > 0.5){
return "学习";
}else{
return "睡觉";
}
}
}
function Teac(n){
this.name = n;
this.listen = function(t,sn){
if(t == "学习"){
console.log(`${sn}是好孩子`);
}else{
console.log(`给${sn}一巴掌`);
}
}
}
function Teac2(n){
this.name = n;
this.listen = function(t,sn){
if(t == "学习"){
console.log(`嗯嗯...点头离开`);
}else{
console.log(`把${sn}揪起来,叫家长`);
}
}
}
var s = new Stu("张三");
var t = s.type();
var t1 = new Teac("班主任");
t1.listen(t, s.name);
var t2 = new Teac2("教导主任");
t2.listen(t, s.name);
策略模式就简单一点了,就是给出多个计划,当将来发生某种状态时,执行对应的计划
跟分支结构差不多
new Promise((a,b)=>{
//根据将来的状态
//选择执行成功或失败
}).then(()=>{
}).catch(()=>{})
然后就是MVC模式,这个在后端用的比较多,前端比较少,也是语义化: M:model数据
V:view视图
C:ctrl控制器
创建模型,管理多个数据
class Model{
model1(){
return "hello";
}
model2(){
return "world";
}
model3(){
return "你好";
}
}
创建视图,管理多种渲染方式
class View{
view1(data){
console.log(data);
}
view2(data){
document.write(data);
}
view3(data){
alert(data);
}
}
创建控制器,设定对应的指令
class Ctrl{
constructor(){
// 初始化模型和视图
this.m = new Model();
this.v = new View();
}
// 在指令中,可以读取对应的数据,放在对应的视图中
ctrl1(){
var data = this.m.model1();
this.v.view1(data);
}
ctrl2(){
var data = this.m.model2();
this.v.view3(data);
}
}
var c = new Ctrl();
c.ctrl1();
c.ctrl2();
设计模式总结:所有的设计模式的共同目标都是:
高内聚,低耦合
内聚:关系
耦合:依赖