您的位置:首页 > 其它

学习设计模式——工厂方法

2015-08-12 10:03 302 查看
这里要先感谢《研磨设计模式》一书的作者,在讲述IoC/DI(控制反转/依赖注入)的时候深入浅出,让我有了清晰的理解,谢谢。

关于IoC/DI

依赖注入:应用程序依赖容器创建并注入它所需要的外部资源

控制反转:容器控制应用程序,有容器反向地向应用程序注入其所需要的外部资源

有效的分离了对象和所需要的外部资源,松耦合,有利于复用

适用于:

让父类在不知道具体实现的情况下,完成自身功能的调用,将具体的实现延迟到子类来实现。

子类通常是做选择来实现产品对象,而非直接实现功能。

优点:

良好的封装性,代码结构清晰——平行化代码结构,有什么样的产品对象就有什么样的产品工厂。或者由带参数的总工厂来生成所有的产品对象。

扩展性非常强——只需要适当的修改具体工厂类或者扩展一个工厂类,就可以实现变化。

可以屏蔽具体的产品类。

典型的解耦模式。

缺点:

具体产品对象和工厂方法的耦合。(关于这点个人认为是理所应当的,不算缺点,毕竟总有类是耦合的,在子类中耦合是解耦父类的一种途径,符合里氏替换原则)

产品类:

public interface Product {
void doSomething();
}

public class ProductA implements Product {
//这里私有没有特别的意思,就是不想被外界直接new
private ProductA(){
}
public void doSomething() {
System.out.println("it's ProductA");
}
}

public class ProductB implements Product {
private ProductB(){
}
public void doSomething() {
System.out.println("it's ProductB");
}
}


工厂类:

public abstract class Factory {
//这个就是工厂方法,是该模式的核心
public abstract Product createProduct();

//这里通过访问工厂的方法来调用具体产品的方法
//这样产品被封装的很好,而且扩展很强
public void doSomething() {
Product p = createProduct();
if(p!=null){
p.doSomething();
}
}
}

public class FactoryA extends Factory {
public Product createProduct() {
try {
Constructor<?> c = Class.forName(ProductA.class.getName()).getDeclaredConstructor();
c.setAccessible(true);
return (Product) c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}


客户端:

public class Client {
public static void main(String[] args) {
Factory a = new FactoryA();
a.doSomething();
}
}


结果:

it’s ProductA

扩展:

生成单例的工厂类:

public class SingletonFactory {
private static final Map<String, Object> objectMap = new HashMap<String, Object>();

public synchronized static <T> T createSingleton(Class<T> c) {
T t = null;
String className = c.getName();
try {
if (!objectMap.containsKey(className)) {
Class<?> c1 = Class.forName(className);
Constructor<?> constructor = c1.getDeclaredConstructor();
constructor.setAccessible(true);
t = (T) constructor.newInstance();
objectMap.put(className, t);
}
} catch (Exception e) {
e.printStackTrace();
}
return (T) objectMap.get(className);
}

public static void main(String[] args) {
Product productA1 = SingletonFactory.createSingleton(ProductA.class);
System.out.println(productA1);
Product productB1 = SingletonFactory.createSingleton(ProductB.class);
System.out.println(productB1);

Product productA2 = SingletonFactory.createSingleton(ProductA.class);
System.out.println(productA2);
Product productB2 = SingletonFactory.createSingleton(ProductB.class);
System.out.println(productB2);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: