GVKun编程网logo

JS 设计模式四 -- 模块模式(js模块化原理及实现过程)

11

以上就是给各位分享JS设计模式四--模块模式,其中也会对js模块化原理及实现过程进行解释,同时本文还将给你拓展2018.3.18设计模式--常用设计模式和设计模式的六大原则汇总、iOS设计模式--备忘

以上就是给各位分享JS 设计模式四 -- 模块模式,其中也会对js模块化原理及实现过程进行解释,同时本文还将给你拓展2018.3.18 设计模式 -- 常用设计模式和设计模式的六大原则汇总、iOS设计模式--备忘录设计模式与命令设计模式、Java 之美 [从菜鸟到高手演变] 之设计模式四、Java 之设计模式四等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

JS 设计模式四 -- 模块模式(js模块化原理及实现过程)

JS 设计模式四 -- 模块模式(js模块化原理及实现过程)

概念

模块模式的思路 就是 就是单例模式添加私有属性和私有方法,减少全局变量的使用。

简单的代码结构:

var singleMode = (function(){
    // 创建私有变量
    var privateNum = 100;
    // 创建私有函数
    function privateFunc(){
        // 实现自己的业务逻辑代码
    }
    // 返回一个对象包含公有方法和属性
    return {
        publicMethod1: publicMethod1,
        publicMethod2: publicMethod1
    };
})();

 

什么时候使用模块模式?

如果我们必须创建一个对象并对某些对象进行初始化时,同时还要公开访问这些私有数据的方法,name 这个时候我们就可以使用模块模式了。

 

增强的模块模式

增强的模块模式的使用场合是:适合那些单列必须是某种类型的实例,同时还必须添加某些属性或方法对其加以增强的情况。

function CustomType() {
    this.name = "GaoSir";
};
CustomType.prototype.getName = function(){
    return this.name;
}
var application = (function(){
    // 定义私有
    var privateA = "privateA";
    // 定义私有函数
    function privateMethodA(){};

    // 实例化一个对象后,返回该实例,然后为该实例增加一些公有属性和方法
    var object = new CustomType();

    // 添加公有属性
    object.publicA = "publicA";
    // 添加公有方法
    object.publicB = function(){
        return privateA;
    }
    // 返回该对象
    return object;
})();

console.log(application.publicA);// publicA

console.log(application.publicB()); // privateA

console.log(application.name); // GaoSir

console.log(application.getName());// GaoSir

 

 

2018.3.18 设计模式 -- 常用设计模式和设计模式的六大原则汇总

2018.3.18 设计模式 -- 常用设计模式和设计模式的六大原则汇总

## 常用 23 种设计模式 ###1. 设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

其实还有两类:并发型模式和线程池模式。

## 设计模式六大原则

总原则-开闭原则
        总是对扩展开放、对修改封闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有的代码,。一句话概括就是:为程序的拓展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类等。


1.单一职责原则
     不要存在于一个导致类变更的原因,也就是说每个类应该实现单一的职责,否则就应该吧类拆分


2.里氏替换原则
    任何基类可以出现的地方,子类一定可以出现。里氏替换原则是继承复用的基石,只有当衍生类可以替换基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏替换原则是对“开---闭原则的补充”。实现“开闭”原则的额关键步骤就是抽象化。而基类与子类的继承关系就是抽象化
的具体实现,所以里氏替换原则是对实现抽象化的具体步骤的规范。里氏替换原则中,子类与父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这额规范的接口与外界交互,子类不应该随便破坏它。

3.依赖倒转原则
    面向接口编程,依赖于抽象而不依赖于具体,写代码用到具体类时,不与具体类交互,而与具体类的上层接口接口交互。

4.接口隔离原则
    每个接口中不存在子类用不到却必须是实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个接口)要好。


5.迪米特法则(最少知道原则)
    一个类对自己依赖的类知道的越少越好。无论被依赖的类多复杂,都应该讲逻辑封装在方法内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
最少知道原则的另一个表达方式是:只与直接的朋友通信。类与类之间只要有耦合关系,就叫做朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。

6.合成复用原则
    尽量首先使用合成/集合的方式,而不是使用继承。

####1. 简单工厂模式(面向接口)

1.概念:
	先构造一个工厂出来,在里面进行生产,用的时候直拿出来

2.实现的过程:
			先定义一个接口的标准  里面定义某些方法不用具体实现
			在具体的类(所谓的产品)中去实现这个接口,然后把里面具体的方法实现出来(就是在实现类中重写接口里面的方法)
			在工厂类中,定义一个  静态接口 方法 然后根据传入的参数(所谓的原料)来判断最后的结果(成品) 
			在测试类中,通过工厂类去点里面的方法来实现最终的产品是什么。

3.总结
	屏蔽了不同子类实现的差异,提高代码的可拓展行和可维护性。

####2. 适配器模式(面向接口)

