葫芦娃,葫芦娃, 一根藤上七朵花。风吹雨打,都不怕,啦啦啦啦。 叮当当咚咚当当,葫芦娃,叮当当咚咚当当,本领大,啦啦啦啦。 葫芦娃,葫芦娃,本领大。
从葫芦娃引申开来,这篇文章主要讲讲java设计模式之原型模式
定义:用原型的实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
原型模式是一种比较特殊的设计模式,通过克隆一个对象快速的创建一个新的对象,然后使用这个对象完成一些对象的操作,不需要通过new操作。
类图如下:
下面我们还是用例子来阐述这个模式,就用葫芦娃七兄弟的故事吧,大家都知道葫芦娃是葫芦里面长出来的,我们这里把这个故事背景做个修改,当初宇宙混沌一片,女娲抟土造人,她费劲了很大的力气才把大娃造出来,消耗了她很大的时间力气,剩下的六个如果一个个的重新设计制造,又得花费很大的精力,这时候我们的原型模式横空出世,利用巧妙的设计,一举帮助女娲搞定了这个难题。
public class BigBrother implements Cloneable //类只有实现了这个接口才会被虚拟机认为是能够克隆的
{
private String name;//姓名
private String speciality;//特长
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSpeciality() {
return speciality;
}
public void setSpeciality(String speciality) {
this.speciality = speciality;
}
public void print()
{
System.out.println(this.getName());
System.out.println(this.getSpeciality());
}
//克隆方法,关键所在,调用超类的方法,这个地方的超类就是Object类
@Override
public BigBrother clone()
{
try
{
return (BigBrother)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
/**
* @author Administrator
* 造人工厂类
*/
public interface ILifeFactory {
public BigBrother getNewInstance();
}
/**
* @author Administrator
* 造人工厂类
*/
public class LifeFactory implements ILifeFactory{
private static BigBrother cloneBigone=null;
public BigBrother getNewInstance()
{
if(cloneBigone==null)
{
System.out.println("天地混沌一片,女娲开始抟土造人");
cloneBigone=new BigBrother();
cloneBigone.setName("大娃");
cloneBigone.setSpeciality("大娃能喷火");
}else
{ //大娃已经诞生了,这时候调用克隆方法来客隆下一个葫芦娃
System.out.println("接下来,见证奇迹的时刻,这是用克隆的新技术来造的");
cloneBigone=cloneBigone.clone();
}
return cloneBigone;
}
}
//女娲类
public class Goodness {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//默认先把大娃造出来
ILifeFactory factory=new LifeFactory();
factory.getNewInstance().print();
//开始造二娃了,没有用new ,这是关键
BigBrother twoOne=factory.getNewInstance();
twoOne.setName("二娃");
twoOne.setSpeciality("二娃可以喷水");
twoOne.print();
//开始造二娃了,没有用new ,这是关键
BigBrother threeOne=factory.getNewInstance();
threeOne.setName("三娃");
threeOne.setSpeciality("三娃千里眼");
threeOne.print();
}
}
运行结果如下:从此之后,维护世界和平就靠你们了
总结:
原型模式允许在运行时动态改变具体的实现类型。原型模式可以在运行期间,由客户来注册符合原型接口的实现类型,也可以动态地改变具体的实现类型,看起来接口没有任何变化,但其实运行的已经是另外一个类实例了。因为克隆一个原型就类似于实例化一个类。
原型模式最主要的缺点是每一个类都必须配备一个克隆方法。配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类来说不是很难,而对于已经有的类不一定很容易,特别是当一个类引用不支持序列化的间接对象,或者引用含有循环结构的时候。