美文网首页
设计模式(五)工厂方法模式

设计模式(五)工厂方法模式

作者: Misout | 来源:发表于2018-08-11 16:59 被阅读69次

    导读:前文设计模式(四)简单工厂模式介绍了简单工厂模式,本篇开始介绍工厂方法模式,继续优化简单工厂模式,更好的满足开闭原则和可扩展性。

    工厂方法模式解决的问题

    简单工厂模式存在如下的缺点,而工厂方法模式能够解决这些问题:

    • 在简单工厂中,所有的产品子类的实例创建都是在一个静态工厂方法中创建,如果工厂方法出现问题,就会导致所有引用工厂的客户端出现问题;
    • 如果产品下增加新的产品,简单工厂必须进行修改支持新的产品,违背了开闭原则;
    • 简单工厂中把所有的产品创建都集中在一个方法中,违背了单一职责原则;
    • 简单工厂使用静态方法,造成无法通过继承来扩展工厂方法;

    工厂方法模式定义

    工厂方法模式定义了一个创建对象的接口,但由子类或实现接口的类决定要创建或实例化的类是哪一个。工厂方法让类的实例化推迟到子类中。简单来说,工厂方法模式会创建出很多具体的工厂方法子类,其共同继承一个工厂父类或工厂接口。

    工厂方法模式的UML类图

    工厂方法模式的UML类图

    工厂方法模式角色划分

    • 抽象产品(或者产品接口),如上图中Factory
    • 具体产品,如上图中的ConcreteProduct1
    • 抽象工厂(或者工厂接口),如Factory
    • 具体工厂,如ConcreteFactory1

    工厂方法模式的示例代码

    抽象产品
    这里以Car代表抽象产品,相当于UML类图中的Product角色,代码如下:

    public class Car {
        
        private String name;
        
        public Car() {
            this.name = "This is a Car";
        }
        
        public Car(String name) {
            this.name = name;
        }
        
        public String getName() {
            return name;
        }
        
        public void drive() {
            System.out.println("driving on road");
        }
    }
    

    具体产品
    具体产品BenzCar、BMWCar、LandRoverCar,相当于UML类图中的ConcreteProduct角色,代码如下:

    public class BenzCar extends Car {
    
        public BenzCar() {
            super("BenzCar");
        }
        
        public String getName() {
            return super.getName();
        }
        
        public void drive() {
            System.out.println(getName() + " driving on road");
        }
    }
    
    public class BMWCar extends Car {
    
        public BMWCar() {
            super("BMWCar");
        }
        
        public String getName() {
            return super.getName();
        }
        
        public void drive() {
            System.out.println(getName() + " driving on road");
        }
    }
    
    public class LandRoverCar extends Car {
    
        public LandRoverCar() {
            super("LandRoverCar");
        }
        
        public String getName() {
            return super.getName();
        }
        
        public void drive() {
            System.out.println(getName() + " driving on road");
        }
    }
    

    抽象工厂
    这里以Factory来代表抽象工厂

    public interface Factory {
        /**
         * 抽象工厂方法,子类实现
         * @return
         */
        Car getCar();
    }
    

    具体工厂
    这里有三个具体工厂BenzCarFactory、BMWCarFactory、LandRoverCarFactory

    public class BenzCarFactory implements Factory {
    
        @Override
        public Car getCar() {
            return new BenzCar();
        }
    }
    
    public class BMWCarFactory implements Factory {
        @Override
        public Car getCar() {
            return new BMWCar();
        }
    }
    
    public class LandRoverCarFactory implements Factory {
        @Override
        public Car getCar() {
            return new LandRoverCar();
        }
    }
    

    客户端测试类
    分别创建了三个具体工厂,用来创建三种不同的汽车产品

    public class Client {
    
        public static void main(String[] args) {
            Factory factory = new BenzCarFactory();
            
            Car car = factory.getCar();
            car.drive();
            
            factory = new BMWCarFactory();
            car = factory.getCar();
            car.drive();
            
            factory = new LandRoverCarFactory();
            car = factory.getCar();
            car.drive();
        }
    }
    

    输出结果:

    BenzCar driving on road
    BMWCar driving on road
    LandRoverCar driving on road
    

    工厂方法模式的优点

    • 每个具体工厂只负责创建一种具体产品,职责单一,满足单一职责原则。
    • 这一类产品中新增产品时,原有的抽象工厂和具体工厂都不用修改,只需要新增一个具体的工厂类即可,满足了开闭原则。

    工厂方法模式的缺点

    • 新增产品时,不仅需要需要增加产品类,还需要增加与之对应的具体工厂类,当产品的数量众多时,类的数量将爆发式增长,复杂度变高。
    • 工厂方法只能对同一类的产品进行创建,当需要增加其他类别的产品,比如动物类时,仍需要修改抽象工厂方法类,在里面增加创建动物类的方法,因此开闭原则只是局部满足,并非完美满足。

    该是总结经验的时候了

    在本篇文章,我们学习了更加可扩展的工厂方法模式。我们已经学习到,创建多个对象时可以抽离变化的部分,将代码封装起来。
    那么工厂模式到底能带来哪些好处呢。有许多好多,将创建对象的代码封装起来,可以达到代码的复用,避免重复的代码,利于维护。同时,我们也知道创建对象要尽量依赖接口,而不是具体类。依赖接口而不针对实现编程,可以增加我们代码的弹性,扩展性更好。

    推荐阅读

    设计模式(一)策略模式
    设计模式(二)观察者模式
    设计模式(三)装饰器模式
    设计模式(四)简单工厂模式

    相关文章

      网友评论

          本文标题:设计模式(五)工厂方法模式

          本文链接:https://www.haomeiwen.com/subject/spzrbftx.html