Factory模式与Prototype模式的异同

工厂模式实现的生产产品的功能,关键是利用了继承的特性。也就是说,你生成的产品,一定是由同一个抽象产品类派生出来的。所以,在工厂模式下,你如果要生成一类产品,就要引入一个抽像产品类,然后再由它派生出具体产品。同样,在原型模式中,你完全可以同样定义一个这样的“抽象产品--具体产品”层次,再利用具体产品本身的clone功能来产生具体产品本身。从而达到实现工厂模式功能的目的。可能说到这,大家有点糊涂了。实际上,在原型模式中,每个具体产品就扮演了工厂模式里的具体工厂的角色(为什么会这样,其实很简单,因为,每个具体产品都具有生成
自己拷贝的功能?从这种意义上讲,难道这不正是工厂的作用吗?)。另外,要在Java中利用原形模式实现工厂模式的功能,则更为简单,因为object已经为我们实现了clone函数,且对于clone方法,Java中默认是:如果A是父类且A实现了clone函数,B是A的子类,则B不用实现clone函数,它只要调用父类的clone函数,Java就会在运行时动态地为我们生成正确的B的对象。理解这点的关键在于,所有类实现的clone操作都是调用object的clone方法。这也就是说,我上面所说的父类A根本就不用自己实现clone方法,而仅仅是调用父类(object)的clone方法而已。好,到了这,读者也许又有疑问了,既然所有的cloen操作都是由object实现的,而在java中所有的自定义类默认都是由object派生而来,那这样的话,应该所有的类都自动就具有了clone自己的能力?
    确实,如果object不将它的clone函数声明为protect的话,情况的确如此。但Java为了安全方面的原因,所以没有将clone方法公开,而是声明为保护类型,这样的话,子类是不可以直接调用object类的clone方法的,而必须做到如下两点:
       1.必须实现Cloneable接口;
       2.必须声明一个clone方法,来调用object的clone函数;
       Java在调用父类的clone函数时,都会在运行时动态地进行检查,如果发现调用的类不符合上面的任何一点,则会抛出一个异常。
    明白了上面的原因,那么如果我们希望某个类具备clone自身的能力,那么,我们可以这样做:
       1.直接按上面所说,自己实现clone操作;
       2.声明一个抽象父类,实现上面的clone操作并将它声明为公开方法,再由此类派生出子类,这样,所有的  子类只要调用父类的clone方法,就能够正确地拷贝自己。
    通常,我们都是使用第一种方式,但在我们现在讨论的如何用原型模式实现工厂模式的功能的问题中,我们最好是采用第二种方式。
    最后,让我们通过具体的代码来看看如何用Prototype模式实现工厂模式的功能。

package prototype;
/**
 *************************************
  * @Title   Person.java
  * @Author  张作强
  * @Date    2010-8-11
  * @Comment 定义抽象类Person
 *************************************
 */
public abstract class Person implements Cloneable {
	public String Gender;

	public String getGender() {
		return Gender;
	}

	public void setGender(String gender) {
		Gender = gender;
	}

	public Object clone(){
		Object object = null ;
		try {
			object = super.clone();//调用父类,即Object的clone()
		} catch (CloneNotSupportedException exception) {
			System.err.println("Person is not Cloneable");
		}
		return object;
	}
}

 

 

package prototype;

public class Man extends Person {
	public Man(){
		setGender("男");
	}
}

 

 

package prototype;

public class Test {
	public static void main(String[] args) {
		try {
			Person pM = (Person)Class.forName("prototype.Man").newInstance();
			System.out.println("==================");
			System.out.println("** 显示中文性别:" + pM.getGender());
			pM.setGender("Man");
			System.out.println("** 显示英文性别:" + pM.getGender());
			
			System.out.println("==================");
			Person pW = (Person) pM.clone();
			pW.setGender("女");
			System.out.println("** 显示中文性别:" + pW.getGender());
			pW.setGender("Woman");
			System.out.println("** 显示英文性别:" + pW.getGender());
			System.out.println("==================");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值