浅谈设计模式

前言:设计模式是程序员进阶的必经之路,真正地理解、掌握设计模式对编写高质量代码是极有帮助的,下面简单谈一下自己对设计模式的理解。

概括:设计模式就是代码书写经验,为了应对各种场景,经过前人不断的总结,压缩,形成的一套又一套的代码的书写规范,于是就形成了设计模式。

一、单例模式
单例模式就是保证一个类仅有一个实例,并提供一个访问它的全局访问点。
代码如下:

// 给页面创建一个信息框
  // 每次执行,设置新内容
  // 信息框只有一个,只是内容在改
  function Msg() {
    this.ele = document.createElement("div");
    document.body.appendChild(this.ele);
  }
  Msg.prototype.init = function (str) {
    this.ele.innerHTML = str;
  }
  var f = (function () {
    var instance;
    return function (text) {
      if (!instance) {
        instance = new Msg();
      }
      instance.init(text);
      return instance;
    }
  })()
  var m1 = f("hello");
  var m2 = f("world");
  console.log(m1 === m2); //true

二、组合模式
组合模式是一种专为创建Web.上的动态用户界面而量身定制的模式。使用这种模式,可
以用一条命令在多个对象上激发复杂的或递归的行为。这可以简化粘合性代码,使其
更容易维护,而那些复杂行为则被委托给各个对象。
代码如下:

 class Game {
    init() {
      console.log("打游戏");
    }
  }
  class Run {
    init() {
      console.log("跑步");
    }
  }
  class Study {
    init() {
      console.log("学习");
    }
  }
  // 组合器,用来组合功能
  class Comb {
    constructor() {
      this.skills = [];
    }
    // 用来要组合的功能,接收组合的对象
    add(task) {
      this.skills.push(task);
    }
    // 用来批量执行的功能
    action() {
      this.skills.forEach(val => {
        val.init();
      })
    }
  }
  // 创建一个组合器
  var f = new Comb();
  // 提前将,将来要批量操作的对象,组合起来
  f.add(new Game());
  f.add(new Run());
  f.add(new Study());
  // 等待何时的时机,执行组合器的启动功能
  f.action();

三、观察者模式:也称发布订阅者模式
在事件驱动的环境中,比如浏览器这种持续寻求用户关注的环境中,观察者模式是一种管理人与其任务之间的关系(确切地讲,是对象及其行为和状态之间的关系)的得力工具。用JavaScript的话来说,这种模式的实质就是你可以对程序中某个对象的状态进行观察,并且在其发生改变时能够得到通知。
简而言之:
发布者:发布信息,会随时新自身的信息或状态;
订阅者:接收信息,接收到发布者发布的信息,从而做出对应的改变或执行;

下面是一个简单的广播通信,实现一对多的对应关系:

  function Stu(n) {
     this.name = n;
     this.type = function () {
       if (Math.random() > 0.5) {
         return "学习";
       } else {
         return "打游戏";
       }
     }
   }
 
   function Teacher(n) {
     this.name = n;
     this.listen = function (t) {
       if (t == "学习") {
         console.log("好孩子");
       } else {
         console.log("坏孩子");
       }
     }
   }
 
   function Teacher2(n) {
     this.name = n;
     this.listen = function (t) {
       if (t == "学习") {
         console.log("奖励");
       } else {
         console.log("惩罚");
       }
     }
   }
 
 var s = new Stu("张三");
 var t = s.type();
 console.log(t);
 
 var t1 = new Teacher("老师1");
 t1.listen(t);
 
 var t2 = new Teacher2("老师2");
 t2.listen(t);

四、策略模式
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
下面举一个简单的小例子:
根据情况进行不一样的方案,比如你想去旅游,明确自己有多少钱然后选择旅游方式。
没钱,走路
有钱,飞机
还行,火车
这里就涉及到策略的模式了。
代码如下:

var strategies = {
    "rich": function () {
        console.log("You can go with plane!");
    },
    "poor": function () {
        console.log("OH, You can go with your feet!");
    },
    "middle": function () {
        console.log("You can go with train!");
    }
}
var howShouldGo = function (money) {
    return strategies[money]();
}
console.log(howShouldGo("rich"));

五、工厂模式
故名思意,我们从字面上的意思就可以看到,可以想象一座工厂源源不断产出一样的产品,流水线作业。没错,工厂模式就是这样。
我们首先创建一个工厂,我们只要传递参数进去,里面具体的过程我们不用去关心,最后返回一个对象。
代码如下:

function createPerson(n,a,s){
      var person = {};        // 原料
      // 加工
      person.name = n;
      person.age = a;
      person.sex = s;
      person.sayHello = function(){
          console.log(this.name + "---" + this.age)
      }
      // 出厂
      return person;
  }
  var p1 = createPerson("zhangsan",18,"男");
  console.log(p1);
  p1.sayHello();

  var p2 = createPerson("lisi",19,"女");
  console.log(p2);
  p2.sayHello();

六、MVC模式:M:model数据 V:view视图 C:ctrl控制器
MVC是一个架构设计模式,它通过分离关注点的方式来支持改进应用组织方式。它促成了业务数据(Models)从用户界面(Views)中分离出来,还有第三个组成部分(Controllers)负责管理传统意义上的业务逻辑和用户输入。
代码如下:

 // 创建模型,管理多个数据
    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();

