推荐:Java设计模式汇总
工厂方法模式
定义
工厂方法模式,定义抽象工厂类来负责定义创建对象的公共接口,而具体工厂类则负责生成具体的对象。与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类。
类型
创建型。
例子
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();
}
}
上面也说过,抽象工厂可以定义为接口,也可以定义为抽象类,我这里是定义为抽象类。
适用场景
- 当一个类不知道它所需要的对象的类时,在工厂方法模式中,应用层不需要知道具体产品类的类名,只需要知道所对应的具体工厂类即可。
- 当一个类希望通过其子类来指定创建对象时,在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品对象的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
- 具体的产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。
优点
更加符合开闭原则,当需要增加一种新的产品时,只需要增加相应的具体产品类和相应的具体工厂类即可,而简单工厂模式则需要修改工厂类的if-else
判断逻辑,会非常繁琐。
设计模式的七大原则设计模式-简单工厂模式(Simple Factory Pattern)
也更加符合单一职责原则,每个具体工厂类只负责创建对应的产品类,而简单工厂模式中的工厂类需要创建所有的产品类,存在很多if-else
逻辑判断,既不美观,也很容易出现错误。并且简单工厂模式的工厂类一般使用静态工厂方法,不便于子类进行方法重写。工厂方法模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂模式中创建对象由工厂类统一创建的同时(只不过工厂方法模式将工厂类进行抽象,创建对象的任务则由具体工厂类来完成),也让扩展变得简单,让继承变得可行,增加了程序的多态性。
缺点
当需要增加一种新的产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,此时,类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,系统便有更多的类需要编译和运行,会给系统带来一些额外的内存、cpu消耗。由于考虑到系统的可扩展性,需要引入抽象层,在应用层代码中均使用抽象层来进行定义,增加了系统的抽象性、理解难度以及系统的实现难度。
如果有说错的地方,请大家不吝赐教(记得留言哦~~~~)。