设计模式学习笔记——工厂(Factory)模式
@(设计模式)[设计模式, 工厂模式, factory]
基本介绍
工厂(Factory
)模式可以看作模版模式的一种固定实现,如果用模版模式生成实例,这就可以视为工厂模式。
在工厂模式中,抽象的工厂类(父类)决定实例的生成方式和内部细节,但是并不决定所要生成的具体的类,具体的处理全权由具体的工厂类(子类)负责。也就是说抽象的工厂类并不知道自己要生成什么具体的产品,只要是其生成的抽象的产品类的子类就行了。
通过以上方式,可以很方便的将工厂类、产品类(父类)和它们的实现类进行解耦。比如说可以将父类放在framework
包中,子类放在其自己的包中。
工厂案例
类图
实现代码
framework包
Product抽象类
package com.pc.factory.example.framework;
/**
* 产品类
* Created by Switch on 2017-02-09.
*/
public abstract class Product {
/**
* 使用
*/
public abstract void use();
}
Factory抽象类
package com.pc.factory.example.framework;
/**
* 工厂类
* Created by Switch on 2017-02-09.
*/
public abstract class Factory {
/**
* 创建产品
*
* @param owner 所有者
* @return 产品
*/
public final Product create(String owner) {
// 创建产品
Product product = this.createProduct(owner);
// 注册产品
this.registerProduct(product);
return product;
}
/**
* 创建产品
*
* @param owner 所有者
* @return 产品
*/
protected abstract Product createProduct(String owner);
/**
* 注册产品
*
* @param product 产品
*/
protected abstract void registerProduct(Product product);
}
idcard包
IDCard类
package com.pc.factory.example.idcard;
import com.pc.factory.example.framework.Product;
/**
* IDCard类
* Created by Switch on 2017-02-09.
*/
public class IDCard extends Product {
// 所有者
private String owner;
/**
* 构造方法,需要提供所有者<br/>
* 这里有个优化,访问范围为包内,也就是说只能让IDCardFactory创建实例
*
* @param owner 所有者
*/
IDCard(String owner) {
System.out.println("制作" + owner + "的ID卡。");
this.owner = owner;
}
@Override
public void use() {
System.out.println("使用" + owner + "的ID卡。");
}
/**
* 获取所有者
*
* @return 所有者
*/
public String getOwner() {
return this.owner;
}
}
IDCardFactory类
package com.pc.factory.example.idcard;
import com.pc.factory.example.framework.Factory;
import com.pc.factory.example.framework.Product;
import java.util.HashMap;
import java.util.Map;
/**
* IDCard工厂类
* Created by Switch on 2017-02-09.
*/
public class IDCardFactory extends Factory {
// ID卡所有者Map集合
private Map<String, Product> owners = new HashMap<>();
@Override
protected Product createProduct(String owner) {
return new IDCard(owner);
}
@Override
protected void registerProduct(Product product) {
this.owners.put(((IDCard) product).getOwner(), product);
}
/**
* 获取ID卡所有者Map集合
*
* @return ID卡所有者Map集合
*/
public Map<String, Product> getOwners() {
return this.owners;
}
}
测试类
package com.pc.factory.example.test;
import com.pc.factory.example.framework.Factory;
import com.pc.factory.example.framework.Product;
import com.pc.factory.example.idcard.IDCardFactory;
import org.junit.Test;
import java.util.Map;
/**
* ID卡工厂测试类
* Created by Switch on 2017-02-09.
*/
public class IDCardFactoryTest {
@Test
public void testIDCard() {
Factory factory = new IDCardFactory();
Product product1 = factory.create("Switch");
Product product2 = factory.create("Kity");
Product product3 = factory.create("Tom");
product1.use();
product2.use();
product3.use();
// 扩展使用
IDCardFactory idCardFactory = (IDCardFactory) factory;
Map<String, Product> owners = idCardFactory.getOwners();
for (Map.Entry<String, Product> entryOwners : owners.entrySet()) {
System.out.println(entryOwners.getKey() + ":" + entryOwners.getValue());
}
}
}
运行结果
制作Switch的ID卡。
制作Kity的ID卡。
制作Tom的ID卡。
使用Switch的ID卡。
使用Kity的ID卡。
使用Tom的ID卡。
Kity:com.pc.factory.example.idcard.IDCard@e03bb5
Tom:com.pc.factory.example.idcard.IDCard@8c92f4
Switch:com.pc.factory.example.idcard.IDCard@1e4705b
工厂模式中的角色
Product(产品)
Product
角色属于框架这一方,是一个抽象类。它定义了在Factory Method
模式中生成的那些实例所持有的接口API
,但具体的处理则由子类ConcreteProduct
角色决定。在案例中,由Product
类扮演此角色。
Creator(创建者)
Creator
角色属于框架这一方,它是负责生成Product
角色的抽象类,但具体的处理则由子类ConcreteCreator
角色决定。在案例中,由Factory
类扮演此角色。
Creator
角色对于实际负责生成实例的ConcreteCreator
角色一无所知,它唯一知道的就是,只要调用Product
角色和生成实例的方法(类图中的factoryMethod
方法),就可以生成Product
的实例。在案例中,createProduct
方法是用于生成实例的方法。
不用new
关键字来生成实例,而是调用生成实例的专用方法来生成实例,这样就可以防止父类与其他具体类藕合。
ConcreteProduct(具体的产品)
ConcreteProduct
角色属于具体加工这一方,它决定了具体的产品。在案例中,由IDCard类扮演此角色。
ConcreteCreator(具体的创建者)
ConcreteCreator
角色属于具体加工这一方,它负责生成具体的产品。在案例中,由IDCardFactory
类扮演此角色。
类图
GitHub:DesignPatternStudy
——————参考《图解设计模式》