`

工厂方法模式如何解决简单工作方法中的不足?

阅读更多

看《Java与模式》时,发现一个理解上的问题:说工厂方法模式可能解决简单工厂方法的不足,不过我的理解是工厂方法模式把原来的问题抛给客户端而没有真正解决掉。

 

先看简单工厂模式的示例代码。

 

class Factory{
	static Product createProduct(String type) {
		if(type.equalsIgnoreCase("apple")) {
			return new AppleProduct();
		}else if(type.equalsIgnoreCase("grape")) {
			return new GrapeProduct();
		}else {
			throw new IllegalArgumentException("Not type corresponding");
		}
	}
}

class Client_SimpleFactoryMethod {
	public static void main(String[] args) {
		String type = "grape";
		
		Product p = Factory.createProduct(type);
	}
}

interface Product{}

class AppleProduct implements Product{}
class GrapeProduct implements Product{}

 

它的缺点是如果有新产品时,Factory类中createProduct方法应该做相应调整以包含新产品类的加入。哪新加了产品类BananaProduct,我们得给createProduct方法新加一个分支:

   else if(type.equalsIgnoreCase("banana")) {

return new BananaProduct();

}

  这样不好, 因为这样的处理违背了“开闭”原则。

 

  为了解决这个问题,书中说引入工厂方法模式就可以了。 

 

  于是新加了每个产品类对应的工厂

interface ProduectFactory{
	Product createProduct();
}


class AppleProduectFactory implements ProduectFactory{

	public Product createProduct() {
		
		return new AppleProduct();
	}
}
class GrapeProduectFactory implements ProduectFactory{
	public Product createProduct() {
		
		return new GrapeProduct();
	}
}


class Client_FactoryMethod {
	public static void main(String[] args) {
		String type = "grape";
		
		ProduectFactory produectFactory=null;
		
		if(type.equalsIgnoreCase("apple")) {
			produectFactory = new AppleProduectFactory();
		}else if(type.equalsIgnoreCase("grape")) {
			produectFactory = new GrapeProduectFactory();
		}
			
		Product p = produectFactory.createProduct();
	}
}
 

对比上面的简单工厂方法,所不同的是,上面Client_SimpleFactoryMethod里的p的生成,是由Factory类的createProduct方法来据type种类判断具体生成哪种Product(直接生成);而在Client_FactoryMethod中的main里,先据type生成一个

ProduectFactory实现,再由这个ProduectFactory生成一个具体的Product

 

 

问题是, 新产品BananaProduct引入时,工厂这边新加一个BananaProductFactory没问题,而客户端得加一个相应的判断分支。看来不厚道啊,相当于把问题推给客户端。

 

 

我知道,上面我的理解有偏差的地方,工厂模式的价值不会这个偏差而有所降低,请问理解的偏差在哪?
分享到:
评论
5 楼 Sasori 2011-08-01  
我觉得工厂模式的意图是把工厂具体方法的实现与客户端对工厂的使用解耦,而不是动态的生成不同的工厂。
4 楼 rmn190 2010-07-12  
factoryClass = System.getProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME);

这样可以减少形如
        if(type.equalsIgnoreCase("apple")) { 
            produectFactory = new AppleProduectFactory(); 
        }else if(type.equalsIgnoreCase("grape")) { 
            produectFactory = new GrapeProduectFactory(); 
        } 
这样的if-else判断。

从而达到调用与实现的解耦合。

当然有些比这个getProperty更深一点的配置。 如Java\jdk1.6.0_18\jre\lib\security\java.security文件中“security.provider.1=sun.security.provider.Sun”类似property的配置。
3 楼 rmn190 2010-07-06  
引用
是抽象工厂


谢谢二位的回复。


不过我觉得有个问题,你说那是“抽象工厂”, 我不认为是, 抽象工厂的价值是“生产”出相关的一组产品,表现在代码上也就是一个接口(或抽象类)中有多个生成方法。这里的ProduectFactory接口只有一个方法, 也就不存在“相关”产品的说法了。


在闫宏所写的《Java与模式》一书中的第153页中有相关的例子代码“Creator”, 可参考。
2 楼 opmic 2010-07-06  
确实是抽象工厂
1 楼 键盘寄生物 2010-07-06  
其实 你这个不是工厂方法模式吧, 是抽象工厂。

个人理解,
在这里, 抽象工厂模式并不是用来简化判断分支的代码的,因为只有客户端知道什么时候该用哪段程序,
所以,这个判段代码不论是在客户端代码,还是在工厂里都是必须的。只能考虑通过配置,反射等方式来解决这个问题。


这里引入抽象工厂的主要目的

首要的 是用来将不同判断分支的代码分离,使方法轻量化。

第一你可以想象如果每个分支的代码段有上百行,如果全部写在一个方法里, 那是多么的臃肿,而不易阅读。

第二如果分支达到数十个,那这个方法体不仅臃肿,而且难以修改,阅读。

所以分离各个分支到单独的类是将工厂方法轻量化的可行办法。


其次  用来解耦工厂方法业务,提供扩展性。

考虑如下这个问题: 如果其中某个分支的代码不满足业务要求,需要替换怎么办?
如果将分支都写在工厂方法里,那将导致代码的修改,
第一,这个方法也许很臃肿,修改难度大。第二,如果又想恢复之前的业务,之前的代码由于修改丢失了,现在想恢复,只能再次修改代码了,扩展性极差。

如果使用抽象工厂模式,则只需增加新的业务工厂类。在修改客户端代码 就能实现了。同时不会造成原工厂的丢失修改。如果使用SPRING之类的注入方式,则连客户端都无需修改,只要改配置文件就行了。
具有良好的扩展性和低侵入性,符合 开、闭原则。

因此这里使用抽象工厂模式是正确的。

相关推荐

    工厂模式:简单工厂模式、工厂方法模式、抽象工厂模式

    工厂模式分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。 1. **简单工厂模式** 简单工厂模式是最简单的工厂模式实现,它提供一个静态方法或者类来创建对象,这个类通常被称为“工厂”。用户只需要...

    简单工厂模式-工厂方法模式-抽象工厂模式

    在软件设计模式中,工厂模式是一组非常基础且实用的设计模式,主要分为简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都是为了解决对象创建的问题,通过封装对象的创建过程,使得代码更加灵活,易于扩展和维护...

    用工厂方法模式重构简易计算器 源代码+实验报告

    《工厂方法模式在简易计算器重构中的应用》 在软件工程中,设计模式是解决常见问题的模板,它们为程序员提供了一种标准化的解决方案。工厂方法模式(Factory Method Pattern)是面向对象设计模式的一种,它在实际...

    设计模式-工厂方法模式

    工厂方法模式作为创建型模式中的一种,提供了一种创建对象的优雅方式,它不仅使对象的创建与使用分离,还极大地提高了系统的扩展性和灵活性。本文将深入探讨工厂方法模式的内部机制,以及通过反射和配置文件技术增强...

    简单工厂模式,工厂方法模式,抽象工厂模式

    在实际项目中,工具类库也经常采用工厂模式,如Apache Commons Lang中的`StringUtils`就是一个简单工厂的例子,它提供了静态方法来创建或处理字符串对象。 总结: 工厂模式是设计模式中的重要成员,它有效地解决了...

    抽象工厂模式+工厂方法模式+策略模式+类图实现手机加工厂

    它是简单工厂模式的一种扩展,它将产品实例化的责任委托给子类。在手机加工厂的场景中,每个手机品牌工厂都可以看作是工厂方法模式的一个实现,它们各自负责特定型号手机的组装和测试,例如iPhone工厂负责制造iPhone...

    C#中的简单工厂模式与工厂方法模式

    ### C#中的简单工厂模式与工厂方法模式 #### 一、引言 在软件工程领域,设计模式是一种被广泛接受的解决特定问题的最佳实践。在众多设计模式中,工厂模式因其能够灵活创建对象而备受推崇。本文将详细介绍两种常见...

    工厂模式(简单工厂,普通工厂,抽象工厂)代码java

    工厂模式分为三种主要类型:简单工厂模式、普通工厂模式(也称为工厂方法模式)和抽象工厂模式。 1. **简单工厂模式**: - 简单工厂模式中,有一个中心工厂类,它负责根据输入条件(通常是一个参数)来创建具体的...

    设计模式之工厂方法、简单工厂、抽象工厂

    简单工厂模式是一种静态工厂方法,它通常包含一个类,该类负责创建其他类的实例。客户端通过调用静态方法获取所需对象,而不必了解具体创建对象的逻辑。虽然简单工厂模式易于理解和实现,但它的缺点在于违反了“开...

    c++设计模式-工厂方法模式

    描述中的“创建型模式-工厂方法模式-最简单的源码-qt工程”表明,这个压缩包可能包含了一个基于Qt框架的C++项目,该项目展示了工厂方法模式的简单应用。Qt是一个跨平台的应用程序开发框架,广泛用于GUI编程,但也...

    第5章_工厂方法模式.ppt

    在简单工厂模式中,所有的产品都是由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,严重影响了系统的灵活性和扩展性,而工厂方法模式则可以很好地解决这一问题。

    C#设计模式(3)——工厂方法模式.pdf

    工厂方法模式之所以可以解决简单工厂的模式,是因为它的实现把具体产品的创建推迟到子类中,此 时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式就可以允许 系统不修改工厂类...

    设计模式之工厂方法

    通过运行这些示例代码,你可以更深入地理解工厂方法模式的工作原理及其在实际项目中的应用。 设计模式的学习不仅仅是理论上的了解,更重要的是将这些模式运用到实际的项目中去。工厂方法模式在软件设计中扮演着重要...

    Java 工厂模式 抽象工厂 工厂方法模式

    本文将深入探讨Java中的工厂模式,包括基本的工厂模式、抽象工厂模式以及工厂方法模式。 **工厂模式**:工厂模式的核心思想是提供一个创建对象的接口,但让实现这个接口的类来决定实例化哪一个类。这样,客户端无需...

    简单工厂模式和工厂方法模式

    简单工厂模式和工厂方法模式是面向对象设计中的两种常见的创建型设计模式,它们在软件工程中扮演着重要的角色,主要用于解决对象的创建问题,降低了代码的耦合度,提高了系统的可扩展性和可维护性。 首先,我们来看...

    简单工厂模式、工厂模式、抽象工厂模式案例(C++实现)

    在这个压缩包中,包含了三种工厂模式的C++实现:简单工厂模式、工厂方法模式以及抽象工厂模式。让我们一一探讨这些模式。 1. 简单工厂模式: 简单工厂模式是一种静态工厂方法,它提供一个公共的工厂类来创建对象。...

    设计模式之-工厂方法-FactoryMethod

    简单工厂模式中,有一个静态工厂类负责创建所有产品,而在工厂方法模式中,产品创建的责任被转移到了具体的子类中,这样更符合面向对象的原则,同时也更利于扩展。 总的来说,工厂方法模式是一种实用的设计模式,它...

    52-简单工厂工厂方法模式抽象工厂1

    在软件设计模式中,工厂方法模式和抽象工厂模式是两种常用的创建型模式,它们都用于对象的创建,但各有特点和适用场景。首先,我们来理解这两种模式的基本概念。 **简单工厂模式**: 简单工厂模式是一种较为初级的...

    简单工厂模式与工厂方法模式

    简单工厂模式和工厂方法模式是面向对象设计中的两种常见的设计模式,它们都属于创建型模式,主要用于解决对象的创建问题,使得代码更加灵活,易于扩展。这两种模式在软件开发中有着广泛的应用,尤其是在需要根据不同...

Global site tag (gtag.js) - Google Analytics