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


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

    作者: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图如下:

    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. JDK 中的 Calendar 类的 getInstance() 方法;

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

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

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

    UML 和 代码

    UML 图

    代码

    更多

    设计模式学习专栏

    参考资料

  • 相关阅读:
    TeamViewer的替代品:realVNC
    Introduction of Generator in Python
    Excel: assign label to scatter chart using specific cell values
    reverse/inverse a mapping but with multiple values for each key
    虚拟化与云计算
    现代计算机简介
    CentOS 7 安装中网络设置111
    机械硬盘原理
    文件系统
    最重要的块设备——硬盘
  • 原文地址:https://www.cnblogs.com/greyzeng/p/16867763.html
Copyright © 2020-2023  润新知