1.概念:
	使用一个现成的类,但是它的接口不完全符合你的需求,我只是想要他其中的一个方法,不想复写其他的方法,因此可以用适配器作为中间的过渡。

2.实现的过程
	先定义一个接口的标准,把标准的方法声明出来,不用具体实现;
	在写一个适配器的类来实现这个接口,因此需要重写里面的所有方法。
	在写一个你自己想要特定需求的类,然后继承这个适配器类,就能写你需要的方法
	在测试类中,new 一下你自己需要的类,因为可以简便的通过点方法来实现。

3.总结
	只想用其中某一个方法,用适配器作为中间的过度

iOS设计模式--备忘录设计模式与命令设计模式

iOS设计模式--备忘录设计模式与命令设计模式

何为备忘录模式?

    在响应某些事件时,应用程序需要保存自身的状态,比如当用户保存文档或程序退出时。例如,游戏退出之前,可能需要保存当前会话的状态,如游戏等级、敌人数量、可用武器的种类等。游戏再次打开时,玩家可以从离开的地方接着玩。很多时候,保存程序的状态真的不需要什么特别巧妙的方法。任何简单有效的方法都可以,但是同时,保存信息应该只对原始程序有意义。原始程序应该是能够解码它所保存文档中的信息的唯一实体。这就是备忘录模式应用于游戏、文字处理等程序的软件设计中的方式,这些程序需要保存当前上下文的复杂状态的快照并在以后恢复。

    备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先的保存状态。

何时使用备忘录模式?

    当同时满足以下两个条件时,应当考虑使用这一模式:

    @:需要保存一个对象(或某部分)在某一个时刻的状态,这样以后就可以恢复到先前的状态。

    @:用于获取状态的接口会暴漏实现的细节,需要将其隐藏起来。

Cocoa Touch框架中的备忘录模式

    Cocoa Touch框架在归档、属性列表序列化和核心数据中采用了备忘录模式。Cocoa的归档是对对象及其属性还有同其他对象间的关系进行编码,形成一个文档,该文档既可以保存于文件系统,也可以在进程或网络间传送。对象与其他对象的关系被看做对象图的网络。归档过程把对象保存为一种与架构无关的字节流,保持对象的标识以及对象之间的关系。对象的类型也同数据一起保存。从字节流解码出来的对象通常用与对象编码时相同的类型进行实例化。

    如果想归档一个对象,很多时候我们是考虑保存程序的状态。在模型-视图-控制器范式中,程序的状态通常由模型对象来进行维护。我们把模型对象编码到文档,然后再对其解码读回来。在运行时使用NSCoder对象进行编码与解码操作。NSCoder本身是个抽象类。苹果公司建议通过NSCoder的具体类NSKeyArchiver和NSKeyedUnarchiver,使用基于键的归档技术。被编码与解码的对象必须遵守NSCoding协议并实现以下方法:

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;


何为命令模式?

    命令对象封装了如何对目标执行命令的信息,因此客户端或调用者不必了解目标的任何细节,却仍可以对它执行任何已有的操作。通过把请求封装成对象,客户端可以把参数化并置入队列或日志中,也能够支持可撤销的操作。命令对象将一个或多个动作绑定到特定的接收器。命令模式消除了作为对象的动作和执行它的接收器之间的绑定。

    命令模式:将请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求队列或记录请求日志,以及支持可撤销的操作。

何时使用命令模式?

    在以下情形,自然会考虑使用这一模式。

    @:想让应用程序支持撤销与恢复。

    @:想用对象参数化一个动作以执行操作,并用不同的命令对象来代替回调函数。

    @:想要在不同时刻对请求进行指定、排列和执行。

    @:想记录修改日志,这样在系统故障时,这些修改可以在后来重做一遍。

    @:想让系统支持事务,事务封装了对数据的一系列修改,事务可以建模为命令对象。

在Cocoa Touch框架中使用命令模式:

    NSInvocation、NSUndoManage和Target-Action机制是框架中对这个模式的典型引用。


如何使用备忘录模式与命令模式,详见下面这篇文章:

http://blog.jobbole.com/48179/ (译文)  http://www.raywenderlich.com/46988/ios-design-patterns (原文)

本篇文章的demo链接地址:

https://guoshimeihua@github.com/guoshimeihua/MemoryAndCommandDemo.git

本篇文章备忘录模式与命令模式就写到这里了。

Java 之美 [从菜鸟到高手演变] 之设计模式四

Java 之美 [从菜鸟到高手演变] 之设计模式四

其实每个设计模式都是很重要的一种思想,看上去很熟,其实是因为我们在学到的东西中都有涉及,尽管有时我们并不知道,其实在 Java 本身的设计之中处处都有体现,像 AWT、JDBC、集合类、IO 管道或者是 Web 框架,里面设计模式无处不在。因为我们篇幅有限,很难讲每一个设计模式都讲的很详细,不过我会尽我所能,尽量在有限的空间和篇幅内,把意思写清楚了,更好让大家明白。本章不出意外的话,应该是设计模式最后一讲了,首先还是上一下上篇开头的那个图:

本章讲讲第三类和第四类。

19、备忘录模式(Memento)

主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类 A,A 中有各种属性,A 可以决定需要备份的属性,备忘录类 B 是用来存储 A 的一些内部状态,类 C 呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。做个图来分析一下:

Original 类是原始类,里面有需要保存的属性 value 及创建一个备忘录类,用来保存 value 值。Memento 类是备忘录类,Storage 类是存储备忘录的类,持有 Memento 类的实例,该模式很好理解。直接看源码:

[java] view plain copy print ?
  1. public class Original {  
  2.       
  3.     private String value;  
  4.       
  5.     public String getValue() {  
  6.         return value;  
  7.     }  
  8.   
  9.     public void setValue(String value) {  
  10.         this.value = value;  
  11.     }  
  12.   
  13.     public Original(String value) {  
  14.         this.value = value;  
  15.     }  
  16.   
  17.     public Memento createMemento(){  
  18.         return new Memento(value);  
  19.     }  
  20.       
  21.     public void restoreMemento(Memento memento){  
  22.         this.value = memento.getValue();  
  23.     }  
  24. }  
public class Original {
	
	private String value;
	
	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public Original(String value) {
		this.value = value;
	}

	public Memento createMemento(){
		return new Memento(value);
	}
	
	public void restoreMemento(Memento memento){
		this.value = memento.getValue();
	}
}
[java] view plain copy print ?
  1. public class Memento {  
  2.       
  3.     private String value;  
  4.   
  5.     public Memento(String value) {  
  6.         this.value = value;  
  7.     }  
  8.   
  9.     public String getValue() {  
  10.         return value;  
  11.     }  
  12.   
  13.     public void setValue(String value) {  
  14.         this.value = value;  
  15.     }  
  16. }  
public class Memento {
	
	private String value;

	public Memento(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}
[java] view plain copy print ?
  1. public class Storage {  
  2.       
  3.     private Memento memento;  
  4.       
  5.     public Storage(Memento memento) {  
  6.         this.memento = memento;  
  7.     }  
  8.   
  9.     public Memento getMemento() {  
  10.         return memento;  
  11.     }  
  12.   
  13.     public void setMemento(Memento memento) {  
  14.         this.memento = memento;  
  15.     }  
  16. }  
public class Storage {
	
	private Memento memento;
	
	public Storage(Memento memento) {
		this.memento = memento;
	}

	public Memento getMemento() {
		return memento;
	}

	public void setMemento(Memento memento) {
		this.memento = memento;
	}
}

测试类:

[java] view plain copy print ?
  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.           
  5.         // 创建原始类   
  6.         Original origi = new Original("egg");  
  7.   
  8.         // 创建备忘录   
  9.         Storage storage = new Storage(origi.createMemento());  
  10.   
  11.         // 修改原始类的状态   
  12.         System.out.println("初始化状态为:" + origi.getValue());  
  13.         origi.setValue("niu");  
  14.         System.out.println("修改后的状态为:" + origi.getValue());  
  15.   
  16.         // 回复原始类的状态   
  17.         origi.restoreMemento(storage.getMemento());  
  18.         System.out.println("恢复后的状态为:" + origi.getValue());  
  19.     }  
  20. }  
public class Test {

	public static void main(String[] args) {
		
		// 创建原始类
		Original origi = new Original("egg");

		// 创建备忘录
		Storage storage = new Storage(origi.createMemento());

		// 修改原始类的状态
		System.out.println("初始化状态为:" + origi.getValue());
		origi.setValue("niu");
		System.out.println("修改后的状态为:" + origi.getValue());

		// 回复原始类的状态
		origi.restoreMemento(storage.getMemento());
		System.out.println("恢复后的状态为:" + origi.getValue());
	}
}

输出:

初始化状态为:egg
修改后的状态为:niu
恢复后的状态为:egg

简单描述下:新建原始类时,value 被初始化为 egg,后经过修改,将 value 的值置为 niu,最后倒数第二行进行恢复状态,结果成功恢复了。其实我觉得这个模式叫 “备份 - 恢复” 模式最形象。

20、状态模式(State)

核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿 QQ 来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:1、可以通过改变状态来获得不同的行为。2、你的好友能同时看到你的变化。看图:


State 类是个状态类,Context 类可以实现切换,我们来看看代码:

[java] view plain copy print ?
  1. package com.xtfggef.dp.state;  
  2.   
  3. /** 
  4.  * 状态类的核心类 
  5.  * 2012-12-1 
  6.  * @author erqing 
  7.  * 
  8.  */  
  9. public class State {  
  10.       
  11.     private String value;  
  12.       
  13.     public String getValue() {  
  14.         return value;  
  15.     }  
  16.   
  17.     public void setValue(String value) {  
  18.         this.value = value;  
  19.     }  
  20.   
  21.     public void method1(){  
  22.         System.out.println("execute the first opt!");  
  23.     }  
  24.       
  25.     public void method2(){  
  26.         System.out.println("execute the second opt!");  
  27.     }  
  28. }  
package com.xtfggef.dp.state;

/**
 * 状态类的核心类
 * 2012-12-1
 * @author erqing
 *
 */
public class State {
	
	private String value;
	
	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public void method1(){
		System.out.println("execute the first opt!");
	}
	
	public void method2(){
		System.out.println("execute the second opt!");
	}
}
[java] view plain copy print ?
  1. package com.xtfggef.dp.state;  
  2.   
  3. /** 
  4.  * 状态模式的切换类   2012-12-1 
  5.  * @author erqing 
  6.  *  
  7.  */  
  8. public class Context {  
  9.   
  10.     private State state;  
  11.   
  12.     public Context(State state) {  
  13.         this.state = state;  
  14.     }  
  15.   
  16.     public State getState() {  
  17.         return state;  
  18.     }  
  19.   
  20.     public void setState(State state) {  
  21.         this.state = state;  
  22.     }  
  23.   
  24.     public void method() {  
  25.         if (state.getValue().equals("state1")) {  
  26.             state.method1();  
  27.         } else if (state.getValue().equals("state2")) {  
  28.             state.method2();  
  29.         }  
  30.     }  
  31. }  
package com.xtfggef.dp.state;

/**
 * 状态模式的切换类   2012-12-1
 * @author erqing
 * 
 */
public class Context {

	private State state;

	public Context(State state) {
		this.state = state;
	}

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	public void method() {
		if (state.getValue().equals("state1")) {
			state.method1();
		} else if (state.getValue().equals("state2")) {
			state.method2();
		}
	}
}

测试类:

[java] view plain copy print ?
  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.           
  5.         State state = new State();  
  6.         Context context = new Context(state);  
  7.           
  8.         // 设置第一种状态   
  9.         state.setValue("state1");  
  10.         context.method();  
  11.           
  12.         // 设置第二种状态   
  13.         state.setValue("state2");  
  14.         context.method();  
  15.     }  
  16. }  
public class Test {

	public static void main(String[] args) {
		
		State state = new State();
		Context context = new Context(state);
		
		//设置第一种状态
		state.setValue("state1");
		context.method();
		
		//设置第二种状态
		state.setValue("state2");
		context.method();
	}
}

输出:

execute the first opt!
execute the second opt!

根据这个特性,状态模式在日常开发中用的挺多的,尤其是做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。
21、访问者模式(Visitor)

访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。—— From 百科

简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。简单关系图:


来看看原码:一个 Visitor 类,存放要访问的对象,

[java] view plain copy print ?
  1. public interface Visitor {  
  2.     public void visit(Subject sub);  
  3. }  
public interface Visitor {
	public void visit(Subject sub);
}
[java] view plain copy print ?
  1. public class MyVisitor implements Visitor {  
  2.   
  3.     @Override  
  4.     public void visit(Subject sub) {  
  5.         System.out.println("visit the subject:"+sub.getSubject());  
  6.     }  
  7. }  
public class MyVisitor implements Visitor {

	@Override
	public void visit(Subject sub) {
		System.out.println("visit the subject:"+sub.getSubject());
	}
}

Subject 类,accept 方法,接受将要访问它的对象,getSubject () 获取将要被访问的属性,

[java] view plain copy print ?
  1. public interface Subject {  
  2.     public void accept(Visitor visitor);  
  3.     public String getSubject();  
  4. }  
public interface Subject {
	public void accept(Visitor visitor);
	public String getSubject();
}
[java] view plain copy print ?
  1. public class MySubject implements Subject {  
  2.   
  3.     @Override  
  4.     public void accept(Visitor visitor) {  
  5.         visitor.visit(this);  
  6.     }  
  7.   
  8.     @Override  
  9.     public String getSubject() {  
  10.         return "love";  
  11.     }  
  12. }  
public class MySubject implements Subject {

	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

	@Override
	public String getSubject() {
		return "love";
	}
}

测试:

[java] view plain copy print ?
  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.           
  5.         Visitor visitor = new MyVisitor();  
  6.         Subject sub = new MySubject();  
  7.         sub.accept(visitor);      
  8.     }  
  9. }  
public class Test {

	public static void main(String[] args) {
		
		Visitor visitor = new MyVisitor();
		Subject sub = new MySubject();
		sub.accept(visitor);	
	}
}

输出:visit the subject:love

该模式适用场景:如果我们想为一个现有的类增加新功能,不得不考虑几个事情:1、新功能会不会与现有功能出现兼容性问题?2、以后会不会再需要添加?3、如果类不允许修改代码怎么办?面对这些问题,最好的解决方法就是使用访问者模式,访问者模式适用于数据结构相对稳定的系统,把数据结构和算法解耦,
22、中介者模式(Mediator)

