前面提到抽象工厂的实现,这里说说抽象工厂的原型实现,与工厂方法的实现不同,原型实现有他自己的优点和缺点
原型的优点:
1. 效率:clone是native方法,比new的效率高,当使用复杂循环嵌套对象是尤为明显
2. 不需要为每一个新增的product创造一个具体factory
缺点:
1. 如果需要深复制,则需要手写所有包含循环引用对象的类的clone方法,因为需要手动在clone方法里对引用对象进行clone,否则是浅复制
2. 当需要改变一个克隆实例内部的值时,由于clone方法是无参方法,只能在clone完以后手动调用改变值得方法,且如果这个值是一个类的引用,则克隆应该建立在深复制的前提下,否则会污染原型数据
3. 原型工厂有可能被初始化成不兼容组件的组合,例如 CatHead和DogBody的组合,实际上这也是原型的一个灵活性的体现之一
4. 就Java而言,它的clone方法是protected方法,我们需要手动实现Clonable接口以后重写clone()方法将其改为public方法才能调用
下面是一个例子
工厂类,不在需要具体的工厂子类,而是通过构造方法设置原型来产生不同的工厂
package factory; import product.Body; import product.Eye; import product.Head; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:33 * To change this template use File | Settings | File Templates. */ public class ModuleFactory { private static ModuleFactory factory = new ModuleFactory(); private static Head _head; // 原型组件 private static Body _body; private static Object lockObj = new Object(); // 设置原型 public static ModuleFactory createFactory(Head newHead, Body newBody) { if (newHead == null || newBody == null) throw new RuntimeException("Param newHead and newBody cannot be null"); // 为简单起见,不考虑多线程问题,不使用延迟加载 _head = newHead; _body = newBody; return factory; } public Head createHead() throws CloneNotSupportedException { Head head = (Head) _head.clone(); return head; } // 重载方法 public Head createHead(Eye eye) throws CloneNotSupportedException { Head head = (Head) _head.clone(); // 必须在clone之后手动调用修改成员的方法 head.setEye(eye); return head; } public Body createBody() throws CloneNotSupportedException { return (Body) _body.clone(); } }
产品类
package product; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:24 * To change this template use File | Settings | File Templates. */ public abstract class Head implements Cloneable { private Eye eye = new Eye("defaultEye"); public Eye getEye() { return eye; } public void setEye(Eye eye) { this.eye = eye; } @Override public Object clone() throws CloneNotSupportedException { Head head = (Head) super.clone(); // 对内部对象进行深复制 head.setEye((Eye) eye.clone()); return head; } public abstract void eat(); } package product; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:29 * To change this template use File | Settings | File Templates. */ public class DogHead extends Head { @Override public void eat() { System.out.println("A dooog's head is eating with its eye " + getEye().getName()); } } package product; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:29 * To change this template use File | Settings | File Templates. */ public class CatHead extends Head { @Override public void eat() { System.out.println("A caaat's head is eating fast"); } } package product; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:48 * To change this template use File | Settings | File Templates. */ public class Eye implements Cloneable{ private String name; @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } public Eye(String name) { this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return name; } } package product; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:24 * To change this template use File | Settings | File Templates. */ public abstract class Body implements Cloneable { public abstract void dance(); // 此处必须将clone方法重新声明为public方法 @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } } package product; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:27 * To change this template use File | Settings | File Templates. */ public class CatBody extends Body { @Override public void dance() { System.out.println("A caaat's body is dancing crazily!!"); } } package product; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:27 * To change this template use File | Settings | File Templates. */ public class DogBody extends Body { @Override public void dance() { System.out.println("A dooog's body is dancing!"); } }
测试类
import factory.ModuleFactory; import product.*; /** * Created with IntelliJ IDEA. * User: zhenwei.liu * Date: 13-8-1 * Time: 上午12:35 * To change this template use File | Settings | File Templates. */ public class Test { // 通过原型工厂克隆得到新的实例 // 与具体实现无关的解耦代码 private static void act(ModuleFactory factory) throws CloneNotSupportedException { Head head = factory.createHead(); Body body = factory.createBody(); head.eat(); body.dance(); } public static void main(String[] args) throws CloneNotSupportedException { Head head = new DogHead(); head.getEye().setName("customEye"); ModuleFactory factory = ModuleFactory.createFactory(head, new DogBody()); factory.createHead().eat(); // 测试深浅复制 Head head2 = (Head) head.clone(); head2.getEye().setName("smallEye"); head2.eat(); head.eat(); // 这里的输出发现eye并没有变成smallEye,所以可以确定eye是深复制 System.out.println(); factory = ModuleFactory.createFactory(new CatHead(), new CatBody()); act(factory); } }
输出
A dooog's head is eating with its eye customEye
A dooog's head is eating with its eye smallEye
A dooog's head is eating with its eye customEye
A caaat's head is eating fast
A caaat's body is dancing crazily!!