创建型设计模式有5种,它们是单例模式,工厂方法,抽象工厂,原型模式和建造者模式,其中原型模式是依靠clone()方法复制产生对象,而其他模式是用new产生对象。
1.单例模式
一个类只能有一个实例,这就是单例模式。使用单例,必须要隐藏构造器,将它的修饰符改为private。可以用:public static final single=new Object()。也可以用下面的例子:
public class Singleton {
private static Singleton sing;
private Singleton() {
}
public static Singleton getInstance() {
if (sing == null) {
sing = new Singleton();
}
return sing;
}
}
public class Test {
public static void main(String[] args) {
Singleton sing = Singleton.getInstance();
Singleton sing2 = Singleton.getInstance();
System.out.println(sing);
System.out.println(sing2);
}
}
结果: 两个结果是一样的,只有一个对象。
singleton.Singleton@1c78e57
singleton.Singleton@1c78e57
2 简单工厂 工厂方法 抽象工厂
定义:
简单工厂:简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。不修改代码的话,是无法扩展的。
工厂模式:定义一个用于创建对象的借口,让子类决定实例化哪一个类。
抽象工厂模式:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
简单工厂就是一个静态方法,里面运用逻辑判断你要生产的产品,直接返回产品实例。如果要增加某种产品,则必须修改工厂类。下面主要谈谈工厂方法和抽象工厂。
工厂方法:有一个抽象工厂,它是接口,有几个它的实现类,每一个类是个具体的工厂,生产某一种产品。这个实际就是面向对象编程中多态的运用。它的适用性如下:
适用性:1.当一个类不知道它所必须创建的对象的类的时候。 2.当一个类希望由它的子类来指定它所创建的对象的时候。 3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
工厂方法的UML图如下
抽象工厂是应对产品族概念的。就是按产品的功能来区分,不再是一个具体工厂生产一个产品,而是一个具体工厂生产某一些产品,,这些产品都有相似性。它的适应性:
1.一个系统要独立于它的产品的创建、组合和表示时。 2.一个系统要由多个产品系列中的一个来配置时。 3.当你要强调一系列相关的产品对象的设计以便进行联合使用时。 4.当你提供一个产品类库,而只想显示它们的接口而不是实现时。UML图如下:
再给一个抽象工厂的类图:
三种方法的区别:
简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品(某一种产品),无能为力;支持增加产品族(某一类全部产品))
四.原型模式
原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对象的副本。java的object有clone方法,任何一个需要被克隆的类需要实现Cloneable接口,它就包含clone方法。
这里要注意“深复制”和“浅复制”的区别(又称深拷贝和浅拷贝),这里的区别就如“值传递”和“引用传递”。深复制是完完全全的克隆了两个对象,包括对象的引用和它所指向的真实对象,而浅复制只拷贝了对象的引用,复制的引用还是指向原来的对象。也只有8种基本类型是深复制,其他都是浅复制。要想让对象具有深复制,需要自己实现clone方法。像ArrayList已经实现了clone方法。例子如下:
原型类:
public class Prototype implements Cloneable {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public Object clone(){
try {
return super.clone();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
ConcretePrototype //继承原型的具体类,也可以直接用原型类
public class ConcretePrototype extends Prototype {
public ConcretePrototype(String name) {
setName(name);
}
}
Client
public class Test {
public static void main(String[] args) {
Prototype pro = new ConcretePrototype("prototype");
Prototype pro2 = (Prototype)pro.clone(); //复制对象
System.out.println(pro.getName());
System.out.println(pro2.getName());
}
}
结果如下:
prototype 两个是一样的
prototype
五.建造者模式
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。就是将一个对象的模式固定住,但是又可以有不同的内容。这里要用到多态。
适用性:1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。2.当构造过程必须允许被构造的对象有不同的表示时。
例子如下
Builder
public interface PersonBuilder {
void buildHead();
void buildBody();
void buildFoot();
Person buildPerson();
}
ConcreteBuilder
public class ManBuilder implements PersonBuilder {
Person person;
public ManBuilder() {
person = new Man();
}
public void buildBody() {
person.setBody("建造男人的身体");
}
public void buildFoot() {
person.setFoot("建造男人的脚");
}
public void buildHead() {
person.setHead("建造男人的头");
}
public Person buildPerson() {
return person;
}
}
Director
public class PersonDirector {
//建造者,这里已经将模式固定,就是要一步一步来,也可以生产女人,生产儿童等等。具体产生的内容不同
public Person constructPerson(PersonBuilder pb) {
pb.buildHead();
pb.buildBody();
pb.buildFoot();
return pb.buildPerson();
}
}
Product
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 {
}
Test
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());
}
}
结果:
建造男人的身体
建造男人的脚
建造男人的头
生产者消费者模式:
它不是创建型设计模式,但是也是一种很重要的模式,这里介绍一下概念。
在计算机科学中,我们将生产者消费者问题描述为:
一群生产者在生产消息,并将此消息提供给消费者去消费。它们中间设了具有N个缓存区的缓冲池,生产者每次可将生产的消息放入一个缓存区内,消费者每次可将一个缓存区内的消息拿出来消费。但这个过程有两个条件:任何一方操作一个缓冲区时不能有其它同时对该缓冲区进行操作;只有当缓冲区还有空余,生产者才能生产,只有当缓冲区至少有一个产品,消费者才能从中取出来消费。这里两个条件分别对应了互斥和同步。
http://blog.csdn.net/hsuxu/article/details/9467651
http://blog.csdn.net/hsuxu/article/details/9467651
http://ifeve.com/atomic-operation/