JDK与设计模式:工厂模式
2016-06-18 09:46
627 查看
1、简单工厂方法模式
简单工厂模式又称静态工厂方法模式。从命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定那一个产品类应当被实例化。简单工厂方法模式是一种创建型模式。
组成:
1)
工厂类角色:这是本模式的核心,含有一定的业务逻辑和判断逻辑。在java中它往往由一个具体类实现。
2)
抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
3)
具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
类图:
代码:
2、工厂方法模式
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。工厂方法模式是一种创建型模式。
组成:
1) 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2) 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3) 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4) 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的统一工厂类。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活
起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。可以看出工厂角色的结构也是符合开闭原则的!
类图:
代码:
适用场景:客户端不知道其所需要的对象的类。只需要知道对应的工厂,通过工厂获取需要的产品对象。抽象工厂类通过子类来指定创建那个对象,由子类类确定具体创建那个对象,利用面向对象多态性和里氏代换原则,在运行时,子类对象覆盖父类对象,从而使得系统更容易扩展。
总结:在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。但是在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
JDK中工厂方法模式应用
参考资料:《大话设计模式》、《HeadFirst设计模式》
简单工厂模式又称静态工厂方法模式。从命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定那一个产品类应当被实例化。简单工厂方法模式是一种创建型模式。
组成:
1)
工厂类角色:这是本模式的核心,含有一定的业务逻辑和判断逻辑。在java中它往往由一个具体类实现。
2)
抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
3)
具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
类图:
代码:
public static Product createProduct(String type){ if(type.equals("A")){ return new ConcreteProductA(); }else if(type.equals("B")){ return new ConcreteProductB(); }else{ return null ; } }
2、工厂方法模式
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。工厂方法模式是一种创建型模式。
组成:
1) 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2) 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3) 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4) 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的统一工厂类。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活
起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。可以看出工厂角色的结构也是符合开闭原则的!
类图:
代码:
abstract class Product{ } abstract class Factory{ public Product createProduct(){ return null; } } class ConcreteProduct extends Product{ } class ConcreteFactory extends Factory{ public Product createProduct(){ return new ConcreteProduct(); } }
适用场景:客户端不知道其所需要的对象的类。只需要知道对应的工厂,通过工厂获取需要的产品对象。抽象工厂类通过子类来指定创建那个对象,由子类类确定具体创建那个对象,利用面向对象多态性和里氏代换原则,在运行时,子类对象覆盖父类对象,从而使得系统更容易扩展。
总结:在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。但是在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
JDK中工厂方法模式应用
class Class<T> implements java.io.Serializable,... {
abstract class Product{ } abstract class Factory{ public Product createProduct(){ return null; } } class ConcreteProduct extends Product{ } class ConcreteFactory extends Factory{ public Product createProduct(){ return new ConcreteProduct(); } }
// 通过静态工厂方法 static Class<?> forName(String className),获取到具体Class工厂对象。
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true,
ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
//然后通过具体Class工厂对象newInstance(),生产该工厂中的具体实例产品对象。
@CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class<?>[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// Disable accessibility checks on the constructor
// since we have to do the security check here anyway
// (the stack depth is wrong for the Constructor's
// security check to work)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw new InstantiationException(getName());
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
....
....
}
参考资料:《大话设计模式》、《HeadFirst设计模式》
相关文章推荐
- PropertyChangeListener简单理解
- JDK动态代理VS CgLib
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- Ubuntu 安装 JDK 问题
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解