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


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

    作者: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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

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

    工厂方法

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

    public interface MouseFactory {
        Mouse createMouse();
    }
    
    • 1
    • 2
    • 3

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

    public class DellMouseFactory implements MouseFactory {
        @Override
        public Mouse createMouse() {
            return new DellMouse();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    public class FactoryMethodDemo {
        public static void main(String[] args) {
            MouseFactory mf = new HpMouseFactory();
            Mouse mouse = mf.createMouse();
            mouse.sayHi();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    抽象工厂

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

    public abstract class AbstractFactory {
    
        protected abstract Transportation createTransportation();
    
        protected abstract WritingInstrument createWritingInstrument();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    交通工具也可以抽象出来

    public abstract class Transportation {
        protected abstract void go();
    }
    
    • 1
    • 2
    • 3

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

    public class Car extends Transportation {
        @Override
        protected void go() {
            System.out.println("car go");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    public class ModernFactory extends AbstractFactory {
    
        @Override
        protected Transportation createTransportation() {
            return new Car();
        }
    
        @Override
        protected WritingInstrument createWritingInstrument() {
            return new Pen();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

    public class Main {
        public static void main(String[] args) {
            AbstractFactory factory = new ModernFactory();
            factory.createTransportation().go();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    抽象工厂的UML图如下:

    image

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    工厂模式应用举例

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

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

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

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

    UML 和 代码

    UML 图

    代码

    更多

    设计模式学习专栏

    参考资料

  • 相关阅读:
    【二叉树】- 层序遍历( js 实现)
    Java架构师常见基础面试题(附答案)
    ubuntu系统中查看打开的端口
    JavaEE 进阶:Spring 的创建和使用
    初级测试到中级测试就差这几个找bug小技巧
    Anaconda平台下从0到1安装TensorFlow环境详细教程(Windows10+Python)
    什么是原生IP?原生IP与住宅IP有何区别?
    晨控CK-FR102系列与汇川AC800系列MODBUSTCP通讯手册
    Mathorcup数学建模竞赛第四届-【妈妈杯】B题:基于协同过滤的书籍推荐模型
    ppo-clip的本质以及它为什么是另一种ppo-KL-penalty
  • 原文地址:https://blog.csdn.net/hotonyhui/article/details/127741119