前因:如果创建一个对象需要一系列复杂的初始化操作,比如需要关联其他成员对象、查配置文件、查数据库表…

    如果将这些东西写在构造函数里面,那么代码会变得很长很长,大大降低了程序的可读性。

    这个时候,我们可以增加一个特殊的类—工厂类,专门负责对象的创建工作。

    1. public class Mask {
    2. //构造函数
    3. public Mask(){
    4. // .....
    5. // 100行初始化代码
    6. }
    7. }
    8. public class MaskFactory {
    9. public Mask createMask() {
    10. Mask mask = new Mask();
    11. // .....
    12. // 100行初始化代码
    13. return mask;
    14. }
    15. }

    假如这个口罩分为高端口罩和低端口罩

    1. public interface IMask {
    2. void show();
    3. }
    4. public class HighEndMask implements IMask {
    5. @Override
    6. public void show() {
    7. System.out.println("我是高端口罩");
    8. }
    9. }
    10. public class LowEndMask implements IMask {
    11. @Override
    12. public void show(){
    13. System.out.println("我的低端口罩");
    14. }
    15. }

    为了区分,我们可以传入不同的参数,根据参数返回不同的口罩

    1. public class MaskFactory{
    2. public IMask createMask(String type) {
    3. IMask mask = null;
    4. if("高端口罩".equals(type)){
    5. mask = new HighEndMask();
    6. // .....
    7. // HighEndMask的100行初始化代码
    8. }else if("低端口罩".equals(type)){
    9. mask = new LowEndMask();
    10. // .....
    11. // LowEndMask的100行初始化代码
    12. }
    13. return mask;
    14. }
    15. }

    使用

    1. public class Test {
    2. public static void main(String[] args) {
    3. MaskFactory factory = new MaskFactory();
    4. IMask maskA = factory.createMask("高端口罩");
    5. IMask maskB = factory.createMask("低端口罩");
    6. maskA.show();
    7. maskB.show();
    8. }
    9. }

    像这样通过工厂类创建对象,并且根据传入参数决定具体子类对象的做法,就是简单工厂模式(Simple Factory Pattern)

    但是,如果增加新的口罩类别,就要修改这个工厂模式了,不符合开闭原则。因此,我们可以针对每一个口罩类创建对应的工厂类,这些工厂类分别实现抽象的工厂接口,这样我们只要实例化不同的工厂类,调用创建方法,得到的就是对应的口罩对象。(多态

    1. public interface IMaskFactory {
    2. IMask createMask();
    3. }
    4. public class HighEndFactory implements IMaskFactory{
    5. @Override
    6. public IMask createMask() {
    7. IMask mask = new HighEndMask();
    8. // .....
    9. // HighEndMask的100行初始化代码
    10. return mask;
    11. }
    12. }
    13. public class LowEndFactory implements IMaskFactory{
    14. @Override
    15. public IMask createMask() {
    16. IMask mask = new LowEndMask();
    17. // .....
    18. // LowEndMask的100行初始化代码
    19. return mask;
    20. }
    21. }

    在代码中,工厂类变成了抽象的接口,高端口罩工厂和低端口罩工厂这两个子类分别实现了该接口。

    在客户端,想要创建什么样的口罩对象,只需实例化不同的工厂子类,调用相同的创建方法,无需再传入参数:

    1. public class Test {
    2. public static void main(String[] args) {
    3. IMaskFactory factoryA = new LowEndFactory();
    4. IMaskFactory factoryB = new HighEndFactory();
    5. IMask maskA = factoryA.createMask();
    6. IMask maskB = factoryB.createMask();
    7. maskA.show();
    8. maskB.show();
    9. }
    10. }

    这就是工厂方法模式(Factory Method Pattern)

    如果业务涉及的子类越来愈多,不可能每一个都要创建一个子类

    工厂模式 - 图1

    这个时候可以对应的进行分组:

    工厂模式 - 图2

    首先看一下产品类的代码,口罩和防护服是两个抽象接口,分别拥有高端和低端两个实现类:

    1. public interface IMask {
    2. void showMask();
    3. }
    4. public class LowEndMask implements IMask {
    5. @Override
    6. public void showMask(){
    7. System.out.println("我的低端口罩");
    8. }
    9. }
    10. public class HighEndMask implements IMask {
    11. @Override
    12. public void showMask() {
    13. System.out.println("我是高端口罩");
    14. }
    15. }
    16. public interface IProtectiveSuit {
    17. void showSuit();
    18. }
    19. public class LowEndProtectiveSuit implements IProtectiveSuit {
    20. @Override
    21. public void showSuit() {
    22. System.out.println("我是低端防护服");
    23. }
    24. }
    25. public class HighEndProtectiveSuit implements IProtectiveSuit {
    26. @Override
    27. public void showSuit() {
    28. System.out.println("我是高端防护服");
    29. }
    30. }

    接下来是工厂类,由于产品分成了高端和低端两大组,工厂也相应分成了高端工厂和低端工厂,各自负责组内产品的创建:

    1. public interface IFactory {
    2. //创建口罩
    3. IMask createMask();
    4. //创建防护服
    5. IProtectiveSuit createSuit();
    6. }
    7. public class LowEndFactory implements IFactory {
    8. @Override
    9. public IMask createMask() {
    10. IMask mask = new LowEndMask();
    11. // .....
    12. // LowEndMask的100行初始化代码
    13. return mask;
    14. }
    15. @Override
    16. public IProtectiveSuit createSuit() {
    17. IProtectiveSuit suit = new LowEndProtectiveSuit();
    18. // .....
    19. // LowEndProtectiveSuit的100行初始化代码
    20. return suit;
    21. }
    22. }
    23. public class HighEndFactory implements IFactory {
    24. @Override
    25. public IMask createMask() {
    26. IMask mask = new HighEndMask();
    27. // .....
    28. // HighEndMask的100行初始化代码
    29. return mask;
    30. }
    31. @Override
    32. public IProtectiveSuit createSuit() {
    33. IProtectiveSuit suit = new HighEndProtectiveSuit();
    34. // .....
    35. // HighEndProtectiveSuit的100行初始化代码
    36. return suit;
    37. }
    38. }

    最后是客户端代码,通过实例化不同的工厂子类,调用不同的创建方法,可以创建出不同的产品:

    1. public class Test {
    2. public static void main(String[] args) {
    3. IFactory factoryA = new LowEndFactory();
    4. IFactory factoryB = new HighEndFactory();
    5. //创建低端口罩
    6. IMask maskA = factoryA.createMask();
    7. //创建高端口罩
    8. IMask maskB = factoryB.createMask();
    9. //创建低端防护服
    10. IProtectiveSuit suitA = factoryA.createSuit();
    11. //创建高端防护服
    12. IProtectiveSuit suitB = factoryB.createSuit();
    13. maskA.showMask();
    14. maskB.showMask();
    15. suitA.showSuit();
    16. suitB.showSuit();
    17. }
    18. }

    像这样把产品类分组,组内不同产品对应于同一工厂类不同方法的涉及模式,就是抽象工厂模式(Abstract Factory Pattern)

    参考:

    漫画:设计模式之 “工厂模式”

    漫画:什么是 “抽象工厂模式” ?