工厂方法,通过Template Method模式来生成实例的工厂,就是Factory Method模式,和Template Method一样,Factory Method模式超类决定实例的生成方式,但是不决定所要生成的具体的类,具体的处理都还是由子类来负责,这样生成实例的framework框架和实际负责生成实例的类解耦
以制作身份证为例,创建的类如下:
Product:定义一个抽象产品类,类里定义一个抽象方法使用身份证use
Factory:定义制作和注册两个抽象方法,create调用这两个抽象方法生成Product实例
IDCard:重写产品Product类的重写方法use
IDCardFactory:重写工厂类Factory里制作和注册两个抽象方法
Main:测试类main
可以创建两个不同的包完成解耦:
factory.framework:包括了Product类和Factory类,组成了生成实例的框架
factory.idcard:包括了IDCard类和IDCardFactory类,负责身份证的加工处理
首先是Product抽象类,表示任意产品,定义一个use抽象方法,可以给任意产品调用use,但是具体实现在Product类的子类完成
package factory.framework;
/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: Product
* Author: lihui
* Date: 2018/4/30 23:38
*/
public abstract class Product {
public abstract void use();
}
然后工厂类Factory,里面调用create方法生成Product实例,具体实现调用另两个抽象方法,首先createProduct生成产品,然后调用registerProduct注册产品;而他们的具体处理交给了Factory的子类重写
package factory.framework;
/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: Factory
* Author: lihui
* Date: 2018/4/30 23:38
*/
public abstract class Factory {
protected abstract Product createProduct(String owner);
protected abstract void registerProduct(Product product);
public final Product create(String owner) {
Product p = createProduct(owner);
registerProduct(p);
return p;
}
}
接着就是身份证IDCard类,继承超类Product,为了与框架分离,放到idcard包里,重写Product的use方法
package factory.idcard;
import factory.framework.Product;
/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: IDCard
* Author: lihui
* Date: 2018/4/30 23:42
*/
public class IDCard extends Product {
private String owner;
IDCard(String owner) {
System.out.println("制作" + owner + "的ID卡");
this.owner = owner;
}
@Override
public void use() {
System.out.println("使用" + owner + "的ID卡");
}
public String getOwner() {
return owner;
}
}
最后就是IDCardFactory了,继承超类Factory,重写createProduct和registerProduct方法,createProduct方法实例化生产身份证卡,registerProduct方法通过将身份证IDCard的owner保存到owners来注册该身份证
package factory.idcard;
import factory.framework.Factory;
import factory.framework.Product;
import java.util.ArrayList;
import java.util.List;
/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: IDCardFactory
* Author: lihui
* Date: 2018/4/30 23:44
*/
public class IDCardFactory extends Factory {
private List owners = new ArrayList();
@Override
protected Product createProduct(String owner) {
return new IDCard(owner);
}
@Override
protected void registerProduct(Product product) {
owners.add(((IDCard)product).getOwner());
}
public List getOwners() {
return owners;
}
}
测试类main
package factory;
import factory.framework.Factory;
import factory.framework.Product;
import factory.idcard.IDCardFactory;
/**
* Copyright (C), 2014-2018, maoxiaomeng.com
* FileName: Main
* Author: lihui
* Date: 2018/4/30 23:48
*/
public class Main {
public static void main(String[] args) {
Factory factory = new IDCardFactory();
Product card1 = factory.create("LiLei");
Product card2 = factory.create("LiMing");
Product card3 = factory.create("LiHui");
card1.use();
card2.use();
card3.use();
}
}
工厂方法模式的角色:
Product:例子中的Product类;产品,属于框架的一方,是一个抽象类;定义了工厂方法模式中生成的实例锁持有的接口,而具体的处理实现都是由其子类ConcreteProduct角色来处理
Creator:例子中的Factory类;创建者,属于框架的一方,负责生成Product角色的抽象类,而具体的处理实现都是由其子类ConcreteCreator角色处理
ConcreteProduct:例子中的IDCard类;具体的产品,属于具体加工实现的一方,它决定了具体的产品
ConcreteCreator:例子中的IDCardFactory类;具体的创建者,属于具体加工实现的一方,负责生成具体的产品
Creator角色对于实际负责生成实例的ConcreteCreator角色一无所知,它只要调用Product角色和 生成实例的方法,就可以生成Product的实例;这里不需要用new来生成实例,而是调用生成实例的工厂方法来实现,这样可以防止超类和其它具体类耦合
因为产品Product和工厂Factory封装到同一个包里了,这样如果想要创建任何其它产品实例的产品和工厂,都通过这同一个框架来完成,不需要做任何修改就搞定了产品和工厂