`
tonyan416
  • 浏览: 29229 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

设计模式之工厂模式 Factroy Method

阅读更多
基本概念

FactoryMethod是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式了.简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类.Factory Method把创建这些实例的具体过程封装起来了,简化了客户端的应用,也改善了程序的扩展性,使得将来可以做最小的改动就可以加入新的待创建的类. 通常我们将Factory Method作为一种标准的创建对象的方法,当发现需要更多的灵活性的时候,就开始考虑向其它创建型模式转化

上回我们简单介绍了simple factory的工作原理 这回我们看看他的爸爸 factory method.其实按我来看,simple factory就是一个特殊的factory method(从某方面来说的话)

Fruit.java
public abstract class Fruit {
public abstract void grow();
public String name;
public Fruit(String name) {
	this.name=name;
}
}

Grape.java
public class Grape extends Fruit{
public Grape(String name) {
		super(name);	
	}
@Override
public void grow() {
	System.out.println("I grows grape");	
}
}

StrawBerry.java
public class StrawBerry extends Fruit {
public StrawBerry(String name) {
		super(name);		
	}
@Override
public void grow() {
	System.out.println("I grows strawberry");
}
}

FruitFactory.java
public abstract class FruitFactory {
 protected abstract Fruit factoryMethod(String name);
 public void anOperation(String name){
	    Fruit f = factoryMethod(name);
	    System.out.println("I choose I like: " + f.name);
	    f.grow();
	  }
}

GrapeFactory.java
public class GrapeFactory extends FruitFactory{

@Override

protected Fruit factoryMethod(String name) {
  return new Grape(name + " (created by GrapeFactory)");
}
}

StrawBerryFactory.java
public class StrawBerryFactory extends FruitFactory {
@Override
protected Fruit factoryMethod(String name) {
	// TODO Auto-generated method stub
	return new StrawBerry(name + " (created by StrawBerryFactory)");
}
}

Client.java
public class Client {
public static void main(String args[]){
	  FruitFactory ff1 = new GrapeFactory(); 
	  FruitFactory ff2 = new StrawBerryFactory();
	    ff1.anOperation("Fruit one");
	    ff2.anOperation("Fruit two");
}
}

应用工厂方法模式来解决的思路
        仔细分析上面的问题,事实上在实现导出数据的业务功能对象里面,根本就不知道究竟要使用哪一种导出文件的格式,因此这个对象本就不应该和具体的导出文件的对象耦合在一起,它只需要面向导出的文件对象的接口就好了。
        但是这样一来,又有新的问题产生了:接口是不能直接使用的,需要使用具体的接口实现对象的实例。
        这不是自相矛盾吗?要求面向接口,不让和具体的实现耦合,但是又需要创建接口的具体实现对象的实例。怎么解决这个矛盾呢?
        工厂方法模式的解决思路很有意思,那就是不解决,采取无为而治的方式:不是需要接口对象吗,那就定义一个方法来创建;可是事实上它自己是不知道如何创建这个接口对象的,没有关系,那就定义成抽象方法就好了,自己实现不了,那就让子类来实现,这样这个对象本身就可以只是面向接口编程,而无需关心到底如何创建接口对象了。
工厂方法模式的优缺点
可以在不知具体实现的情况下编程
  工厂方法模式可以让你在实现功能的时候,如果需要某个产品对象,只需要使用产品的接口即可,而无需关心具体的实现。选择具体实现的任务延迟到子类去完成。更容易扩展对象的新版本
    工厂方法给子类提供了一个挂钩,使得扩展新的对象版本变得非常容易。比如上面示例的参数化工厂方法实现中,扩展一个新的导出Xml文件格式的实现,已有的代码都不会改变,只要新加入一个子类来提供新的工厂方法实现,然后在客户端使用这个新的子类即可。
    另外这里提到的挂钩,就是我们经常说的钩子方法(hook),这个会在后面讲模板方法模式的时候详细点说明。

    工厂方法除了创造产品对象外,在连接平行的类层次上也大显身手。这个在前面已经详细讲述了。
具体产品对象和工厂方法的耦合性
    在工厂方法模式里面,工厂方法是需要创建产品对象的,也就是需要选择具体的产品对象,并创建它们的实例,因此具体产品对象和工厂方法是耦合的。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics