工厂方法模式是一种创建型设计模式,它提供了一个抽象的工厂接口,并允许子类自己决定实例化哪个类。 当我们需要根据不同的条件来创建对象时,可以使用工厂方法模式。
工厂方法模式通常由以下几种角色组成:
-
抽象产品 (Product) :定义产品的属性和行为。
-
具体产品 (Concrete Product) :实现抽象产品接口的具体类。
-
抽象工厂 (Factory) :定义工厂的属性和行为以及返回实例化产品的方法。
-
具体工厂 (Concrete Factory) :实现抽象工厂接口的具体类。
例如:使用工厂方法实现咖啡工厂,具体功能如下
功能描述:
-
咖啡店可以生产两种咖啡,拿铁咖啡和美食咖啡。
-
生产咖啡的步骤是 加奶,加糖 然后产生咖啡成品。
工厂方法模式的流程如下:
1、创建一个抽象产品类,定义产品的基本属性与方法。 咖啡【Coffee】:抽象类,有名字属性,加奶、加糖两个抽象方法
public abstract class Coffee {
private String name;
public abstract void addNai();
public abstract void addTang();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Coffee() {
}
public Coffee(String name) {
this.name = name;
}
@Override
public String toString() {
return "Coffee{" +
"name='" + name + '\'' +
'}';
}
}
2、创建一个抽象工厂类,在其中定义一个创建产品的抽象方法。 咖啡工厂【CoffeeFactory】:接口或者抽象类,里面提供生产咖啡的抽象方法
public interface CoffeeFactory {
Coffee makeCoffee();
}
3、创建具体产品类,实现抽象产品接口,即定义具体的产品类型。 美式咖啡【MeishiCoffee】:Coffee 的子类,具体化 Coffee 中的两个方法 拿铁咖啡【NatieCoffee】:Coffee 的子类,具体化 Coffee 中的两个方发
public class MeishiCoffee extends Coffee{
@Override
public void addNai() {
System.out.println(super.getName() + "加奶");
}
@Override
public void addTang() {
System.out.println(super.getName() +"加糖");
}
public MeishiCoffee() {
}
public MeishiCoffee(String name) {
super(name);
}
}
public class NatieCoffee extends Coffee{
@Override
public void addNai() {
System.out.println(super.getName() + "加奶");
}
@Override
public void addTang() {
System.out.println(super.getName() + "加糖");
}
public NatieCoffee() {
}
public NatieCoffee(String name) {
super(name);
}
}
4、创建一个具体工厂类,实现抽象工厂接口,即具体决定应该创建哪种产品。 美式咖啡工厂【MeishiCoffeeFactory】:制作美式咖啡 拿铁咖啡工厂【NatieCoffeeFactory】:制作拿铁咖啡
public class MeishiCoffeeFactory implements CoffeeFactory{
@Override
public Coffee makeCoffee() {
return new MeishiCoffee("美式");
}
}
public class NatieCoffeeFactory implements CoffeeFactory{
@Override
public Coffee makeCoffee() {
return new NatieCoffee("拿铁");
}
}
5、在客户端程序中通过调用具体工厂类的方法来创建产品。 咖啡店【CoffeeShop】:咖啡店,内部聚合了咖啡工厂,提供点单服务,返回具体 Coffee 对象
public class CoffeeShop {
/**
* 咖啡店必须有工厂才能够制作咖啡
**/
private CoffeeFactory factory;
public CoffeeFactory getFactory() {
return factory;
}
public void setFactory(CoffeeFactory factory) {
this.factory = factory;
}
/**
* 制作咖啡
**/
public Coffee order(){
Coffee coffee = factory.makeCoffee();
coffee.addNai();
coffee.addTang();
return coffee;
}
}
6、测试,制作咖啡
public static void main(String[] args) {
//声明咖啡店
CoffeeShop shop = new CoffeeShop();
//创建一个拿铁咖啡工厂
NatieCoffeeFactory natieCoffeeFactory = new NatieCoffeeFactory();
//创建一个美式咖啡工厂
MeishiCoffeeFactory meishiCoffeeFactory = new MeishiCoffeeFactory();
//使用拿铁咖啡工厂制作咖啡
shop.setFactory(natieCoffeeFactory);
//生产了一杯咖啡1【拿铁】
Coffee coffee1 = shop.order();
System.out.println("coffee1 = " + coffee1);
System.out.println("------------------------------");
//使用美式咖啡工厂制作咖啡
shop.setFactory(meishiCoffeeFactory);
//生产一杯咖啡【美式】
Coffee coffee2 = shop.order();
System.out.println("coffee2 = " + coffee2);
}
//测试结果
拿铁加奶
拿铁加糖
coffee1 = Coffee{name='拿铁'}
------------------------------
美式加奶
美式加糖
coffee2 = Coffee{name='美式'}
Process finished with exit code 0
工厂方法模式可以将具体的产品实现与其它部分的代码分离开来,同时也具备扩展方便、可维护性高等优点。
在需要动态创建对象,并且不知道具体创建哪种对象时,使用工厂方法模式是一种很好的实践方式。