将实例的生成交给子类
1.基本介绍
模板设计模式中,父类规定处理的流程,在子类中实现具体处理,如果该模式用于生成实例对象,它就演变为工厂设计模式。
工厂方法模式中:父类决定实例的生成方式,但并不决定所要生成具体的类,具体的处理全部交给子类负责。 这样就可以将生成实例的框架和负责生成实例的类解耦。
2.实现过程
类的一览表
名字 | 说明 |
---|---|
Product | 只定义抽象方法 use 的抽象类 |
Factory | 实现了create方法的抽象类 |
IDcard | 实现了use方法的类 |
IDcardFactory | 实现了createProduct registerProduct方法的类 |
Main | 测试类 |
类图
Product
声明use的抽象方法,交给子类实现,此框架定义了产品是任何可以使用的东西。
/**
* @author Jay
* @date 2019/5/21 22:06
* @description 表示产品的抽象类
*/
public abstract class Product {
/**
* 表示产品都有可以被使用的属性
*/
public abstract void use();
}
Factory
使用模板设计模式,声明了生成产品和注册产品俩个抽象方法,交给子类具体实现,同时定义了实例的具体生成方式。
工厂方法模式在生成实例时一定会用到模板模式的。
/**
* @author Jay
* @date 2019/5/21 22:14
* @description 工厂抽象类
*/
public abstract class Factory {
/**
* 用到模板设计模式
* final修饰生成对象,无法被子类继承,其中规定了生成实例方式.
*/
public final Product create(String owner) {
Product p = createProduct(owner);
registerProduct(p);
return p;
}
/**
* 注册产品方法
*
* @param p
*/
public abstract void registerProduct(Product p);
/**
* 创建产品方法
*
* @param owner
* @return
*/
protected abstract Product createProduct(String owner);
}
IDCard
产品的具体实现类,定义了产品的实例生成方式,以及 use() 的具体实现,并且构造方法为包级别访问,外界无法直接调用。
/**
* @author Jay
* @date 2019/5/21 22:27
* @description 具体产品实现类
*/
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
实现了父类的抽象方法,并按照父类的流程具体实现产品的实例化。
/**
* @author Jay
* @date 2019/5/21 22:34
* @description
*/
public class IDCardFactory extends Factory {
private List owners = new ArrayList<String>();
@Override
public void registerProduct(Product p) {
owners.add(((IDCard) p).getOwner());
}
/**
* 修饰符为类访问,外界无法直接通过创建对象,只能父类接收,调用父类创造类的模板
*
* @param owner
* @return
*/
@Override
protected Product createProduct(String owner) {
//构造方法为包级别,只能本包使用,所以只能通过本类调用
return new IDCard(owner);
}
}
Main
/**
* @author Jay
* @date 2019/5/21 22:38
* @description 测试类
*/
public class Main {
public static void main(String[] args) {
//父类接收子类实例,可以直接调用父类方法,里氏替换.
Factory factory = new IDCardFactory();
Product card1 = factory.create("张三");
Product card2 = factory.create("李四");
Product card3 = factory.create("王五");
//IDCardFactory idCardFactory = new IDCardFactory();
//idCardFactory.create("赵六"); 由于方法为类访问权限,所以外界无法直接调用
card1.use(); //只能用父类去接收,调用父类create方法,然后从内部自动调用.
card2.use();
}
}
制作张三的ID卡
制作李四的ID卡
制作王五的ID卡
使用张三的ID卡
使用李四的ID卡
使用王五的ID卡
3.工厂模式中的各种角色
类图:
Product(产品)
属于框架一方,是一个抽象类,定义了模式中工厂模式中生成的实例所持有的接口,但具体的处理由子类ConcreteProduct角色实现。
Creator(创建者)
属于框架一方,负责生成Product角色的抽象类,但是具体实现由子类实现,只定义了实现的流程.他对负责实际生成实例的ConcteteCreator一无所知,只知道只要调用Product角色和生成实例的方法,就可以生成Product的实例.
不用new关键字来生成实例,而是调用生成实例的专门方法来生成实例,防止父类与其他类的耦合。
ConcreteProduct(具体产品)
属于具体加工这一方,实现父类方法,决定了具体的产品.构造方法为包级别访问,只能本包调用。
ConcteteCreator(具体创建者)
负责生成具体产品,调用专门的生成实例方法来生成产品。
4.思路
框架与具体加工
若上边例子想要创建电视对象,我们只需俩个类继承实现父类方法,并不需要修改框架包中的内容,即框架完全不依赖于具体加工内容.
生成实例的三种实现方式
- 指定为抽象方法
- 实现默认处理:直接new出Product类,此时该类无法设置为抽象类.
- 在其中抛出异常:若没有实现直接抛出异常.