七、适配器模式:
适配器模式就相当于一个转换接口,大家想想我们手机充电器通常是二岔口的,但是电源只有三岔口的。这时候就需要一个适配器把三岔口的转换成二岔口的。
它的作用其实就是解决两个软件实体间的接口不兼容问题,使用之后就可以一起工作了。
代码如下:

var googleMap = {
    show: function () {
        console.log('googleMap show!');
    }
}
var baiduMap = {
    show: function () {
        console.log('baiduMap show!');
    }
}

var renderMap = function (map) {
    if (map.show instanceof Function) {
        map.show()
    }
}
renderMap(googleMap);
renderMap(baiduMap);

上面这段程序能够运行是因为百度地图和谷歌地图用的同一种show方法,但是我们在不知道对方使用的函数接口的时候,我们就不能这样用了(可能百度是使用了display方法来显示)。下面的baiduMapAdapter就是我们使用的适配器。
代码如下:

var googleMap = {
    show: function () {
        console.log('googleMap show!');
    }
}
var baiduMap = {
    display: function () {
        console.log('baiduMap show!');
    }
}

var renderMap = function (map) {
    if (map.show instanceof Function) {
        map.show()
    }
}

var baiduMapAdapter = {
    show:function(){
        return baiduMap.display()
    }
}
renderMap(googleMap);
renderMap(baiduMapAdapter);

八、外观模式:
为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使子系统更加容易使用。
具体代码如下:

// 三个处理函数
function start() {
    console.log('start');
}

function doing() {
    console.log('doing');
}

function end() {
    console.log('end');
}

// 外观函数,将一些处理统一起来,方便调用
function execute() {
    start();
    doing();
    end();
}


// 调用init开始执行
function init() {
    // 此处直接调用了高层函数,也可以选择越过它直接调用相关的函数
    execute();
}

init(); 

九、中介者模式:
所有的相关 对象都通过中介者对象来通信,而不是互相引用,所以当一个对象发生改变时,只需要通知中介者对象即可。
中介者模式使网状的多对多关系变成了相对简单的一对多关系(复杂的调度处理都交给中介者)。
代码如下:

var A = {
    score: 10,

    changeTo: function(score) {
        this.score = score;

        // 自己获取
        this.getRank();
    },
    
    // 直接获取
    getRank: function() {
        var scores = [this.score, B.score, C.score].sort(function(a, b) {
            return a < b;
        });

        console.log(scores.indexOf(this.score) + 1);
    }
};

var B = {
    score: 20,

    changeTo: function(score) {
        this.score = score;

        // 通过中介者获取
        rankMediator(B);
    }
};

var C = {
    score: 30,

    changeTo: function(score) {
        this.score = score;

        rankMediator(C);
    }
};

// 中介者,计算排名
function rankMediator(person) {
    var scores = [A.score, B.score, C.score].sort(function(a, b) {
        return a < b;
    });

    console.log(scores.indexOf(person.score) + 1);
}

// A通过自身来处理
A.changeTo(100); // 1

// B和C交由中介者处理
B.changeTo(200); // 1
C.changeTo(50); // 3

总结:其实设计模式我们经常能用到,只是我们没有注意而已。上面我们说了一些设计模式,还有很多其它的模式,比如命令模式,享元模式,装饰模式等等,后面会持续更新…。

以上如有错误、描述不准确等问题,欢迎大家指正,谢谢…

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java是一种面向对象的编程语言,设计模式可以帮助我们更好地编写面向对象的代码。在JavaWeb项目中,设计模式可以帮助我们解决一些常见的问题,比如复杂的业务逻辑、代码重用、可扩展性等等。 下面是一些常见的设计模式在JavaWeb项目中的使用: 1. MVC模式:MVC模式是一种常见的设计模式,它将应用程序分为三个部分:模型、视图和控制器。在JavaWeb项目中,我们可以使用MVC模式来分离业务逻辑和用户界面,并且可以更容易地进行修改和维护。 2. 工厂模式:工厂模式是一种创建型设计模式,它可以帮助我们更好地组织代码并提高代码的可复用性。在JavaWeb项目中,我们可以使用工厂模式来创建对象,并且可以根据需要动态地创建不同的对象。 3. 单例模式:单例模式是一种创建型设计模式,它保证了一个类只有一个实例,并提供了一个全局访问点。在JavaWeb项目中,我们可以使用单例模式来管理共享资源,比如数据库连接池。 4. 观察者模式:观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,它的所有依赖对象都会得到通知并自动更新。在JavaWeb项目中,我们可以使用观察者模式来实现事件驱动的编程。 5. 装饰器模式:装饰器模式是一种结构型设计模式,它允许我们动态地添加或修改一个对象的功能。在JavaWeb项目中,我们可以使用装饰器模式来扩展一个类的功能,而不需要修改它的原始代码。 当然,在JavaWeb项目中还有很多其他的设计模式可以使用,具体使用哪些设计模式需要根据具体的情况而定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值