GOF23设计模式之工厂模式-Factory

本文将分别实现简单工厂模式–>工厂方法模式–>抽象工厂模式,并比较其优缺点。

简单工厂模式

定义:由一个工厂对象决定创建出哪一种产品实例

  • 不属于GOF23种设计模式中

类型:创建型设计模式

适用场景:

  1. 工厂类负责创建的对象比较少
  2. 客户端(应用层)只知道传入工厂类的参数,对于如何创建对象逻辑并不关心

Coding

public class SimpleFactoryMain {

    /**
     * Car接口
     */
    interface Car {
        /**
         * 行驶
         */
        void run();
    }

    /**
     * 奥迪车
     */
    static class AudiCar implements Car {

        @Override
        public void run() {
            System.out.println("奥迪车行驶速度150km/h");
        }
    }

    /**
     * 保时捷
     */
    static class PorscheCar implements Car {

        @Override
        public void run() {
            System.out.println("保时捷行驶速度200km/h");
        }
    }

    /**
     * 工厂接口
     */
    interface CarFactory {
        Car create(String name);
 
    }

    /**
     * 工厂类实现
     */
    static class DefaultCarFactory implements CarFactory {
        /**
         * 优点:
         * 对外屏蔽具体的实现细节,外界不需要关心里面的实现逻辑,使用者只需要放心的使用
         * 将生产者和消费者进行责任分割
         *
         * 缺点:
         * 无法灵活地应对产品的增加,比如后面需要增加其他的Car,无法避免修改代码的情况下实现功能,
         * 而且会造成整个实现方法越来越复杂,直至无法维护
         * @param name
         * @return
         */
        @Override
        public Car create(String name) {
            if (Objects.equals(name, "Audi")) {
                return new AudiCar();
            } else if (Objects.equals(name, "Porsche")) {
                return new PorscheCar();
            }
            return null;
        }

    }


    /**
     * 主函数
     *
     * @param args
     */
    public static void main(String[] args) {
        CarFactory carFactory = new DefaultCarFactory();
        Car car = carFactory.create("Audi");
        car.run();

        car = carFactory.create("Porsche");
        car.run();
    }

UML

在这里插入图片描述

优点:

  • 对外屏蔽具体的实现细节,外界不需要关心里面的实现逻辑,使用者只需要放心的使用
  • 将生产者和消费者进行责任分割

缺点:

  • 无法灵活地应对产品的增加,比如后面需要增加其他的Car,无法避免修改代码的情况下实现功能,
  • 而且会造成整个实现方法越来越复杂,直至无法维护

框架中的简单工厂模式

  • JDk中:
    • Calendar.createCalendar()
      在这里插入图片描述
  • JDBC中
    • DriverManager.getConnection()
  • logback中
    • LoggerContext.getLogger()

拓展知识:基于反射升级简单工厂模式

  • coding

public class SimpleFactoryMain {

    /**
     * Car接口
     */
    interface Car {
        /**
         * 行驶
         */
        void run();
    }

    /**
     * 奥迪车
     */
    static class AudiCar implements Car {

        @Override
        public void run() {
            System.out.println("奥迪车行驶速度150km/h");
        }
    }

    /**
     * 保时捷
     */
    static class PorscheCar implements Car {

        @Override
        public void run() {
            System.out.println("保时捷行驶速度200km/h");
        }
    }

    /**
     * 工厂接口
     */
    interface CarFactory {
        Car create(String name);
        // 基于反射升级简单工厂模式
        Car create(Class clazz);
    }

    /**
     * 工厂类实现
     */
    static class DefaultCarFactory implements CarFactory {
        /**
         * 优点:
         * 对外屏蔽具体的实现细节,外界不需要关心里面的实现逻辑,使用者只需要放心的使用
         * 将生产者和消费者进行责任分割
         *
         * 缺点:
         * 无法灵活地应对产品的增加,比如后面需要增加其他的Car,无法避免修改代码的情况下实现功能,
         * 而且会造成整个实现方法越来越复杂,直至无法维护
         * @param name
         * @return
         */
        @Override
        public Car create(String name) {
            if (Objects.equals(name, "Audi")) {
                return new AudiCar();
            } else if (Objects.equals(name, "Porsche")) {
                return new PorscheCar();
            }
            return null;
        }

        /**
         *  基于反射升级简单工厂模式
         *  优点:在上面基础上升级,当增加其他的Car时,系统无需扩展工厂的代码,只需要实现Car,
         *  因此符合开闭原则。
         **/
        @Override
        public Car create(Class clazz) {
            try {
                return (Car) clazz.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return null;
        }

    }


    /**
     * 主函数
     *
     * @param args
     */
    public static void main(String[] args) {
        CarFactory carFactory = new DefaultCarFactory();
        Car car = carFactory.create("Audi");
        car.run();

        car = carFactory.create("Porsche");
        car.run();


        car = carFactory.create(AudiCar.class);
        car.run();

        car = carFactory.create(PorscheCar.class);
        car.run();
    }

  • 优点:在上面基础上升级,当增加其他的Car时,系统无需扩展工厂的代码,只需要实现Car,因此符合开闭原则。

工厂方法模式

描述:

正是因为简单工厂的缺点,使用一个工厂类无法应对多样的产品变化,导致代码的维护越来越困难,脱离了设计模式的初衷。所以针对后期可能出现的多样产品,我们尝试使用一下工厂方法解决问题。

定义:

  • 一个用于创建对象的接口,让子类决定将哪一个类实例化。使一个类的实例化延迟到其子类

适用场景

  • 创建代码需要大量重复的代码
  • 客户端(应用层)不依赖产品实例如何被创建、实现等细节
  • 一个类通过其子类来指定创建哪个对象

coding

public class FactoryMethodMain {

    /**
     * Car接口
     */
    interface Car {
        /**
         * 行驶
         */
        void run();
    }

    /**
     * 奥迪车
     */
    static class AudiCar implements Car {

        @Override
        public void run() {
            System.out.println("奥迪车行驶速度150km/h");
        }
    }

    /**
     * 保时捷
     */
    static class PorscheCar implements Car {

        @Override
        public void run() {
            System.out.println("保时捷行驶速度200km/h");
        }
    }

    /**
     * 工厂接口
     */
    interface CarFactory {
        /**
         * 生产车
         *
         * @return
         */
        Car create();
    }

    /**
     * 奥迪工厂类实现
     */
    static class AudiCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car create() {
            return new AudiCar();
        }
    }

    /**
     * 保时捷工厂类实现
     */
    static class PorscheCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car create() {
            return new PorscheCar();
        }
    }


    /**
     * 主函数
     *
     * @param args
     */
    public static void main(String[] args) {
        //奥迪车工厂
        CarFactory carFactory1 = new AudiCarFactory();
        Car car = carFactory1.create();
        car.run();


        /**
         * 保时捷工厂
         */
        CarFactory carFactory2 = new PorscheCarFactory();
        car = carFactory2.create();
        car.run();
    }
}

UML

在这里插入图片描述
基于工厂方法的设计思想,即使有再多的产品需要加入进来,也是可以通过不断地创建对应的工厂类进行生产,完全不需要担心修改或维护非常复杂的创建逻辑

优点

  • 用户只需关系所需产品对应的工厂,无需关心创建细节
  • 加入新产品符合开闭原则,提高可扩展性

缺点

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性, 理解难度

框架中的工厂方法模式:

  • Jdk 中
//  所有实现Collection接口的实现类都需要实现iterator()方法
//  不同的子类需要创建不同的Iterator子类
public interface Collection<E> extends Iterable<E> {

       Iterator<E> iterator();
}

抽象工厂模式

描述:

工厂方法和抽象工厂最大的区别在于,工厂方法针对于一个产品等级结构,而抽象工厂针对于多个产品等级结构。

概述

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

适用场景

客户端(应用层)不依赖产品实例如何被创建、实现等细节
强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复代码
提供一个产品类的库,所有的产品以同样的接口出现,从而客户端不依赖与具体实现

Coding

public class AbstractFactoryMain {

    /**
     * Car接口
     */
    interface Car {
        /**
         * 行驶
         */
        void run();
    }

    /**
     * 奥迪车
     */
    static class AudiCar implements Car {

        @Override
        public void run() {
            System.out.println("奥迪车行驶速度150km/h");
        }
    }

    /**
     * 保时捷
     */
    static class PorscheCar implements Car {

        @Override
        public void run() {
            System.out.println("保时捷行驶速度200km/h");
        }
    }


    /**
     * 发动机
     */
    interface Engine {

        void run();
    }

    /**
     * 奥迪发动机
     */
    static class AudiEngine implements Engine {

        @Override
        public void run() {
            System.out.println("奥迪发动机在运行");
        }
    }

    /**
     * 保时捷发动机
     */
    static class PorscheEngine implements Engine {

        @Override
        public void run() {
            System.out.println("保时捷发动机在运行");
        }
    }


    /**
     * 工厂接口
     */
    interface CarFactory {
        /**
         * 生产车
         *
         * @return
         */
        Car createCar();

        /**
         * 生产发动机
         *
         * @return
         */
        Engine createEngine();
    }

    /**
     * 奥迪工厂类实现
     */
    static class AudiCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car createCar() {
            return new AudiCar();
        }

        @Override
        public Engine createEngine() {
            return new AudiEngine();
        }
    }

    /**
     * 保时捷工厂类实现
     */
    static class PorscheCarFactory implements CarFactory {
        /**
         * @return
         */
        @Override
        public Car createCar() {
            return new PorscheCar();
        }

        @Override
        public Engine createEngine() {
            return new PorscheEngine();
        }
    }


    /**
     * 主函数
     *
     * @param args
     */
    public static void main(String[] args) {
        //奥迪车工厂
        CarFactory carFactory1 = new AudiCarFactory();
        Car car = carFactory1.createCar();
        car.run();

        Engine engine1 = carFactory1.createEngine();
        engine1.run();


        /**
         * 保时捷工厂
         */
        CarFactory carFactory2 = new PorscheCarFactory();
        car = carFactory2.createCar();
        car.run();

        Engine engine2 = carFactory2.createEngine();
        engine2.run();
    }

优点

具体产品在应用层代码隔离,无需关心创建细节
讲一个系列的产品族放在一起

缺点

规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
增加了系统的抽象性和理解难度

GOF23种设计模式面试之三种工厂模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值