中介者模式也是用来降低类类之间的耦合的,因为如果类类之间有依赖关系的话,不利于功能的拓展和维护,因为只要修改一个对象,其它关联的对象都得进行修改。如果使用中介者模式,只需关心和 Mediator 类的关系,具体类类之间的关系及调度交给 Mediator 就行,这有点像 spring 容器的作用。先看看图:


User 类统一接口,User1 和 User2 分别是不同的对象,二者之间有关联,如果不采用中介者模式,则需要二者相互持有引用,这样二者的耦合度很高,为了解耦,引入了 Mediator 类,提供统一接口,MyMediator 为其实现类,里面持有 User1 和 User2 的实例,用来实现对 User1 和 User2 的控制。这样 User1 和 User2 两个对象相互独立,他们只需要保持好和 Mediator 之间的关系就行,剩下的全由 MyMediator 类来维护!基本实现:

[java] view plain copy print ?
  1. public interface Mediator {  
  2.     public void createMediator();  
  3.     public void workAll();  
  4. }  
public interface Mediator {
	public void createMediator();
	public void workAll();
}
[java] view plain copy print ?
  1. public class MyMediator implements Mediator {  
  2.   
  3.     private User user1;  
  4.     private User user2;  
  5.       
  6.     public User getUser1() {  
  7.         return user1;  
  8.     }  
  9.   
  10.     public User getUser2() {  
  11.         return user2;  
  12.     }  
  13.   
  14.     @Override  
  15.     public void createMediator() {  
  16.         user1 = new User1(this);  
  17.         user2 = new User2(this);  
  18.     }  
  19.   
  20.     @Override  
  21.     public void workAll() {  
  22.         user1.work();  
  23.         user2.work();  
  24.     }  
  25. }  
public class MyMediator implements Mediator {

	private User user1;
	private User user2;
	
	public User getUser1() {
		return user1;
	}

	public User getUser2() {
		return user2;
	}

	@Override
	public void createMediator() {
		user1 = new User1(this);
		user2 = new User2(this);
	}

	@Override
	public void workAll() {
		user1.work();
		user2.work();
	}
}
[java] view plain copy print ?
  1. public abstract class User {  
  2.       
  3.     private Mediator mediator;  
  4.       
  5.     public Mediator getMediator(){  
  6.         return mediator;  
  7.     }  
  8.       
  9.     public User(Mediator mediator) {  
  10.         this.mediator = mediator;  
  11.     }  
  12.   
  13.     public abstract void work();  
  14. }  
public abstract class User {
	
	private Mediator mediator;
	
	public Mediator getMediator(){
		return mediator;
	}
	
	public User(Mediator mediator) {
		this.mediator = mediator;
	}

	public abstract void work();
}
[java] view plain copy print ?
  1. public class User1 extends User {  
  2.   
  3.     public User1(Mediator mediator){  
  4.         super(mediator);  
  5.     }  
  6.       
  7.     @Override  
  8.     public void work() {  
  9.         System.out.println("user1 exe!");  
  10.     }  
  11. }  
public class User1 extends User {

	public User1(Mediator mediator){
		super(mediator);
	}
	
	@Override
	public void work() {
		System.out.println("user1 exe!");
	}
}
[java] view plain copy print ?
  1. public class User2 extends User {  
  2.   
  3.     public User2(Mediator mediator){  
  4.         super(mediator);  
  5.     }  
  6.       
  7.     @Override  
  8.     public void work() {  
  9.         System.out.println("user2 exe!");  
  10.     }  
  11. }  
public class User2 extends User {

	public User2(Mediator mediator){
		super(mediator);
	}
	
	@Override
	public void work() {
		System.out.println("user2 exe!");
	}
}

测试类:

[java] view plain copy print ?
  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Mediator mediator = new MyMediator();  
  5.         mediator.createMediator();  
  6.         mediator.workAll();  
  7.     }  
  8. }  
public class Test {

	public static void main(String[] args) {
		Mediator mediator = new MyMediator();
		mediator.createMediator();
		mediator.workAll();
	}
}

输出:

user1 exe!
user2 exe!
23、解释器模式(Interpreter)
解释器模式是我们暂时的最后一讲,一般主要应用在 OOP 开发中的编译器的开发中,所以适用面比较窄。


Context 类是一个上下文环境类,Plus 和 Minus 分别是用来计算的实现,代码如下:

[java] view plain copy print ?
  1. public interface Expression {  
  2.     public int interpret(Context context);  
  3. }  
public interface Expression {
	public int interpret(Context context);
}
[java] view plain copy print ?
  1. public class Plus implements Expression {  
  2.   
  3.     @Override  
  4.     public int interpret(Context context) {  
  5.         return context.getNum1()+context.getNum2();  
  6.     }  
  7. }  
public class Plus implements Expression {

	@Override
	public int interpret(Context context) {
		return context.getNum1()+context.getNum2();
	}
}
[java] view plain copy print ?
  1. public class Minus implements Expression {  
  2.   
  3.     @Override  
  4.     public int interpret(Context context) {  
  5.         return context.getNum1()-context.getNum2();  
  6.     }  
  7. }  
