创建型:Factory(工厂模式)
说到工厂,我们最新想到的应该是一堆堆的原料通过流水线组装成产品的场景吧?
其实对于一个程序员来讲,这个模式应该是很难不遇到的,特别是对于web开发的人员。为啥呢?因为这种场景在我们使用MVC的M层中是经常会遇到的。Hibernate的SessionFactory和JPA标准的EntityFactory。
所以说工厂模式用人类的语言来沟通的话,就是你给我清单上的原材料,我给你组装好的产品。非常简单的一个Demo(简单工厂):
工厂方法一般是把实例化延迟到子类;而抽象工厂一般是用于定义一组家族组件,或原材料,比如有多家分工厂,但是每一家分工厂都可以供给同样的原件
package top.gabin.oa.web.design.factory; /** * 食物 * @author linjiabin on 16/4/30 */ public interface Food { String getName(); }
package top.gabin.oa.web.design.factory; /** * 面条 * @author linjiabin on 16/4/30 */ public class Noodles implements Food { @Override public String getName() { return "面条"; } }
package top.gabin.oa.web.design.factory; /** * 米饭 * @author linjiabin on 16/4/30 */ public class Rice implements Food { @Override public String getName() { return "米饭"; } }
package top.gabin.oa.web.design.factory; /** * 食物简单工厂类 * @author linjiabin on 16/4/30 */ public class SimpleFactory { public static Food createFood(String foodName) { if (foodName != null) { if (foodName.equals("Noodles")) { return new Noodles(); } else if (foodName.equals("Rice")) { return new Rice(); } } return null; } }
package top.gabin.oa.web.design.factory; import org.junit.Test; /** * 简单工厂测试类 * @author linjiabin on 16/4/30 */ public class TestSimpleFactory { @Test public void testSimple() { Food noodles = SimpleFactory.createFood("Noodles"); if (noodles != null) { System.out.println(noodles.getName()); } } }
输出:
面条
上面是一个很简单的工厂应用,一般我们不认为简单工厂是设计模式。我们认为的工厂模式一般指的是(普通)工厂模式和抽象工厂。
现在我们假设我是一家上市公司总公司的总裁,我们公司的主要业务是手机,而我们公司在全世界各地都有分工厂。
ok,现在首先我们希望有一个标准的组装工厂类(工厂模式)和原料工厂(抽象工厂)
package top.gabin.oa.web.design.factory.normal; import java.util.ArrayList; import java.util.List; /** * 手机组装工厂 * @author linjiabin on 16/4/30 */ public abstract class PhoneFactory { // 元件工厂, 这边直接初始化, 默认是泉州元件工厂 private ComponentFactory componentFactory = new QzCompontFactory(); // 元件 private List<Component> componentList = new ArrayList<>(); // 获取组件 protected final List<Component> getComponentList() { componentList.add(componentFactory.createScreen()); componentList.add(componentFactory.createCamera()); return componentList; } public void setComponentFactory(ComponentFactory componentFactory) { this.componentFactory = componentFactory; } // 订购手机 protected final Phone orderPhone() { Phone phone = createPhone(); return phone; } // 生产手机 public abstract Phone createPhone(); protected final void buildPhone(Phone phone) { // 获取所有元件, List<Component> componentList = getComponentList(); for (Component component : componentList) { // 组装 component.assembly(phone); } } }
package top.gabin.oa.web.design.factory.normal; /** * 抽象工厂:创建一组有关联的产品家族 * 一般这个产品族是比较固定的,因为想扩展这个抽象类,子类都必须重新覆盖 * @author linjiabin on 16/5/8 */ public abstract class ComponentFactory { abstract Component createScreen(); abstract Component createCamera(); }
很明显,我们不希望我们的子公司自己去采购元件和出售手机,所以获取元件的方式和出售手机的方式还是由抽象父类来决定。而生产手机的具体流程由子类来实现。这就是将实例化对象的行为交给子类去决定,我也只给你这个权利,其他的你得听我的。(高级组件不能依赖低级组件,don‘t call me,I will call you。)
这里面元件工厂的应用属于抽象工厂,其与工厂模式的差别是前者使用对象组合,后者使用抽象继承,而且一般抽象工厂所创建的是一组相关的产品家族,而非单个产品。
就像我们在厦门设置了一个分工厂:
package top.gabin.oa.web.design.factory.normal; /** * 厦门手机组装工厂 * @author linjiabin on 16/4/30 */ public class XmPhoneFactory extends PhoneFactory { @Override public Phone createPhone() { Phone phone = new Phone() { }; // 我希望使用厦门自己的元件工厂 setComponentFactory(new XmComponentFactory()); // 根据工厂抽象父类的组装方式,由于创建手机的方法是子类自己实现的,所以这里也可以自己组装,但是不让覆盖 buildPhone(phone); return phone; } }
泉州和厦门原料工厂:
package top.gabin.oa.web.design.factory.normal; /** * 泉州元件工厂 * @author linjiabin on 16/5/8 */ public class QzCompontFactory extends ComponentFactory { @Override Component createScreen() { return new Screen(); } @Override Component createCamera() { return new Camera(); } }
package top.gabin.oa.web.design.factory.normal; /** * 厦门元件工厂 * @author linjiabin on 16/5/8 */ public class XmComponentFactory extends ComponentFactory { @Override Component createScreen() { Screen screen = new Screen(); screen.setBrand("三星"); return screen; } @Override Component createCamera() { Camera camera = new Camera(); // 1200万像素 camera.setPixel(1200 * 10000); return null; } }
demo中涉及的其他类:
package top.gabin.oa.web.design.factory.normal; /** * 手机 * @author linjiabin on 16/4/30 */ public class Phone { private Screen screen; private Camera camera; public Screen getScreen() { return screen; } public void setScreen(Screen screen) { this.screen = screen; } public Camera getCamera() { return camera; } public void setCamera(Camera camera) { this.camera = camera; } }
package top.gabin.oa.web.design.factory.normal; /** * 摄像头 * @author linjiabin on 16/4/30 */ public class Camera implements Component { // 像素 private int pixel; public int getPixel() { return pixel; } public void setPixel(int pixel) { this.pixel = pixel; } @Override public void assembly(Phone phone) { phone.setCamera(this); } }
package top.gabin.oa.web.design.factory.normal; /** * 屏幕 * @author linjiabin on 16/4/30 */ public class Screen implements Component { private String brand; public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } @Override public void assembly(Phone phone) { phone.setScreen(this); } }