设计模式学习(三):工厂模式

时间:2022-11-08 07:12:58

作者:Grey

原文地址:

博客园:设计模式学习(三):工厂模式

CSDN:设计模式学习(三):工厂模式

工厂模式

工厂模式是创建型模式,工厂模式分为:简单工厂,工厂方法和抽象工厂三种类型。

简单工厂

这个模式很简单,比如我们需要制造不同类型的鼠标,我们只需要创建一个鼠标工厂

public class MouseFactory {
    public static Mouse createMouse(int type) {
        switch (type) {
            case 1:
                return new HpMouse();
            case 2:
                return new LenovoMouse();
            case 0:
            default:
                return new DellMouse();
        }
    }

    public static void main(String[] args) {
        Mouse mouse = MouseFactory.createMouse(1);
        mouse.sayHi();
    }
}

根据不同的 type 来创建不同的鼠标即可。这个模式的缺点很明显,违反了开闭原则 ,所以我们引入工厂方法

工厂方法

工厂方法中,我们可以定义对应产品的对应工厂,以上面这个鼠标的例子为例,我们可以增加工厂的接口

public interface MouseFactory {
    Mouse createMouse();
}

不同类型的鼠标工厂实现这个工厂即可,以 Dell 鼠标工厂为例

public class DellMouseFactory implements MouseFactory {
    @Override
    public Mouse createMouse() {
        return new DellMouse();
    }
}

主函数在调用的时候,直接指定工厂即可制造对应的产品了:

public class FactoryMethodDemo {
    public static void main(String[] args) {
        MouseFactory mf = new HpMouseFactory();
        Mouse mouse = mf.createMouse();
        mouse.sayHi();
    }
}

工厂方法的优点是符合开闭原则,但是缺点也很明显,就是在增加子类的时候,同时要增加一个子类的工厂,而且,只支持同一类产品的创建,不适用于同一产品族

抽象工厂

举例,现在需要通过工厂来制造交通工具,如果是现代的工厂,制造的就是汽车,如果是古代的工厂,制造的就是马车, 我们可以先把工厂抽象出来,

public abstract class AbstractFactory {

    protected abstract Transportation createTransportation();

    protected abstract WritingInstrument createWritingInstrument();
}

交通工具也可以抽象出来

public abstract class Transportation {
    protected abstract void go();
}

对于马车和汽车来说,只需要继承这个 Transportation 类,实现对应的 go 方法即可,以汽车为例

public class Car extends Transportation {
    @Override
    protected void go() {
        System.out.println("car go");
    }
}

对于现代工厂还是古代工厂,只需要继承 AbstractFactory 这个抽象类,实现 createTransportation 方法即可,以现代工厂为例

public class ModernFactory extends AbstractFactory {

    @Override
    protected Transportation createTransportation() {
        return new Car();
    }

    @Override
    protected WritingInstrument createWritingInstrument() {
        return new Pen();
    }
}

主方法在调用的时候,只需要

public class Main {
    public static void main(String[] args) {
        AbstractFactory factory = new ModernFactory();
        factory.createTransportation().go();
    }
}

抽象工厂的UML图如下:

设计模式学习(三):工厂模式

Java SE 8 提供了 Supplier 这个函数式接口,我们可以通过这个接口很方便的实现工厂类。更多 Java SE 8 新特性见:Java SE 8 新增特性

举例:

我们可以定义一个 MovableFactory ,里面的 create 方法,传入的是一个 Supplier 对象,你可以把所有 Movable 的子类实现传给这个参数,示例如下:

public class MovableFactory {
    public static Movable create(Supplier<? extends Movable> supplier) {
        return supplier.get();
    }

    public static void main(String[] args) {
        MovableFactory.create(Car::new).go();
        MovableFactory.create(() -> new Ship()).go();
    }
}

工厂模式应用举例

  1. JDK 中的 Calendar 类的 getInstance() 方法;

  2. LogBack 中 LoggerFactory.getLogger()方法;

  3. 在 Spring 中,所有工厂都是 BeanFactory 的子类。通过对 BeanFactory 的实现,我们可以从 Spring 的容器访问 Bean 。根据不同的策略调用 getBean() 方法,从而获得具体对象。

  4. Hibernate 换数据库只需换方言和驱动就可以切换不同数据库,也是利用了工厂模式。

UML 和 代码

UML 图

代码

更多

设计模式学习专栏

参考资料