public class Minus implements Expression {

	@Override
	public int interpret(Context context) {
		return context.getNum1()-context.getNum2();
	}
}
[java] view plain copy print ?
  1. public class Context {  
  2.       
  3.     private int num1;  
  4.     private int num2;  
  5.       
  6.     public Context(int num1, int num2) {  
  7.         this.num1 = num1;  
  8.         this.num2 = num2;  
  9.     }  
  10.       
  11.     public int getNum1() {  
  12.         return num1;  
  13.     }  
  14.     public void setNum1(int num1) {  
  15.         this.num1 = num1;  
  16.     }  
  17.     public int getNum2() {  
  18.         return num2;  
  19.     }  
  20.     public void setNum2(int num2) {  
  21.         this.num2 = num2;  
  22.     }  
  23.       
  24.       
  25. }  
public class Context {
	
	private int num1;
	private int num2;
	
	public Context(int num1, int num2) {
		this.num1 = num1;
		this.num2 = num2;
	}
	
	public int getNum1() {
		return num1;
	}
	public void setNum1(int num1) {
		this.num1 = num1;
	}
	public int getNum2() {
		return num2;
	}
	public void setNum2(int num2) {
		this.num2 = num2;
	}
	
	
}
[java] view plain copy print ?
  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.   
  5.         // 计算 9+2-8 的值   
  6.         int result = new Minus().interpret((new Context(new Plus()  
  7.                 .interpret(new Context(92)), 8)));  
  8.         System.out.println(result);  
  9.     }  
  10. }  
public class Test {

	public static void main(String[] args) {

		// 计算9+2-8的值
		int result = new Minus().interpret((new Context(new Plus()
				.interpret(new Context(92)), 8)));
		System.out.println(result);
	}
}

最后输出正确的结果:3。

基本就这样,解释器模式用来做各种各样的解释器,如正则表达式等的解释器等等!

设计模式基本就这么大概讲完了,总体感觉有点简略,的确,这么点儿篇幅,不足以对整个 23 种设计模式做全面的阐述,此处读者可将它作为一个理论基础去学习,通过这四篇博文,先基本有个概念,虽然我讲的有些简单,但基本都能说明问题及他们的特点,如果对哪一个感兴趣,可以继续深入研究!同时我也会不断更新,尽量补全遗漏、修正不足,欢迎广大读者及时提出好的建议,我们一起学习!项目中涉及到的代码,已经放到了我的资源里:http://download.csdn.net/detail/zhangerqing/4835830(因为我不喜欢不劳而获,所以没有免积分,只设置了 5 个,如果有人实在没积分又急要,那么联系我吧,我给你发过去)。

在阅读的过程中,有任何问题,请联系:egg。

邮箱:xtfggef@gmail.com   微博:http://weibo.com/xtfggef

更多 2
  • 上一篇:Java 之美 [从菜鸟到高手演变] 之设计模式三
  • 下一篇:Java 之美 [从菜鸟到高手演变] 之 Exception
