4.建造者模式
建造者模式和抽象工厂模式很相似,如果抽象工厂模式时一个汽车配件生产厂,那么建造者模式就是一个汽车组装厂,通过对配件的组装,返回一台完整的汽车。
4.1.实例说明
某游戏软件中人物角色包括多种不同类型,不同类型的人物角色,其性别,脸型,服装,发型等外部特性都有差异,使用建造者模式创建人物角色对象。
4.2.实例类图

4.3.实例代码
package com.ljessie.designpattern.creational.builder;
public class Actor {
private String type;
private String sex;
private String face;
private String costume;
private String hairStyle;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getCostume() {
return costume;
}
public void setCostume(String costume) {
this.costume = costume;
}
public String getHairStyle() {
return hairStyle;
}
public void setHairStyle(String hairStyle) {
this.hairStyle = hairStyle;
}
}
package com.ljessie.designpattern.creational.builder;
public abstract class ActorBuilder {
protected Actor actor = new Actor();
public abstract void buildType();
public abstract void buildSex();
public abstract void buildFace();
public abstract void buildcostume();
public abstract void buildHairStyle();
public Actor createActor(){
return actor;
}
}
package com.ljessie.designpattern.creational.builder;
public class HeroBuilder extends ActorBuilder {
@Override
public void buildType() {
actor.setType("英雄");
}
@Override
public void buildSex() {
actor.setSex("男");
}
@Override
public void buildFace() {
actor.setFace("英俊");
}
@Override
public void buildcostume() {
actor.setCostume("盔甲");
}
@Override
public void buildHairStyle() {
actor.setHairStyle("飘逸");
}
}
package com.ljessie.designpattern.creational.builder;
public class AngelBuilder extends ActorBuilder {
@Override
public void buildType() {
actor.setType("天使");
}
@Override
public void buildSex() {
actor.setSex("女");
}
@Override
public void buildFace() {
actor.setFace("漂亮");
}
@Override
public void buildcostume() {
actor.setCostume("白裙");
}
@Override
public void buildHairStyle() {
actor.setHairStyle("齐腰长发");
}
}
package com.ljessie.designpattern.creational.builder;
public class ActorController {
public Actor construct(ActorBuilder builder){
builder.buildSex();
builder.buildcostume();
builder.buildFace();
builder.buildHairStyle();
builder.buildType();
return builder.createActor();
}
}
package com.ljessie.designpattern.creational.builder;
public class Test {
public static void main(String[] args) {
ActorController controller = new ActorController();
ActorBuilder builder = new HeroBuilder();
Actor actor = controller.construct(builder);
System.out.println("type:"+actor.getType());
System.out.println("sex:"+actor.getSex());
System.out.println("costume:"+actor.getCostume());
System.out.println("face:"+actor.getFace());
System.out.println("hairType:"+actor.getHairStyle());
}
}
运行结果:
type:英雄
sex:男
costume:盔甲
face:英俊
hairType:飘逸
工厂模式是用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。建造者模式是用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”地创建不同的对象。
网上有一个经典的例子很好地解释了两者的区别。顾客走进一家餐馆点餐,我们利用工厂模式,根据用户不同的选择,来制作不同的食物,比如披萨、汉堡、沙拉。对于披萨来说,用户又有各种配料可以定制,比如奶酪、西红柿、起司,我们通过建造者模式根据用户选择的不同配料来制作披萨。
5.原型模式
5.1.实例说明
在某OA系统中,用户可以创建工作周报,由于某些岗位每周工作存在重复性,因此可以通过复制原有工作周报,并进行局部修改来快速新建工作周报。现使用原型模式来实现该功能。
5.2.实例类图

5.3.实例代码
package com.ljessie.designpattern.creational.prototype;
public class WeeklyLog implements Cloneable {
private String name;
private String date;
private String content;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Object clone(){
try {
Object obj = super.clone();
return obj;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
package com.ljessie.designpattern.creational.prototype;
public class Test {
public static void main(String[] args) {
WeeklyLog log_previous = new WeeklyLog();
log_previous.setName("张三");
log_previous.setDate("第12周");
log_previous.setContent("每天加班");
System.out.println(log_previous.getName());
System.out.println(log_previous.getDate());
System.out.println(log_previous.getContent());
System.out.println("---------------------------");
WeeklyLog log_current = (WeeklyLog) log_previous.clone();
log_current.setDate("第13周");
System.out.println(log_current.getName());
System.out.println(log_current.getDate());
System.out.println(log_current.getContent());
}
}
运行结果:
张三
第12周
每天加班
---------------------------
张三
第13周
每天加班
原型模式有两种实现方法,深拷贝和浅拷贝。浅拷贝只会复制对象中基本数据类型数据和引用对象的内存地址,不会递归地复制引用对象,以及引用对象的引用对象……而深拷贝得到的是一份完完全全独立的对象。所以,深拷贝比起浅拷贝来说,更加耗时,更加耗内存空间。
深拷贝实现:先将对象序列化,然后再反序列化成新的对象。对象要实现Serializable接口
public Object deepCopy(Object object){
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = null;
Object result = null;
try {
oo = new ObjectOutputStream(bo);
oo.writeObject(object);
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
result= oi.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return result;
}
6.单例模式
单例设计模式(Singleton Design Pattern)理解起来非常简单。一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。
6.1懒加载: 在需要的时候,才会进行实例化。
package com.ljessie.designpattern.creational.singleton;
/**
* 懒汉式单例
* 在需要的时候,才会进行实例化
* @author zbw
*
*/
public class LazySingleton {
//volatile防止JVM指令重排序
private static volatile LazySingleton lazySingleton = null;
private LazySingleton() {
}
/**
* 非线性安全的,加上synchronized
* 若加到方法上,太消耗性能
* @return
*/
public static LazySingleton getInstance() {
if(lazySingleton == null) {
synchronized (LazySingleton.class) {
if(lazySingleton == null) {
lazySingleton = new LazySingleton();
}
}
}
return lazySingleton;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread() {
@Override
public void run() {
System.out.println(LazySingleton.getInstance());
}
}.start();
}
}
}
6.2饿汉:在类加载的时候,就已经实例化。
package com.ljessie.designpattern.creational.singleton;
/**
* 饿汉式单例,在类加载的时候,就已经实例化。
* @author zbw
*
*/
public class HungerSingleton {
private static HungerSingleton hungerSingleton = new HungerSingleton();
public static HungerSingleton getInstance() {
return hungerSingleton;
}
private HungerSingleton() {
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread() {
@Override
public void run() {
System.out.println(HungerSingleton.getInstance());
}
}.start();
}
}
}
网友评论