最近在看设计模式之禅,书的内容以讲故事的方式介绍了设计模式,强力推荐。
以下是个人对于工厂模式的理解
/*
* 工厂模式
* 优点
* 封装性好,降低模块耦合。
* 扩展性好
*/
public class MyMain {
public static void main(String[] args) {
// 实例化一个工厂
AbstractFactory factory = new Factory();
// 用工厂创建产品A,B,C
System.out.println("工厂开始创造产品A");
Product productA = factory.createProduct(ProductA.class);
productA.say();
System.out.println("工厂开始创造产品B");
Product productB = factory.createProduct(ProductB.class);
productB.say();
System.out.println("工厂开始创造产品C");
Product productC = factory.createProduct(ProductC.class);
productC.say();
// 用静态工厂创建产品D
System.out.println("静态工厂开始创造产品A");
Product staticProductA = StaticFactory.createProduct(ProductA.class);
staticProductA.say();
// 用多工厂创建产品A,B
System.out.println("A产品专属工厂开始创造产品A");
Product ProductA2 = new ProductAFactory().createProduct();
ProductA2.say();
System.out.println("B产品专属工厂开始创造产品B");
Product ProductB2 = new ProductBFactory().createProduct();
ProductB2.say();
//单例工厂创造产品A
System.out.println("单例工厂创造的产品D");
SingletonFactory.getProductD().say();
//懒加载工厂获取产品A,B,C
System.out.println("懒加载工厂创造的产品A");
Product lazyProductA=LazyFactory.creatProduct("A");
lazyProductA.say();
}
}
// 核心
// 定义一个抽象的工厂
abstract class AbstractFactory {
// 定义抽象方法创造基础了抽象产品类的产品,用泛型技术限定参数必须是产品的实现类
public abstract <T extends Product> T createProduct(Class<T> Product);
}
// 定义一个抽象的产品类
abstract class Product {
// 输出产品的信息
public void say() {
System.out.print("我是产品:");
type();
};
// 输出产品的类型
public abstract void type();
}
// 继承抽象工厂,实现工厂的方法
class Factory extends AbstractFactory {
@Override
public <T extends Product> T createProduct(Class<T> Product) {
// 定义一个产品对象
Product product = null;
try {
// 根据参数实例化所需要的产品,并返回
product = (T) Class.forName(Product.getName()).newInstance();
} catch (Exception e) {
System.out.println("创造产品出现错误");
}
return (T) product;
}
}
// 继承抽象产品,实现产品的方法
class ProductA extends Product {
@Override
public void type() {
System.out.println("类型为A号");
}
}
class ProductB extends Product {
@Override
public void type() {
System.out.println("类型为B号");
}
}
class ProductC extends Product {
@Override
public void type() {
System.out.println("类型为C号");
}
}
// 扩展
// 静态工厂(简单工厂),只需要一个工厂,去除工厂抽象类,所有工厂扩展不方便
class StaticFactory {
public static <T extends Product> T createProduct(Class<T> Product) {
// 定义一个产品对象
Product product = null;
try {
// 根据参数实例化所需要的产品,并返回
product = (T) Class.forName(Product.getName()).newInstance();
} catch (Exception e) {
System.out.println("创造产品出现错误");
}
return (T) product;
}
}
// 多工厂,为每个产品类提供一个工厂,维护扩展都不方便,但结构清晰
// 多工厂抽象
abstract class AbstractFactory2 {
public abstract Product createProduct();
}
// A产品专属工厂
class ProductAFactory extends AbstractFactory2 {
@Override
public Product createProduct() {
return new ProductA();
}
}
// B产品专属工厂
class ProductBFactory extends AbstractFactory2 {
@Override
public Product createProduct() {
return new ProductB();
}
}
// 单例工厂,用于管理单例
//特殊的单例产品
class ProductD{
private ProductD() {};
public void say() {
System.out.println("DDDDD....");
};
}
//通过反射方式创建private修饰构造函数的ProductD
class SingletonFactory {
private static ProductD Productd;
static {
try {
Class cl = Class.forName(ProductD.class.getName());
// 获得无参构造
Constructor constructor = cl.getDeclaredConstructor();
// 设置无参构造是可访问的
constructor.setAccessible(true);
// 产生一个实例对象
Productd = (ProductD)constructor.newInstance();
} catch (Exception e) {
// 异常处理
System.out.println("单例工厂创造产品失败");
}
}
public static ProductD getProductD() {
return Productd;
}
}
//懒加载工厂
class LazyFactory{
//产品集合
private static final Map<String, Product> productMap=new HashMap<>();
//synchronized保证线程安全根据参数获得产品
public static synchronized Product creatProduct(String ProductType) {
Product product=null;
if(productMap.containsKey(ProductType))
product=productMap.get(ProductType);
else {
switch (ProductType) {
case "A":
product=new ProductA();
break;
case "B":
product=new ProductB();
break;
case "C":
product=new ProductC();
break;
}
productMap.put(ProductType, product);
}
return product;
}
}