11
0
相关主题推荐
设计模式 java 正则表达式 web 框架 编译器
相关博文推荐
java 的 obcik 转航母
安装 JBPM6 运行环境(JBPM6 学习之...
要点 Java3 编译运行 Hello Wo...
url 传中文乱码
java (22) - 异常详解
创建第一个 JBPM6 项目并且运行自带的 h...
黑马程序员 ----IO 流
利用 Java 计算 String 的 MD5
查看评论
5 楼 zhuanyeying 2013-10-26 15:19 发表 [回复] [引用] [举报]
你好,想问下。这个中介者模式和代理模式应该是一样的模式?只不过您之前的代理模式的例子只持有了一个对象的引用,而这个中介者模式持有了两个对象的应用。
4 楼 java_ganbin 2013-06-21 16:38 发表 [回复] [引用] [举报]

Java 之设计模式四

Java 之设计模式四

其实每个设计模式都是很重要的一种思想,看上去很熟,其实是因为我们在学到的东西中都有涉及,尽管有时我们并不知道,其实在 Java 本身的设计之中处处都有体现,像 AWT、JDBC、集合类、IO 管道或者是 Web 框架,里面设计模式无处不在。因为我们篇幅有限,很难讲每一个设计模式都讲的很详细,不过我会尽我所能,尽量在有限的空间和篇幅内,把意思写清楚了,更好让大家明白。本章不出意外的话,应该是设计模式最后一讲了,首先还是上一下上篇开头的那个图:

本章讲讲第三类和第四类。

19、备忘录模式(Memento)

主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下:假设有原始类 A,A 中有各种属性,A 可以决定需要备份的属性,备忘录类 B 是用来存储 A 的一些内部状态,类 C 呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。做个图来分析一下:

Original 类是原始类,里面有需要保存的属性 value 及创建一个备忘录类,用来保存 value 值。Memento 类是备忘录类,Storage 类是存储备忘录的类,持有 Memento 类的实例,该模式很好理解。直接看源码:

public class Original {  
      
    private String value;  
      
    public String getValue() {  
        return value;  
    }  
  
    public void setValue(String value) {  
        this.value = value;  
    }  
  
    public Original(String value) {  
        this.value = value;  
    }  
  
    public Memento createMemento(){  
        return new Memento(value);  
    }  
      
    public void restoreMemento(Memento memento){  
        this.value = memento.getValue();  
    }  
}  
public class Memento {  
      
    private String value;  
  
    public Memento(String value) {  
        this.value = value;  
    }  
  
    public String getValue() {  
        return value;  
    }  
  
    public void setValue(String value) {  
        this.value = value;  
    }  
} 
public class Storage {  
      
    private Memento memento;  
      
    public Storage(Memento memento) {  
        this.memento = memento;  
    }  
  
    public Memento getMemento() {  
        return memento;  
    }  
  
    public void setMemento(Memento memento) {  
        this.memento = memento;  
    }  
}  

测试类:

public class Test {  
  
    public static void main(String[] args) {  
          
        // 创建原始类  
        Original origi = new Original("egg");  
  
        // 创建备忘录  
        Storage storage = new Storage(origi.createMemento());  
  
        // 修改原始类的状态  
        System.out.println("初始化状态为:" + origi.getValue());  
        origi.setValue("niu");  
        System.out.println("修改后的状态为:" + origi.getValue());  
  
        // 回复原始类的状态  
        origi.restoreMemento(storage.getMemento());  
        System.out.println("恢复后的状态为:" + origi.getValue());  
    }  
} 

输出:

初始化状态为:egg
修改后的状态为:niu
恢复后的状态为:egg

简单描述下:新建原始类时,value 被初始化为 egg,后经过修改,将 value 的值置为 niu,最后倒数第二行进行恢复状态,结果成功恢复了。其实我觉得这个模式叫 “备份 - 恢复” 模式最形象。

20、状态模式(State)

核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿 QQ 来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:1、可以通过改变状态来获得不同的行为。2、你的好友能同时看到你的变化。看图:

State 类是个状态类,Context 类可以实现切换,我们来看看代码:

package com.xtfggef.dp.state;  
  
/** 
 * 状态类的核心类 
 * 2012-12-1 
 * @author erqing 
 * 
 */  
public class State {  
      
    private String value;  
      
    public String getValue() {  
        return value;  
    }  
  
    public void setValue(String value) {  
        this.value = value;  
    }  
  
    public void method1(){  
        System.out.println("execute the first opt!");  
    }  
      
    public void method2(){  
        System.out.println("execute the second opt!");  
    }  
}  
package com.xtfggef.dp.state;  
  
/** 
 * 状态模式的切换类   2012-12-1 
 * @author erqing 
 *  
 */  
public class Context {  
  
    private State state;  
  
    public Context(State state) {  
        this.state = state;  
    }  
  
    public State getState() {  
        return state;  
    }  
  
    public void setState(State state) {  
        this.state = state;  
    }  
  
    public void method() {  
        if (state.getValue().equals("state1")) {  
            state.method1();  
        } else if (state.getValue().equals("state2")) {  
            state.method2();  
        }  
    }  
}  

测试类:

public class Test {  
  
    public static void main(String[] args) {  
          
        State state = new State();  
        Context context = new Context(state);  
          
        //设置第一种状态  
        state.setValue("state1");  
        context.method();  
          
        //设置第二种状态  
        state.setValue("state2");  
        context.method();  
    }  
}  

输出:

execute the first opt!
execute the second opt!

根据这个特性,状态模式在日常开发中用的挺多的,尤其是做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。
21、访问者模式(Visitor)

访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。—— From 百科

简单来说,访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。简单关系图:

来看看原码:一个 Visitor 类,存放要访问的对象,

public interface Visitor {  
    public void visit(Subject sub);  
}  
public class MyVisitor implements Visitor {  
  
    @Override  
    public void visit(Subject sub) {  
        System.out.println("visit the subject:"+sub.getSubject());  
    }  
}  

Subject 类,accept 方法,接受将要访问它的对象,getSubject () 获取将要被访问的属性,

public interface Subject {  
    public void accept(Visitor visitor);  
    public String getSubject();  
} 
public class MySubject implements Subject {  
  
    @Override  
    public void accept(Visitor visitor) {  
        visitor.visit(this);  
    }  
  
    @Override  
    public String getSubject() {  
        return "love";  
    }  
}  

测试:

public class Test {  
  
    public static void main(String[] args) {  
          
        Visitor visitor = new MyVisitor();  
        Subject sub = new MySubject();  
        sub.accept(visitor);      
    }  
}  

输出:visit the subject:love

该模式适用场景:如果我们想为一个现有的类增加新功能,不得不考虑几个事情:1、新功能会不会与现有功能出现兼容性问题?2、以后会不会再需要添加?3、如果类不允许修改代码怎么办?面对这些问题,最好的解决方法就是使用访问者模式,访问者模式适用于数据结构相对稳定的系统,把数据结构和算法解耦,
22、中介者模式(Mediator)

中介者模式也是用来降低类类之间的耦合的,因为如果类类之间有依赖关系的话,不利于功能的拓展和维护,因为只要修改一个对象,其它关联的对象都得进行修改。如果使用中介者模式,只需关心和 Mediator 类的关系,具体类类之间的关系及调度交给 Mediator 就行,这有点像 spring 容器的作用。先看看图:

User 类统一接口,User1 和 User2 分别是不同的对象,二者之间有关联,如果不采用中介者模式,则需要二者相互持有引用,这样二者的耦合度很高,为了解耦,引入了 Mediator 类,提供统一接口,MyMediator 为其实现类,里面持有 User1 和 User2 的实例,用来实现对 User1 和 User2 的控制。这样 User1 和 User2 两个对象相互独立,他们只需要保持好和 Mediator 之间的关系就行,剩下的全由 MyMediator 类来维护!基本实现:

public interface Mediator {  
    public void createMediator();  
    public void workAll();  
} 
public class MyMediator implements Mediator {  
  
    private User user1;  
    private User user2;  
      
    public User getUser1() {  
        return user1;  
    }  
  
    public User getUser2() {  
        return user2;  
    }  
  
    @Override  
    public void createMediator() {  
        user1 = new User1(this);  
        user2 = new User2(this);  
    }  
  
    @Override  
    public void workAll() {  
        user1.work();  
        user2.work();  
    }  
}  
public abstract class User {  
      
    private Mediator mediator;  
      
    public Mediator getMediator(){  
        return mediator;  
    }  
      
    public User(Mediator mediator) {  
        this.mediator = mediator;  
    }  
  
    public abstract void work();  
}  
public class User1 extends User {  
  
    public User1(Mediator mediator){  
        super(mediator);  
    }  
      
    @Override  
    public void work() {  
        System.out.println("user1 exe!");  
    }  
}  
public class User2 extends User {  
  
    public User2(Mediator mediator){  
        super(mediator);  
    }  
      
    @Override  
    public void work() {  
        System.out.println("user2 exe!");  
    }  
} 

测试类:

public class Test {  
  
    public static void main(String[] args) {  
        Mediator mediator = new MyMediator();  
        mediator.createMediator();  
        mediator.workAll();  
    }  
}  

输出:

user1 exe!
user2 exe!
23、解释器模式(Interpreter)
解释器模式是我们暂时的最后一讲,一般主要应用在 OOP 开发中的编译器的开发中,所以适用面比较窄。

Context 类是一个上下文环境类,Plus 和 Minus 分别是用来计算的实现,代码如下:

public interface Expression {  
    public int interpret(Context context);  
}  
public class Plus implements Expression {  
  
    @Override  
    public int interpret(Context context) {  
        return context.getNum1()+context.getNum2();  
    }  
}  
public class Minus implements Expression {  
  
    @Override  
    public int interpret(Context context) {  
        return context.getNum1()-context.getNum2();  
    }  
}  
public class Context {  
      
    private int num1;  
    private int num2;  
      
    public Context(int num1, int num2) {  
        this.num1 = num1;  
        this.num2 = num2;  
    }  
      
    public int getNum1() {  
        return num1;  
    }  
    public void setNum1(int num1) {  
        this.num1 = num1;  
    }  
    public int getNum2() {  
        return num2;  
    }  
    public void setNum2(int num2) {  
        this.num2 = num2;  
    }  
      
      
}  
public class Test {  
  
    public static void main(String[] args) {  
  
        // 计算9+2-8的值  
        int result = new Minus().interpret((new Context(new Plus()  
                .interpret(new Context(9, 2)), 8)));  
        System.out.println(result);  
    }  
}  

最后输出正确的结果:3。

基本就这样,解释器模式用来做各种各样的解释器,如正则表达式等的解释器等等!
 

设计模式基本就这么大概讲完了,总体感觉有点简略,的确,这么点儿篇幅,不足以对整个 23 种设计模式做全面的阐述,此处读者可将它作为一个理论基础去学习,通过这四篇博文,先基本有个概念,虽然我讲的有些简单,但基本都能说明问题及他们的特点,如果对哪一个感兴趣,可以继续深入研究!同时我也会不断更新,尽量补全遗漏、修正不足,欢迎广大读者及时提出好的建议,我们一起学习!

今天关于JS 设计模式四 -- 模块模式js模块化原理及实现过程的分享就到这里,希望大家有所收获,若想了解更多关于2018.3.18 设计模式 -- 常用设计模式和设计模式的六大原则汇总、iOS设计模式--备忘录设计模式与命令设计模式、Java 之美 [从菜鸟到高手演变] 之设计模式四、Java 之设计模式四等相关知识,可以在本站进行查询。

本文标签: