设计模式—工厂方法模式
-
定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类
-
优点:
- 良好的封装性,代码结构清晰
- 良好的扩展性
- 典型的解耦架构
-
代码
-
首先定义一个产品的接口
public interface Product { void say(); } -
然后定义产品A,产品B 实现产品接口
public class ProductA implements Product { @Override public void say() { System.out.println("this is product A"); } } public class ProductB implements Product { @Override public void say() { System.out.println("this is product B"); } } -
现在定义一个抽象的工厂类 以及一个产品的工厂类,使用泛型,包含创建产品的方法
public abstract class AbstractProductFactory { public abstract <T extends Product> T createProduct(Class<T> cls); } public class ProductFactory extends AbstractProductFactory { @Override public <T extends Product> T createProduct(Class<T> cls) { Product product = null; try { product = (Product) Class.forName(cls.getName()).newInstance(); // product = cls.newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T) product; } } -
现在就可以测试工厂类去创建产品对象了
public class ProductFactoryTest { @Test public void testFactory(){ AbstractProductFactory factory = new ProductFactory(); Product a = factory.createProduct(ProductA.class); a.say(); ProductB b = factory.createProduct(ProductB.class); b.say(); } }从上面创建对象的方式可以看出没有使用new 关键字,也就实现了解耦
扩展
-
简单工厂模式
当一些模块只需要一个工厂类的时候,没有必要将工厂类实例化出来,这是就可以使用简单工厂模式来实现,去掉抽象工厂类并将工厂类的方法设为static
public class SimpleProductFactory { public static <T extends Product> T createProduct(Class<T> cls){ Product product = null; try { product = (Product) Class.forName(cls.getName()).newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T) product; } } -
多工厂模式
当项目比较复杂且产品的实现类比较多时,可以考虑为每个产品创建一个工厂类
public abstract class MultiAbstractFactory { public abstract Product createProduct(); } public class ProductAFactory extends MultiAbstractFactory { @Override public Product createProduct() { return new ProductA(); } } public class ProductBFactory extends MultiAbstractFactory { @Override public Product createProduct() { return new ProductB(); } } -
替代单例模式
利用反射代替单例模式
public class Singleton { //私有构造 private Singleton(){} } public class SingletonFactory { private static Singleton singleton; static { try { Class cls = Class.forName(Singleton.class.getName()); Constructor constructor = cls.getDeclaredConstructor(); constructor.setAccessible(true); singleton = (Singleton) constructor.newInstance(); } catch (Exception e) { e.printStackTrace(); } } public static Singleton getSingleton(){ return singleton; } }
-