工厂方法模式是一种类创建型模式,它定义了一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式简称为工厂模式,又可称为虚拟构造模式或多态工厂模式。
在工厂方法模式中,抽象产品是定义产品的接口,它是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。具体工厂是抽象工厂的子类,实现了抽象工厂中定义的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够让工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节完全封装在具体工厂内部。所有的具体工厂类都具有同一个抽象父类。
工厂方法模式与简单工厂模式的主要区别在于它们实现产品或对象创建的方式。
简单工厂模式的特点是,它使用一个具体工厂类(包含业务逻辑和创建对象),根据外界给定的原料,加上自身封装好的判断,来生产出不同类型的相应产品或对象。这种模式的问题在于,它很容易违反高内聚低耦合原则,尤其是在产品或对象创建逻辑复杂的情况下。因此,简单工厂模式通常只在产品或对象创建逻辑很简单的情况下应用。
相比之下,工厂方法模式的核心是一个抽象工厂类。在这个模式中,“工厂”创建的是还没有分化好的对象,其中没有逻辑判断。工厂方法模式让子类去决定具体实例化的对象,把简单的内部逻辑判断移到了客户端代码。
当系统需要加入一个新的产品时,只需要向系统中加入一个这个产品类似及它所对象的工厂类,而没有必要修改客户端,也没有必要修改抽象工厂角色或者其他也有的具体工厂角色,在设计上完全符合设计模式的六大设计原则中的开闭原则。因此,工厂方法模式对于业务变化比较大的场景是适用的。
总的来说,简单工厂模式和工厂方法模式的主要区别在于产品或对象的创建方式:简单工厂模式是在一个具体工厂类中实现创建过程,而工厂方法模式则是通过抽象工厂类和子工厂类来共同完成创建过程。
工厂方法模式的UML类图通常由以下四个角色组成:
抽象工厂(Factory):这是工厂方法模式的核心,创建的对象的工厂类需要实现这个接口。
具体工厂(Concrete Factory):这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且被应用程序调用以创建产品对象。
抽象产品(Product):这是工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
具体产品(Concrete Product):这个角色实现了抽象产品角色所定义的接口。
UML类图中不同的箭头和线条,代表的意义是不同的,这里简单的梳理了一下,如果需要可以移步这里:设计模式之基础:UML类图怎么看?_uml图怎么看-CSDN博客
还接着上篇文章《设计模式之简单工厂模式》女娲造人的传说来演示一下工厂方法模式的示例:
1、定义一个抽象人类Human,Man.java、Woman.java分别实现Human;
2、定义一个抽象工厂类HumanFactory,ManFactory.java、WomanFactory.java是两个可以生成男人、女人的工厂类,分别实现了HumanFactory接口;
3、然后就可以分别开动ManFactory、WomanFactory开始造人了;
抽象产品
public interface Human {
/**
* 人类会吃东西
*/
void eat();
/**
* 人类会喝东西
*/
void drink();
}
具体产品1:
public class Man implements Human{
@Override
public void eat() {
System.out.println("男人一般比较喜欢吃肉");
}
@Override
public void drink() {
System.out.println("男人一般比较喜欢喝酒");
}
}
具体产品2:
public class Woman implements Human{
@Override
public void eat() {
System.out.println("女人一般都比较喜欢吃甜食");
}
@Override
public void drink() {
System.out.println("女人一般都比较喜欢喝红酒");
}
}
抽象工厂
public interface HumanFactory {
/**
* 造人
* @return
*/
Human create();
}
具体工厂1
public class ManFactory implements HumanFactory{
@Override
public Human create() {
return new Man();
}
}
具体工厂2
public class WoManFactory implements HumanFactory{
@Override
public Human create() {
return new Woman();
}
}
public class Test {
public static void main(String[] args) {
HumanFactory manFactory=new ManFactory();
Human man=manFactory.create();
man.eat();
man.drink();
HumanFactory womanFactory=new WoManFactory();
Human woman=womanFactory.create();
woman.eat();
woman.drink();
}
}
4、如果要造机器人怎么办呢?再建一个机器人的工厂,实现HumanFactory接口就可以了;
public class Test {
public static void main(String[] args) {
HumanFactory robotFactory=new RobotFactory();
Human robot=robotFactory.create();
robot.drink();
robot.eat();
}
}
工厂方法模式具有以下优点:
然而,工厂方法模式也存在一些缺点: