重学java23种设计模式(4)原型模式

跟着《软件秘笈---设计模式那点事》学习

预热:JAVA深复制(深克隆)与浅复制(浅克隆) 

1.浅复制与深复制概念
⑴浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

⑵深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原对象。

2.Java的clone()方法
(1)clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
①对任何的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。

④如果自己创建,那必须是先cloneable接口。

(2)Java中对象的克隆

①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。



定义:

原型模式(Prototype Pattren),用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。


角色:

(1)原型类

(2)生产原型的工厂(抽象)

(3)原型工厂实现类

(4)客户端


类图:



实例:

pojo类

package com.prototype.pojo;

public class DayLife implements Cloneable {
	// 起床
	private String getUp;
	// 坐公交
	private String byBus;
	// 下车,买早餐
	private String getFood;
	// 中午小憩
	private String noon;
	// 下午开始工作
	private String afternoonWork;
	// 下班回家
	private String goHome;
	// 晚上休闲
	private String night;

	public String getGetUp() {
		return getUp;
	}

	public void setGetUp(String getUp) {
		this.getUp = getUp;
	}

	public String getByBus() {
		return byBus;
	}

	public void setByBus(String byBus) {
		this.byBus = byBus;
	}

	public String getGetFood() {
		return getFood;
	}

	public void setGetFood(String getFood) {
		this.getFood = getFood;
	}

	public String getNoon() {
		return noon;
	}

	public void setNoon(String noon) {
		this.noon = noon;
	}

	public String getAfternoonWork() {
		return afternoonWork;
	}

	public void setAfternoonWork(String afternoonWork) {
		this.afternoonWork = afternoonWork;
	}

	public String getGoHome() {
		return goHome;
	}

	public void setGoHome(String goHome) {
		this.goHome = goHome;
	}

	public String getNight() {
		return night;
	}

	public void setNight(String night) {
		this.night = night;
	}

	public void print() {
		System.out.println(this.getGetUp());
		System.out.println(this.getByBus());
		System.out.println(this.getGetFood());
		System.out.println(this.getNoon());
		System.out.println(this.getAfternoonWork());
		System.out.println(this.getGoHome());
		System.out.println(this.getNight());
	}

	@Override
	public DayLife clone(){
		try {
			return (DayLife)super.clone();//这是Object的方法
		} catch (Exception e) {
		}
		return null;
	}
	
}

抽闲原型工厂

public interface ILifeFactory {
	public DayLife getNewIntance();
}


原型工厂实现

public class LifeFactoryImpl implements ILifeFactory {
	//DayLife对象实例用于初始化
	private static DayLife dayLife = null;

	@Override
	public DayLife getNewIntance() {
		if(dayLife == null){
			System.out.println("----New DayLife----");
			dayLife = new DayLife();
			dayLife.setGetUp("7:00起床");
			dayLife.setByBus("7:30坐公交");
			dayLife.setGetFood("8:30到公司");
			dayLife.setNoon("11:45吃午饭,吃完小憩");
			dayLife.setAfternoonWork("13:30开始下午的工作");
			dayLife.setGoHome("17:45准时下班");
			dayLife.setNight("晚上休闲娱乐");
		}else{
			System.out.println("+++Clone DayLife++++");
			dayLife = dayLife.clone();
		}
		return dayLife;
	}

}

客户端

public class Client {
	public static void main(String[] args) {
		//创建工厂
		ILifeFactory lifeFactory = new LifeFactoryImpl();
		//打印输出DayLife默认内容
		lifeFactory.getNewIntance().print();
		//再次获得DayLife,修改getUp内容后,输出内容
		System.out.println("------------------------------------------------------------");
		DayLife dayLife = lifeFactory.getNewIntance();
		dayLife.setGetUp("早上懒床了,7:15才起床!!!!");
		dayLife.print();
		//再次获得DayLife,修改getUp内容后,输出内容
		System.out.println("------------------------------------------------------------");
		DayLife dayLife2 = lifeFactory.getNewIntance();
		dayLife2.setGetUp("早上懒床了,7:30才起床!!!!");
		dayLife2.print();
	}
}


分析:

原型方法的核心是clone方法,通过这个方法进行对象的复制,

1:克隆对象时对象的构造方法不执行

2:深复制和浅复制

上面这个例子的核心是clone方法,而clone方法是浅复制。如果要深复制,那需要把持有的对象也clone,上面引子里说的很清楚,这里不赘述了。



使用场合:

(1)产生对象过程比较复杂,初始化需要很多资源时。

(2)希望框架原型和产生对象分开时。

(3)同一个对象可能会供其他调用者同事访问时。


一句话总结:

通过Object的Clone方法,创建对象。


Java SDK中的原型模式

实现Cloneable接口


参考资料:

《软件秘笈---设计模式那点事》

http://www.cnblogs.com/yxnchinahlj/archive/2010/09/20/1831615.html




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值