创建型模式之一 工厂模式(Java实现)(一)
2006-10-22 21:04
465 查看
------------------------------创建型模式之一-------工厂模式(Java实现)(一)-------------------------
一、简介:
我们不妨把工厂模式分成以下三种:
1) 简单工厂:不要求产品之间有等级关系,甚至是可以使一些不相关的产品(我们知道所有的类都有公共的基类Object,这点共同点就足够了),我们不妨称之为“杂货工厂”。虽然说是简单工厂,但是它的创造的产品确是丰富多彩的。加上 java的反射功能我们我们甚至可以创建万事万物------万事皆是对象。像java.text.DataFormat,就是一个Data的简单工厂,用来格式化并产生本地的Data.
2) 工厂方法:工厂方法又称为虚拟构造子。要求产品之间有等级关系。构造函数固有的特点,使它不能被继承,当然更不能使用多态来动态的灵活的创建实例,这往往会使程序中到处充满硬编码的new,当我们的需要变更时,我们不得不更改大量的new语句来适应需求。有时我们也会遇到这种情况:我们要实例化一个类的子类,而这个类与具体应用相关,这时我们不可能知道要实例化哪个子类。我们的工厂方法给我们提供了虚拟的构造子,它使一个类的实例化延迟到其子类。其实简单工厂也被称为一种工厂方法,只是我们是通过参数来传递我们要创建的的信息,从来决定要创建的产品,在GOF的《设计模式》中被成为参数化的工厂方法。但二者实现及应用场景不同,我们不妨分开来说并加以比较。
3) 抽象工厂:抽象工厂往往与多个产品系列的创建有关,并且要求产品之间有等级关系。举个生活中的例子来说,许多电脑厂商都生产系列机,所谓的系列机是指体系结构相同的档次不同的机器。我们不妨假设不同的系列机的部件是不兼容的。这可能是抽象工厂的最佳使用时机,他的优点是:i)有利于产品的的一致性,从而不会产生不同系列产品的不兼容,因为我们使用一个工厂只会生产一系列的产品。ii)容易交换不同系列的产品-----只需要更换掉工厂即可。
以上是工厂模式的一个简介,下面我们将分别介绍:
二)简单工厂:
简单工厂其实就是根据参数来决定要创建的类,说是简单,其实他常常被用来创建强大的功能。像现在比较流行的IOC(Inversion of Control),其实就是让程序员从繁杂的对象的创建中解脱出来,与以前相比让角色反转,让容器来负责类的实例化,这与java 的垃圾回收机制有着异曲同工之妙,都是让一切简化。其实现思想其实很简单,就是一个很大的工厂,一个工程中的所有的对象都可以从中取,该工厂从.xml配置文件中读取要实例化的类的信息及其对象间的依赖关系,并将这些依赖关系注入到对象中,Bean factory给我们创建和管理bean,不仅可以减轻我们的负担,更重要的是产生了松耦合的系统。
类似如下:
class BeanFactory{
static Object getBean(String className){
return Class.forName(className).newInstance();
}
//…从xml中读去配置信息来实例化各个对象
}
以后的步骤基本上是:从.xml文件中读去Bean的信息,提取出bean的名字beanName这样调用一下XxxBean bean = BeanFactory.getBean(beanName)就得到想要的 bean了;当然这只是简单的说,考虑到灵活性还需要许多的模式一起来完成。
其实简单工厂的主要优点就是分离了产品与产品的创建,用户只需要与工厂打交道,而不必与具体的产品打交道。像Spring中提供的BeanFactory,被称为Bean的Container,用户只需要从BeanFactoy中得到所需要的bean,而不需要关注如何创建,之所以是 Container 是因为BeanFactory会缓存这些bean,但是在开始的出于性能的考虑,不会一下子产生所有的bean,而是采用lazy load方式.当你把bean设置为Singleton的时候,BeanFactory会始终返那个缓存的实例,而不真正创建。
象我以前写的那个SNLCompiler就使用了这个模式,实现如下:
public ActionFactory{
Action []actionCache = new Action[]{
new Action1(),new Action2(),
//…
new Action106()
}
public Action create ActionInstance(int i){
return actionCache[i];
}
}
actionCache 是Action的缓存,每个Action 都是一个采用Command的模式的一个动作,由于这些Action都是无状态的(没有数据成员),性能不会受到影响,并且由于缓存作用而使
这些实例能够预先创建并且得到共享,当然这只是附带的性能上好处。我在使用这个模式的主要目的是:提供一个数字与一个动作的映射。如果从SNLCompiler的背景中来说,就是从LL(1)文法的动作表中(一个非终极符和输入token流的匹配表,表中填写使用的匹配的文法的序号),找到对应的文法序号,并且每条文法对应一个处理动作(Action)。从而根据找到的文法序号来产生对应的Action,然后使用多态来处理不同的文法:
Action action = factory.createActionInstance(num);
predict(action);
从而避免在predict中使用庞大的 switch…case的判断。
以上举的是实际中遇到的例子,为了便于理解,我们也写一个被人称为“玩具”一样的例子。
举个水果加工场的例子吧:
//FuitFactory水果工厂类:
public class FruitFactory{
public Fruit createFruit(String fruitName){
if(fruitName .equals(“apple”)){
return new Apple();
}else if(fruitName.equals(“pear”)){
return new Pear();
}else if(fruitName.equals(“banana”)){
return new Banana();
}
}
}
public interface Fruit{
//…
}
public class Apple implements Fruit{
public Apple(){
}
//…
}
public class Pear implements Fruit{
public Pear (){
}
//…
}
public class Banana implements Fruit{
public Banana (){
}
//…
}
public class Test{
public static void main(String []args){
FruitFactory factory = new FruitFactory();
Apple apple = (Apple)factory.createFruit(“apple”);
//…
}
}
上面的实现有个缺点,就是当产品增加时需要修改Factory。当然你可以使用java的反射来动态的事例化类(Class.forName(classname).newInstace()),来克服。
待续 之二 ---------Factory Method
一、简介:
我们不妨把工厂模式分成以下三种:
1) 简单工厂:不要求产品之间有等级关系,甚至是可以使一些不相关的产品(我们知道所有的类都有公共的基类Object,这点共同点就足够了),我们不妨称之为“杂货工厂”。虽然说是简单工厂,但是它的创造的产品确是丰富多彩的。加上 java的反射功能我们我们甚至可以创建万事万物------万事皆是对象。像java.text.DataFormat,就是一个Data的简单工厂,用来格式化并产生本地的Data.
2) 工厂方法:工厂方法又称为虚拟构造子。要求产品之间有等级关系。构造函数固有的特点,使它不能被继承,当然更不能使用多态来动态的灵活的创建实例,这往往会使程序中到处充满硬编码的new,当我们的需要变更时,我们不得不更改大量的new语句来适应需求。有时我们也会遇到这种情况:我们要实例化一个类的子类,而这个类与具体应用相关,这时我们不可能知道要实例化哪个子类。我们的工厂方法给我们提供了虚拟的构造子,它使一个类的实例化延迟到其子类。其实简单工厂也被称为一种工厂方法,只是我们是通过参数来传递我们要创建的的信息,从来决定要创建的产品,在GOF的《设计模式》中被成为参数化的工厂方法。但二者实现及应用场景不同,我们不妨分开来说并加以比较。
3) 抽象工厂:抽象工厂往往与多个产品系列的创建有关,并且要求产品之间有等级关系。举个生活中的例子来说,许多电脑厂商都生产系列机,所谓的系列机是指体系结构相同的档次不同的机器。我们不妨假设不同的系列机的部件是不兼容的。这可能是抽象工厂的最佳使用时机,他的优点是:i)有利于产品的的一致性,从而不会产生不同系列产品的不兼容,因为我们使用一个工厂只会生产一系列的产品。ii)容易交换不同系列的产品-----只需要更换掉工厂即可。
以上是工厂模式的一个简介,下面我们将分别介绍:
二)简单工厂:
简单工厂其实就是根据参数来决定要创建的类,说是简单,其实他常常被用来创建强大的功能。像现在比较流行的IOC(Inversion of Control),其实就是让程序员从繁杂的对象的创建中解脱出来,与以前相比让角色反转,让容器来负责类的实例化,这与java 的垃圾回收机制有着异曲同工之妙,都是让一切简化。其实现思想其实很简单,就是一个很大的工厂,一个工程中的所有的对象都可以从中取,该工厂从.xml配置文件中读取要实例化的类的信息及其对象间的依赖关系,并将这些依赖关系注入到对象中,Bean factory给我们创建和管理bean,不仅可以减轻我们的负担,更重要的是产生了松耦合的系统。
类似如下:
class BeanFactory{
static Object getBean(String className){
return Class.forName(className).newInstance();
}
//…从xml中读去配置信息来实例化各个对象
}
以后的步骤基本上是:从.xml文件中读去Bean的信息,提取出bean的名字beanName这样调用一下XxxBean bean = BeanFactory.getBean(beanName)就得到想要的 bean了;当然这只是简单的说,考虑到灵活性还需要许多的模式一起来完成。
其实简单工厂的主要优点就是分离了产品与产品的创建,用户只需要与工厂打交道,而不必与具体的产品打交道。像Spring中提供的BeanFactory,被称为Bean的Container,用户只需要从BeanFactoy中得到所需要的bean,而不需要关注如何创建,之所以是 Container 是因为BeanFactory会缓存这些bean,但是在开始的出于性能的考虑,不会一下子产生所有的bean,而是采用lazy load方式.当你把bean设置为Singleton的时候,BeanFactory会始终返那个缓存的实例,而不真正创建。
象我以前写的那个SNLCompiler就使用了这个模式,实现如下:
public ActionFactory{
Action []actionCache = new Action[]{
new Action1(),new Action2(),
//…
new Action106()
}
public Action create ActionInstance(int i){
return actionCache[i];
}
}
actionCache 是Action的缓存,每个Action 都是一个采用Command的模式的一个动作,由于这些Action都是无状态的(没有数据成员),性能不会受到影响,并且由于缓存作用而使
这些实例能够预先创建并且得到共享,当然这只是附带的性能上好处。我在使用这个模式的主要目的是:提供一个数字与一个动作的映射。如果从SNLCompiler的背景中来说,就是从LL(1)文法的动作表中(一个非终极符和输入token流的匹配表,表中填写使用的匹配的文法的序号),找到对应的文法序号,并且每条文法对应一个处理动作(Action)。从而根据找到的文法序号来产生对应的Action,然后使用多态来处理不同的文法:
Action action = factory.createActionInstance(num);
predict(action);
从而避免在predict中使用庞大的 switch…case的判断。
以上举的是实际中遇到的例子,为了便于理解,我们也写一个被人称为“玩具”一样的例子。
举个水果加工场的例子吧:
//FuitFactory水果工厂类:
public class FruitFactory{
public Fruit createFruit(String fruitName){
if(fruitName .equals(“apple”)){
return new Apple();
}else if(fruitName.equals(“pear”)){
return new Pear();
}else if(fruitName.equals(“banana”)){
return new Banana();
}
}
}
public interface Fruit{
//…
}
public class Apple implements Fruit{
public Apple(){
}
//…
}
public class Pear implements Fruit{
public Pear (){
}
//…
}
public class Banana implements Fruit{
public Banana (){
}
//…
}
public class Test{
public static void main(String []args){
FruitFactory factory = new FruitFactory();
Apple apple = (Apple)factory.createFruit(“apple”);
//…
}
}
上面的实现有个缺点,就是当产品增加时需要修改Factory。当然你可以使用java的反射来动态的事例化类(Class.forName(classname).newInstace()),来克服。
待续 之二 ---------Factory Method
相关文章推荐
- 设计模式(Design Pattern) - 创建型模式(Creational Pattern) - 简单工厂模式(Simple Factory Pattern) - Java实现
- 设计模式(Design Pattern) - 创建型模式(Creational Pattern) - 工厂模式(FactoryMethod) - Java实现
- 设计模式(Design Pattern) - 创建型模式(Creational Pattern) - 抽象工厂模式(Abstract Factory) - Java实现
- Java设计模式之创建型模式-工厂模式(Factory)
- java语言实现创建型设计模式—抽象工厂模式
- 设计模式(Design Pattern) - 创建型模式(Creational Pattern) - 原型模式(Prototype) - Java实现
- 设计模式(Design Pattern) - 创建型模式(Creational Pattern) - 建造者模式(Builder) - Java实现
- 设计模式(Design Pattern) - 创建型模式(Creational Pattern) - 单例模式(Singleton Pattern) - Java实现
- Singleton 模式 Java,c++实现
- java实现的23种设计模式 (个人推荐)
- Java多线程-工具篇-BlockingQueue(实现生产者和消费者模式)
- Java 实现工厂设计模式的三种方式
- JAVA实现在excel插入图片(POI模式)
- java工厂模式应用——多数据库分页实现(结合Spring)
- 二、创建型模式——工厂模式
- (Builder)建造者模式的Java实现
- Strategy 模式 java 实现
- 使用工厂模式、策略模式实现BASE64,MD5,SHA,HMAC,DES各种加密算法
- JAVA设计模式(03):创建型-单例模式(Singleton)
- (Mediator)中介者模式的Java实现(加修改)