设计者模式

Posted zhouying1208

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计者模式相关的知识,希望对你有一定的参考价值。

1. 单例模式:每个new出来的实例都需要有一个相同的方法,但是这时候如果 每个实例都新建一个这种方法,太占据内存也太慢,所以在这里有一个重要的判断:如果有实例,则返回实例;如果没有实例,则创建实例,并且返回实例。

例:

 
class CreateUser 
            static shareInstance()
                if(!CreateUser.ins)
                    CreateUser.ins = new CreateUser(‘aa‘)
                
                return CreateUser.ins;
            
            constructor(name) 
                this.name = name;
                this.getName();
            
            getName() 
                return this.name;
            
 
        
        let c1 = CreateUser.shareInstance()
        let c2 = CreateUser.shareInstance()
        console.log(c1==c2)

  

2. 组合模式:组合模式中基本对象和组合对象被一致对待;无须关心对象有多少层, 调用时只需在根部进行调用;类似DOM树

例:

const MacroCommand = function() 
  return 
    lists: [],
    add: function(task) 
      this.lists.push(task)
    ,
    excute: function()  //  组合对象调用这里的 excute,
      for (let i = 0; i < this.lists.length; i++) 
        this.lists[i].excute()
      
    ,
  



const command1 = MacroCommand() // 命令1
 
command1.add(
  excute: () => console.log(‘吃饭‘) // 
)
 
const command2 = MacroCommand() // 命令2
 
command2.add(
  excute: () => console.log(‘唱歌‘)
)
 
command2.add(
  excute: () => console.log(‘画画‘)
)
 
const command3 = MacroCommand() //命令3
 
command3.add(
  excute: () => console.log(‘下棋‘)
)
 
command3.add(
  excute: () => console.log(‘玩游戏‘)
)
 
const macroCommand = MacroCommand()//组合对象
macroCommand.add(command1)
macroCommand.add(command2)
macroCommand.add(command3)
 
macroCommand.excute()
 
// 吃饭
// 唱歌
//画画
// 下棋
// 玩游戏

  

3. 观察者模式:类似于事件监听, 观察者只要订阅了被观察者的事件,那么当被观察者的状态改变时,被观察者会主动去通知观察者,而无需关心观察者得到事件后要去做什么,实际程序中可能是执行订阅者的回调函数

例:

   var obj = 
            data: 
                list: []

            ,
        

        // defineProperty 可以观察 obj对象 的list 属性的使用
        Object.defineProperty(obj, ‘list‘, 
            get() 
                console.log(‘获取了list 属性‘)
                console.log(this.data[‘list‘])
                return this.data[‘list‘]
            ,
            set(val) 
                console.log(‘值被更改了‘)

                this.data[‘list‘] = val
            
        )

        // 获取了list属性,那么get 方法就会被调用
        console.log(obj.list)
        // 设置了list属性set 方法就会被调用
        obj.list = [‘a‘, ‘b‘]

  

4. 工厂模式: 去做同样的事情,实现同样的效果,批量生产

例:

// 文本工厂
        class Text 
            constructor(text) 
                this.text = text
            
            insert(where) 
                const txt = document.createTextNode(this.text)
                where.appendChild(txt)
            
        

        // 链接工厂
        class Link 
            constructor(url) 
                this.url = url
            
            insert(where) 
                const link = document.createElement(‘a‘)
                link.href = this.url
                link.appendChild(document.createTextNode(this.url))
                where.appendChild(link)
            
        

  

5. 抽象的工厂模式:先标记好模式,然后下面引用,但是里面什么都没有

class DomFactory 

            constructor() 

            


            // 各流水线

            insert() 


            


        

  

6. 策略模式:策略类部分和环境类部分

①策略类:写出好几种策略,类似于planA,planB….

例:

var levelOBJ = 
            "A": function (money) 
                return money * 4;
            ,
            "B": function (money) 
                return money * 3;
            ,
            "C": function (money) 
                return money * 2;
            
        ;
        /*环境类*/
        var calculateBouns = function (level, money) 
            return levelOBJ[level](money);
        ;
        console.log(calculateBouns(‘A‘, 10000)); // 40000

②环境类:运行的环境

7. 代理模式:经典例子:刚打开页面的时候加载个loading图片占位,等图片加载过来后再显示该图片,提前占坑

例:

const MyImage = function (parent) 
            const imgNode = document.createElement(‘img‘)
            parent.appendChild(imgNode)

            // 提供一个方法 ,让外部也能修改 图片的src属性
            this.setSrc = function(src)
                imgNode.src = src
            
            
        
        // 直接添加图片 ,如果图片比较大,可能加载的比较慢,导致网页上的img一开始显示不出来
        let myImage   = new MyImage(document.body)

// 写个代理   提供 预加载功能
        const ProxyImage = function (myImage) 

            // 创建image对象
            const img = new Image()
            img.on
            // 监听img对象的 onload 方法
            img.onload = function ()  // http 图片加载完毕后才会执行
                // 模拟网络很慢的情况
                setTimeout(()=>
                    myImage.setSrc(this.src)

                ,2000)
            
            

            this.setSrc =function (src) 
                    // 加载时候先不加载大图,先加载一张小图(浏览器已经下载过的)
                    myImage.setSrc(‘loading.gif‘) // 本地 loading 图片
                    img.src = src
            
        
        //
        let proxyImage = new ProxyImage(myImage)
        proxyImage.setSrc(‘https://www.baidu.com/img/bd_logo1.png?where=super‘)

  

8. 适配器模式:类似于把obj对象转为数组,这时候如果是大量的操作怕出意外,就可以运用这种模式,就相当于有个中介转一下

例:

// 老接口
        const zhejiangCityOld = function () 
            return [
                    name: ‘hangzhou‘,
                    id: 11,
                ,
                
                    name: ‘jinhua‘,
                    id: 12
                
            ]
        

        console.log(zhejiangCityOld())

        // 新接口希望是下面形式
        // 
        //     hangzhou: 11,
        //     jinhua:12
        // 

        // 这时候就可采用适配者模式
        const adaptor = function (oldCity) 
            console.log(oldCity)
            const obj = 
            for (let city of oldCity) 
                obj[city.name] = city.id
            
            return obj
        


        let oldData = zhejiangCityOld();
        //把老数据放在适配器中产生新数据
        console.log(adaptor(oldData))

 

既然看了这么多设计者模式,接下来也可以了解一下hash,它在我们的应用中也很重要:

1.Hash:传统的网页根据用户访问的不同地址,浏览器从服务器获取对应页面的内容展示给用户,这样造成服务器压力比较大,用户访问比较慢,在这种场景下,出现了单页应用。

2. Hashchange:想要用hash就要监听到hash什么时候改变,这时候就需要用hashchange来监听

 

以上是关于设计者模式的主要内容,如果未能解决你的问题,请参考以下文章

框架源码系列一:设计模式(设计思想设计原则各种设计模式介绍设计模式总结)

Java设计模式-创建型设计模式-原型模式

C#设计模式--桥接模式

软件设计原则都有哪些

设计模式: 单列设计模式 模块方法设计模式

研磨设计模式