理解软件设计模式( 二 )


文章插图
Normal class instantiation
 
下面这幅图使用单例模式创建对象 。这里,构造函数仅当对象首次通过调用预先设计好的 getInstance() 方法时才会被调用 。这通常通过检查该值是否为 null 来完成,并且这个对象被作为私有变量保存在单例类的内部 。下次 getInstance() 被调用时,这个类会返回第一次被创建的对象 。而没有新的对象产生;它只是返回旧的那一个 。
 

理解软件设计模式

文章插图
Singleton pattern instantiation
 
下面这段代码展示了创建单例模式最简单的方法:
package org.opensource.demo.singleton;public class OpensourceSingleton { private static OpensourceSingleton uniqueInstance; private OpensourceSingleton() { } public static OpensourceSingleton getInstance() { if (uniqueInstance == null) { uniqueInstance = new OpensourceSingleton(); } return uniqueInstance; }}在调用方,这里展示了如何调用单例类来获取对象:
Opensource newObject = Opensource.getInstance();这段代码很好的验证了单例模式的思想:
  1. 当 getInstance() 被调用时,它通过检查 null 值来检查对象是否已经被创建 。
  2. 如果值为 null,它会创建一个新对象并把它保存到私有域,返回这个对象给调用者 。否则直接返回之前被创建的对象 。
单例模式实现的主要问题是它忽略了并行进程 。当多个进程使用线程同时访问资源时,这个问题就产生了 。对于这种情况有对应的解决方案,它被称为双重检查锁,用于多线程安全,如下所示:
package org.opensource.demo.singleton;public class ImprovedOpensourceSingleton { private volatile static ImprovedOpensourceSingleton uniqueInstance; private ImprovedOpensourceSingleton() {} public static ImprovedOpensourceSingleton getInstance() { if (uniqueInstance == null) { synchronized (ImprovedOpensourceSingleton.class) { if (uniqueInstance == null) { uniqueInstance = new ImprovedOpensourceSingleton(); } } } return uniqueInstance; }}再强调一下前面的观点,确保只有在你认为这是一个安全的选择时才直接实现你的单例模式 。最好的方法是通过使用一个制作精良的编程框架来利用单例功能 。
工厂模式:将对象创建委派给工厂类以隐藏创建逻辑工厂模式 (factory pattern)是另一种众所周知的设计模式,但是有一小点复杂 。实现工厂模式的方法有很多,而下列的代码示例为最简单的实现方式 。为了创建对象,工厂模式定义了一个接口,让它的子类去决定实例化哪一个类 。
工厂模式:将对象创建委派给工厂类,因此它能隐藏创建逻辑 。
下列的图片展示了最简单的工厂模式是如何实现的 。
 
理解软件设计模式

文章插图
Factory pattern
 
客户端请求工厂类创建类型为 x 的某个对象,而不是客户端直接调用对象创建 。根据其类型,工厂模式决定要创建和返回的对象 。
在下列代码示例中,OpensourceFactory 是工厂类实现,它从调用者那里获取类型并根据该输入值决定要创建和返回的对象:
package org.opensource.demo.factory;public class OpensourceFactory { public OpensourceJVMServers getServerByVendor([String][18] name) { if(name.equals("Apache")) { return new Tomcat(); } else if(name.equals("Eclipse")) { return new Jetty(); } else if (name.equals("RedHat")) { return new WildFly(); } else { return null; } }}OpenSourceJVMServer 是一个 100% 的抽象类(即接口类),它指示要实现的是什么,而不是怎样实现:
package org.opensource.demo.factory;public interface OpensourceJVMServers { public void startServer(); public void stopServer(); public [String][18] getName();}这是一个 OpensourceJVMServers 类的实现示例 。当 RedHat 被作为类型传递给工厂类,WildFly 服务器将被创建:
package org.opensource.demo.factory;public class WildFly implements OpensourceJVMServers { public void startServer() { [System][19].out.println("Starting WildFly Server..."); } public void stopServer() { [System][19].out.println("Shutting Down WildFly Server..."); } public [String][18] getName() { return "WildFly"; }}观察者模式:订阅主题并获取相关更新的通知最后是 观察者模式 (observer pattern) 。像单例模式那样,很少有专业的程序员直接实现观察者模式 。但是,许多消息队列和数据服务实现都借用了观察者模式的概念 。观察者模式在对象之间定义了一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将被自动地通知和更新 。


推荐阅读