- 创建型设计模式
1. Singleton,单例模式。确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
public class Singleton { private static Singleton instance = null; private Singleton() { // do something } public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2. Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
// 抽象工厂 public interface Creator { public ProductA factoryA(); public ProductB factoryB(); } // 具体工厂1 public class ConcreteCreator1 implements Creator { @Override public ProductA factoryA() { return new ProductA1(); } @Override public ProductB factoryB() { return new ProductB1(); } } // 具体工厂2 public class ConcreteCreator2 implements Creator { @Override public ProductA factoryA() { return new ProductA2(); } @Override public ProductB factoryB() { return new ProductB2(); } }
// 抽象产品ProductA public interface ProductA { } // 具体产品ProductA1 public class ProductA1 implements ProductA { } // 具体产品ProductA2 public class ProductA2 implements ProductA { }
// 抽象产品ProductB public interface ProductB { } //具体产品ProductB1 public class ProductB1 implements ProductB { } //具体产品ProductB2 public class ProductB2 implements ProductB { }
3. Factory,工厂模式:相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A();工厂模式也是用来创建实例对象的。
我们以类Sample为例, 如果我们要创建Sample的实例对象。
Sample sample=new Sample();
可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如赋值、查询数据库等。
首先,我们想到的是,可以使用Sample的构造函数,这样生成实例就写成:
Sample sample=new Sample(参数);
但是,创建sample实例时所做的初始化工作可能不是像赋值这样简单的事,而是很长一段代码。
在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开,也就是说,让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。
public class Factory { public static Sample creator(int which) { if (which == 1) return new SampleA(); else if (which == 2) return new SampleB(); else return new Sample0(); } } interface Sample { } class Sample0 implements Sample { } class SampleA implements Sample { } class SampleB implements Sample { }
那么在你的程序中,如果要实例化Sample时,就使用
Sample sampleA=Factory.creator(1);
这样,在整个就不涉及到Sample的具体子类,达到封装效果,也就减少错误修改的机会,这个原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易范错误。这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,犯错误可能性就越少。
4. Builder,建造模式。将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
实用范围:
(1)当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
(2)当构造过程必须允许被构造的对象有不同表示时。
在这样的设计模式中,有以下几个角色:
(1)builder:为创建一个产品对象的各个部件指定抽象接口。
public interface PersonBuilder { void buildHead(); void buildBody(); void buildFoot(); Person buildPerson(); }
(2)ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
public class ManBuilder implements PersonBuilder { Person person; public ManBuilder() { person = new Man(); } @Override public void buildHead() { person.setHead("建造男人的头"); } @Override public void buildBody() { person.setBody("建造男人的身体"); } @Override public void buildFoot() { person.setFoot("建造男人的脚"); } @Override public Person buildPerson() { return person; } }
(3)Director:构造一个使用Builder接口的对象。
public class PersonDirector { public Person constructPerson(PersonBuilder pb) { pb.buildHead(); pb.buildBody(); pb.buildFoot(); return pb.buildPerson(); } }
(4)Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
public class Person { private String head; private String body; private String foot; public String getHead() { return head; } public void setHead(String head) { this.head = head; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getFoot() { return foot; } public void setFoot(String foot) { this.foot = foot; } } public class Man extends Person { }
(5)主方法
public class Test { public static void main(String[] args) { PersonDirector pd = new PersonDirector(); Person person = pd.constructPerson(new ManBuilder()); System.out.println(person.getBody()); System.out.println(person.getFoot()); System.out.println(person.getHead()); } }
5. Prototype,原型模式。用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
Prototype原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
它主要面对的问题是:“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。
public abstract class AbstractSpoon implements Cloneable { String spoonName; public void setSpoonName(String spoonName) { this.spoonName = spoonName; } public String getSpoonName() { return this.spoonName; } public Object clone() { Object object = null; try { object = super.clone(); } catch (CloneNotSupportedException exception) { System.err.println("AbstractSpoon is not Cloneable"); } return object; } } public class SaladSpoon extends AbstractSpoon { public SaladSpoon() { setSpoonName("Salad Spoon"); } } public class SoupSpoon extends AbstractSpoon { public SoupSpoon() { setSpoonName("Soup Spoon"); } }