首先是简单工厂,它其实不是一种设计模式,更像是一种编程习惯。
假设我们需要生产一部手机,这个手机可以是2017年的新款,也可以是2018年的新款,根据我们的需要,生产出手机。所有的手机都继承一个手机基类,我们可以把手机对象创建的过程提取出来,创造一个工厂从工厂中根据需求返回需要的手机。
代码如下

public class PhoneFactory { public static PhoneBase getPhone(PhoneTypeEnum phoneType) { PhoneBase phone = null; switch (phoneType) { case STYLE_2017: phone = new Phone_2017(); break; case STYLE_2018: phone = new Phone_2018(); break; case STYLE_2019: phone = new Phone_2019(); break; default: System.out.println("不存在的手机类型"); } return phone; } }

public class PhoneBase { public void display() { System.out.println("这是一款手机"); } }

public enum PhoneTypeEnum { /** * 2017新款 */ STYLE_2017("2017新款","0"), /** * 2018新款 */ STYLE_2018("2018新款","0"), /** * 2019新款 */ STYLE_2019("2019新款","0"), ; PhoneTypeEnum(String caption, String value) { this.caption = caption; this.value = value; } private String caption; private String value; }

public class Phone_2017 extends PhoneBase { @Override public void display() { System.out.println("这是2017年的新款手机"); } }

public class Phone_2018 extends PhoneBase { @Override public void display() { System.out.println("这是2018年的新款手机"); } }

public class Phone_2019 extends PhoneBase { @Override public void display() { System.out.println("这是2019年的新款手机"); } }
测试

public class Main { public static void main(String[] args) { PhoneBase phone1 = PhoneFactory.getPhone(PhoneTypeEnum.STYLE_2017); phone1.display(); PhoneBase phone2 = PhoneFactory.getPhone(PhoneTypeEnum.STYLE_2018); phone2.display(); PhoneBase phone3 = PhoneFactory.getPhone(PhoneTypeEnum.STYLE_2019); phone3.display(); } }
输出结果
简单工厂把对象的创建和使用区分开来,让整个程序结构更明确。但是工厂中聚合所有的手机创建过程,每次添加一款手机,就需要改动工厂类。
当然手机不可能只有一个公司的,现在有大米公司和香蕉公司两个公司的手机,如果我需要大米公司2019款和香蕉公司2017款的手机,该如何实现呢?这时候就用到了工厂模式。
首先是创建手机的基类,所有的手机都继承于它,然后是创建手机工厂基类,大米和香蕉两个公司的手机工厂类都继承它,然后各自实现制造手机的方法。
代码如下

public class PhoneBase { public void display() { System.out.println("这是一款手机"); } }

public abstract class BasePhoneFactory { /** * 制造工艺 */ public void productionTechnology() { System.out.println("使用最基础的制造工艺"); } /** * 生产手机 * @param phoneType 类型 * @return 手机 */ public abstract BasePhone createPhone(PhoneTypeEnum phoneType); }

public enum PhoneTypeEnum { /** * 2017新款 */ STYLE_2017("2017新款","0"), /** * 2018新款 */ STYLE_2018("2018新款","0"), /** * 2019新款 */ STYLE_2019("2019新款","0"), ; PhoneTypeEnum(String caption, String value) { this.caption = caption; this.value = value; } private String caption; private String value; }

public class Banana2017 extends BasePhone { @Override public void display() { System.out.println("这是香蕉公司2017年款手机"); } } public class Banana2018 extends BasePhone { @Override public void display() { System.out.println("这是香蕉公司2018年款手机"); } } public class Banana2019 extends BasePhone { @Override public void display() { System.out.println("这是香蕉公司2019年款手机"); } }

public class DaMi2017 extends BasePhone { @Override public void display() { System.out.println("这是大米公司2017年款手机"); } } public class DaMi2018 extends BasePhone { @Override public void display() { System.out.println("这是大米公司2018年款手机"); } } public class DaMi2019 extends BasePhone { @Override public void display() { System.out.println("这是大米公司2019年款手机"); } }

public class BananaFactory extends BasePhoneFactory { @Override public void productionTechnology() { System.out.println("使用了香蕉公司独特的制造工艺!"); } @Override public BasePhone createPhone(PhoneTypeEnum phoneType) { BasePhone phone = null; switch (phoneType) { case STYLE_2017: phone = new Banana2017(); break; case STYLE_2018: phone = new Banana2018(); break; case STYLE_2019: phone = new Banana2019(); break; default: System.out.println("不存在的手机类型"); } if (phone != null) { this.productionTechnology(); } return phone; } }

public class DaMiFactory extends BasePhoneFactory { @Override public void productionTechnology() { System.out.println("使用了大米公司独特的制造工艺!"); } @Override public BasePhone createPhone(PhoneTypeEnum phoneType) { BasePhone phone = null; switch (phoneType) { case STYLE_2017: phone = new DaMi2017(); break; case STYLE_2018: phone = new DaMi2018(); break; case STYLE_2019: phone = new DaMi2019(); break; default: System.out.println("不存在的手机类型"); } if (phone != null) { this.productionTechnology(); } return phone; } }
测试
public class Main { public static void main(String[] args) { BasePhoneFactory factory1 = new BananaFactory(); BasePhone phone1 = factory1.createPhone(PhoneTypeEnum.STYLE_2017); phone1.display(); BasePhoneFactory factory2 = new DaMiFactory(); BasePhone phone2 = factory2.createPhone(PhoneTypeEnum.STYLE_2019); phone2.display(); } }
输出
如果我们需要蓝绿公司2018年款的手机时,因为基类已经定义好了方法,只需要再创建蓝绿公司的手机工厂就能够实现。