设计模式-工厂方法模式

定义

工厂方法模式(Factory Pattern)又叫工厂模式,是创建型模式之一。定义一个用于创建对象的接口,让子类决定实例化哪个类

使用场景

在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以创建的对象无需使用工厂模式。

UML类图

工厂模式UML图
  • Product:抽象产品类。
  • ConcreteProduct:具体产品类,实现Product接口。
  • Factory:抽象工厂类,是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类继承它。
  • ConcreteFactory:这是继承自抽象工厂类的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。

实例

简单工厂模式中,如何创建其它品牌电脑,就需要添加相应的case语句,这违反了OCP原则(也就是开闭原则,其要求软件中对象(类,模块,函数等))应该对外扩展时开放的,对于修改时关闭的)。下面的实例也就是工厂方法模式来完善上述实例。

public class Client {
    public static void main(String[] args) {
        ComputerFactory computerFactory = new GDComputerFactor();
        LenovoComputer lenovoComputer = computerFactory.createComputer(LenovoComputer.class);
        lenovoComputer.start();
        HpComputer mHpComputer = computerFactory.createComputer(HpComputer.class);
        mHpComputer.start();
        AsusComputer mAsusComputerr = computerFactory.createComputer(AsusComputer.class);
        mAsusComputerr.start();
    }
}

/**
 * 抽象产品类
 */
abstract class Computer {
    public abstract void start();
}

/**
 * 具体产品类
 */
class LenovoComputer extends Computer {
    @Override
    public void start() {
        System.out.println("联想电脑启动");
    }
}

class AsusComputer extends Computer {
    @Override
    public void start() {
        System.out.println("华硕电脑启动");
    }
}

class HpComputer extends Computer {
    @Override
    public void start() {
        System.out.println("惠普电脑启动");
    }
}

/**
 * 抽象工厂类
 */
abstract class ComputerFactory {
    public abstract  T createComputer(Class clz);
}

/**
 * 具体工厂类-广达代工厂
 */
class GDComputerFactory extends ComputerFactory {
    @Override
    public  T createComputer(Class clz) {
        Computer computer = null;
        String classname = clz.getName();

        try {
            //通过反射来生产不同厂家的电脑
            computer = (Computer) Class.forName(classname).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) computer;
    }
}

整体结构如下


image.png

可以看到如果要增加A品牌电脑,我们只需编写对应A具体产品,通过客户端调用computerFactory.createComputer(HpComputer.class);即可,无需修改原来的代码,符合了开闭原则。当然上面时采用反射方式,也可以采用每个产品都编写一个具体的工厂来写,如下:

public class Client {
    public static void main(String[] args) {
        ComputerFactory factory = new LenovoComputerFactor();
        factory.createComputer().start();
    }
}
/**
 * 抽象工厂类
 */
abstract class ComputerFactory {
    public abstract Computer createComputer();
}

/**
 * 具体的工厂-联想电脑工厂
 */
class LenovoComputerFactor extends ComputerFactory {
    @Override
    public Computer createComputer() {
        return new LenovoComputer();
    }
}

同样的,如果添加某个品牌电脑,只需添加对应工厂即可,而不坏破坏原有类方法,符合开闭原则。

总结

优点:

  1. 工厂方法用来创建客户所需要的产品,隐藏了具体产品类被实例化的细节,用户只需要要关注工厂,不需要关注创建的细节。
  2. 增加新的产品类时不用修改代码,只需要增加对应的工厂就好,完全符合开放封闭性原则。
  3. 有了抽象的工厂类,所有的具体工厂都继承了自己的父类!完美的体现了多态性!

缺点:

  1. 增加新产品时,也必须增加新的工厂类,会带来额外的开销
  2. 抽象层的加入使得理解程度加大

你可能感兴趣的:(设计模式-工厂方法模式)