设计模式-工厂方法模式(Factory Method)

工厂方法模式

定义
工厂方法模式,定义抽象工厂类来负责定义创建对象的公共接口,而具体工厂类则负责生成具体的对象。与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类。

类型
创建型。

优点
更加符合开闭原则,当需要增加一种新的产品时,只需要增加相应的具体产品类和相应的具体工厂类即可,而简单工厂模式则需要修改工厂类的if-else判断逻辑,会非常繁琐。

设计模式的七大原则
设计模式-简单工厂模式(Simple Factory Pattern)

也更加符合单一职责原则,每个具体工厂类只负责创建对应的产品类,而简单工厂模式中的工厂类需要创建所有的产品类,存在很多if-else逻辑判断,既不美观,也很容易出现错误。并且简单工厂模式的工厂类一般使用静态工厂方法,不便于子类进行方法重写。工厂方法模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂模式中创建对象由工厂类统一创建的同时(只不过工厂方法模式将工厂类进行抽象,创建对象的任务则由具体工厂类来完成),也让扩展变得简单,让继承变得可行,增加了程序的多态性。

缺点
当需要增加一种新的产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,此时,类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,系统便有更多的类需要编译和运行,会给系统带来一些额外的内存、cpu消耗。由于考虑到系统的可扩展性,需要引入抽象层,在应用层代码中均使用抽象层来进行定义,增加了系统的抽象性、理解难度以及系统的实现难度。

适用场景

  1. 当一个类不知道它所需要的对象的类时,在工厂方法模式中,应用层不需要知道具体产品类的类名,只需要知道所对应的具体工厂类即可。
  2. 当一个类希望通过其子类来指定创建对象时,在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品对象的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
  3. 具体的产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。

例子
Video类,所有视频的抽象。

package com.kaven.design.pattern.creational.factorymethod;

public abstract class Video {
    public abstract void produce();
}

JavaVideo类,Java视频类,继承Video类。

package com.kaven.design.pattern.creational.factorymethod;

public class JavaVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Java课程!");
    }
}

PythonVideo类,Python视频类,继承Video类。

package com.kaven.design.pattern.creational.factorymethod;

public class PythonVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Python课程!");
    }
}

VideoFactory类,抽象工厂类,定义创建对象的公共接口。

package com.kaven.design.pattern.creational.factorymethod;

public abstract class VideoFactory {
    public abstract Video getVideo();
}

JavaVideoFactory类,负责创建JavaVideo对象的具体工厂类,继承抽象工厂。

package com.kaven.design.pattern.creational.factorymethod;

public class JavaVideoFactory extends VideoFactory {
    public Video getVideo() {
        return new JavaVideo();
    }
}

PythonVideoFactory类,负责创建PythonVideo对象的具体工厂类,继承抽象工厂。

package com.kaven.design.pattern.creational.factorymethod;

public class PythonVideoFactory extends VideoFactory {
    public Video getVideo() {
        return new PythonVideo();
    }
}

应用层代码:

package com.kaven.design.pattern.creational.factorymethod;

public class Test {
    public static void main(String[] args) {
        VideoFactory videoFactory = new JavaVideoFactory();
        Video video = videoFactory.getVideo();
        video.produce();
    }
}

当我们需要增加一个新的视频时,工厂方法模式很好的遵守了开闭原则,我们只需要增加对应的视频类和创建该视频对象的具体工厂即可。

FEVideo类,前端视频类,继承Video类。

package com.kaven.design.pattern.creational.factorymethod;

public class FEVideo extends Video {
    public void produce() {
        System.out.println("录制FE课程!");
    }
}

FEVideoFactory类,负责创建FEVideo对象的具体工厂类,继承抽象工厂。

package com.kaven.design.pattern.creational.factorymethod;

public class FEVideoFactory extends VideoFactory {
    public Video getVideo() {
        return new FEVideo();
    }
}

上面也说过,抽象工厂可以定义为接口,也可以定义为抽象类,我这里是定义为抽象类。

如果有说错的地方,请大家不吝赐教(记得留言哦~~~~)。

发布了258 篇原创文章 · 获赞 161 · 访问量 32万+

猜你喜欢

转载自blog.csdn.net/qq_37960603/article/details/104006685