`
eyesmore
  • 浏览: 363244 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

工厂模式:静态工厂

阅读更多

     一般认为简单工厂模式,产品部分能够在OCP原则下应对变化(这也恰恰是使用静态工厂的意义所在),但是当新增一种产品时候,我们的工厂的static createProduct还是必须被迫修改代码,也就是不具有应对变化的能力。

     本文提供了一种先注册后使用的办法,能够对静态工厂应对变化方面有一定的改善。可能不一定具有太大的使用价值,但对于拓展思路有点启示。

     阅读前,先推荐阅读 http://www.iteye.com/topic/180972   主题:工厂模式----易懂版(转)

 

package com.eyesmore.staticfactory.spi;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.eyesmore.staticfactory.BenzCar;

public class CarRegisteryFactory {

	private static Map<String,Car> registery = Collections.synchronizedMap(new HashMap<String,Car>());
	
	public static boolean registerCar(String name,Car car) {
		if(registery.containsKey(name)) {//注意:可能导致非线程安全




			return false;
		}
		registery.put(name, car);
		return true;
	}
	
	public static boolean unregisterCar(String name) {
		if(!registery.containsKey(name)) {
			return false;
		}
		registery.remove(name);
		return true;
	}
	
	public static boolean containsCar(String name) {
		return registery.containsKey(name);
	}
	
	public static Car createCar(String name) throws NoSuchCarException {
		if(!registery.containsKey(name)) {
			throw new NoSuchCarException("CarName = "+name);
		}
		/* create a new instance according to the registered one*/
		Car template = registery.get(name);
		return cloneInstance(template);




	}

	/* Extract Method from createCar */
	private static Car cloneInstance(Car template) {
		Car cloneInstance = null;
		/*
		 * clone an instance by ObjectOutputStream/ObjectInputStream
		 * */
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(template);
			ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
			cloneInstance = (Car)ois.readObject();
			
		} catch (IOException e) {//一般只会在调试时发生
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return cloneInstance;
	}
	
	
	
	public static void main(String[] args) {

		Car templateInstance = new BenzCar();
		CarRegisteryFactory.registerCar("Benz", templateInstance);
		Car car1 = CarRegisteryFactory.createCar("Benz");
		car1.drive();
		Car car2 = CarRegisteryFactory.createCar("Benz");
		car2.drive();
		System.out.println("(templateInstance == car1):"+(templateInstance == car1));
		System.out.println("(templateInstance == car2):"+(templateInstance == car2));
		System.out.println("(car1 == car2):"+(car1 == car2));//创建的是不同的对象


	}

}

 

 

其他代码:

package com.eyesmore.staticfactory.spi;

import java.io.Serializable;

public interface Car extends Serializable {//重要对象一般推荐继承Serializable 

	public void drive();
}

 

package com.eyesmore.staticfactory;

import com.eyesmore.staticfactory.spi.Car;

public class BenzCar implements Car {

	private static final long serialVersionUID = -6849794470754667222L;
	
	public void drive() {
		System.out.println("Benz ...");
	}

}

 

 

如果此时要增加Audi,我们的CarRegisterFactory足以应对它。

 

package com.eyesmore.staticfactory;

import com.eyesmore.staticfactory.spi.Car;

public class AudiCar implements Car {

	private static final long serialVersionUID = -6849794470754667111L;
	
	public void drive() {
		System.out.println("Audi ...");
	}

}

 

使用时候,先在CarRegisterFactory.registerCar("Audi",new AudiCar());

然后要用的时候则CarRegisterFactory.createCar("Audi");

 

当然也可以通过配置文件+发射的方式对注册器进行初始化。另外,静态工厂的那个方法的实现有很多种不同的策略,比如log4j的Logger.getLogger,被创建的对象会被重复使用。

 

==============================================================

【补充】  以上我们通过createInstance()都是重新克隆出一个新的对象实例。当然,很多时候我们并不重新生成新的对象。单例模式我们经常用到Factory.getInstance(); 但是这样导致一个程序只能有一个实例,我们常常需要Factory去维护一个对象名称到对象实例的一个映射关系,典型的就是Log4j,Logger.getLogger(name)。

==============================================================

// store instances of pools
	private static Map<String,SockIOPool> pools =
		new HashMap<String,SockIOPool>();



	// empty constructor
	protected SockIOPool() { }


/** 
	 * Factory to create/retrieve new pools given a unique poolName. 
	 * 
	 * @param poolName unique name of the pool
	 * @return instance of SockIOPool
	 */
	public static synchronized SockIOPool getInstance( String poolName ) {
		if ( pools.containsKey( poolName ) )
			return pools.get( poolName );

		SockIOPool pool = new SockIOPool();
		pools.put( poolName, pool );

		return pool;
	}

	/** 
	 * Single argument version of factory used for back compat.
	 * Simply creates a pool named "default". 
	 * 
	 * @return instance of SockIOPool
	 */
	public static SockIOPool getInstance() {
		return getInstance( "default" );
	}


 

 

使用静态工厂模式,目的可能不一定是考虑把对象的创建局部在Factory内部,以后修改时只需要修改工厂的代码。从Log4j的例子可以看出使用静态工厂模式还有个好处是方便对象实例的存取,因为如果一个重要对象在很多地方都需要使用,那么作为参数传递还是很不方便的,这常常迫使我们在面向对象时怀念以前过程化程序语言中的全程过程,也就是java的静态方法。

 

分享到:
评论

相关推荐

    09-IoC配置-静态工厂与实例工厂创建bean

    (3)静态工厂:工厂本身不用创建对象;通过静态方法调用,对象 = 工厂类.工厂方法名(); (4)实例工厂:工厂本身需要创建对象;如下: 工厂类 工厂对象 = new 工厂类(); 工厂对象.getAirPlane(“张三”);

    工厂模式详尽源码

    Java 常用创建型设计模式中,工厂模式下的三种子模式:简单工厂(静态工厂)、工厂方法模式、抽象工厂模式的源码

    java设计模式

    1.工厂模式 a.简单工厂(静态工厂):一个工厂类根据传入的参数来决定创建哪一类产品的实例,它的核心是工厂类,由于 工厂类中的创建方法是静态的(static)所以简单工厂又称为静态工厂。 b.工厂方法: 在工厂方法...

    PhpPatterns:php设计模式

    静态工厂模式 :check_mark_button: 原型模式 建造者模式 结构型模式实例 改进模式 享元模式 外观模式 适配器模式 :check_mark_button: 装饰器模式 组合模式 代理模式 过滤器模式 行为型模式实例 模板模式 策略模式 :...

    java 简单工厂模式 源代码

    从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂...

    Java设计模式:工厂模式——图文+代码示例(通俗易懂)

    先来看看,简单工厂模式——也叫静态工厂模式,这里举个例子:你要去买一台手机,你不用关心手机是怎么生产出来的,里面的零件具体又是怎么制造的,这些通通都交给工厂去处理,你尽管去买手机就好了。 简单工厂模式...

    JAVA设计模式(单态模式和简单工厂模式)

    简单工厂模式又叫静态工厂模式,顾名思义,它是用来实例化目标类的静态类。下面我主要通过一个简单的实例说明简单工厂及其优点。 单态模式的定义: Singleton模式主要作用是保证在Java应用程序中,一个类Class只有...

    Java设计模式之静态工厂模式详解

    主要介绍了Java设计模式之静态工厂模式,简单说明了静态工厂模式的概念、原理、实现与使用方法,需要的朋友可以参考下

    工厂模式:初识+工厂方法模式案例

    工厂模式讲解 ————————————分割线—————————— 首先我们提个问题,我们为什么需要工厂方法模式?  在我们编码的过程中,我们有些东西是需要前提条件的,例如我们在某个方法的形参传入,假设...

    为什么要在JAVA工厂模式中使用静态方法

     为什么要在工厂模式中使用静态方法  工厂模式是一种封装对象创建的方法。如果不使用工厂模式,你需要直接使用构造方法来创建对象: Foo x = new Foo()  使用工厂模式,可以取而代之的调用工厂方法: Foo x...

    设计模式 C# 简单工厂模式,实现代码

    设计模式 C# 简单工厂模式,又叫做静态工厂方法模式,这是一个很简单的模式,它不属于GOF二十三个基本模式之中的一个,但它是一个很有用的模式,有用得着的时候可以使用它。

    单例模式 工厂模式DEMO

    结论:工厂模式体现在接口作为返回类型的运用中,实际上返回的是实现接口的类的对象。 3、两种比较器以及sort()方法的重载: 结论:Icomparable接口在需要比较的类中实现;Icomparer接口在任何类中实现,使用时只需...

    简单工厂模式

    用c++实现的简单工厂模式,其功能是一个简单计算功能

    JavaEE spring静态工厂创建实例

    JavaEE spring静态工厂创建实例

    Calculator(简单工厂模式)

    从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂...

    Java设计模式之抽象工厂模式.docx

    一个具体工厂创建一个产品族,一个产品族是不同系列产品的组合,产品的创建的逻辑分在在每个具体工厂类...如果没有应对“多系列对象创建”的需求变化,则没有必要使用抽象工厂模式,这时候使用简单的静态工厂完全可以。

    《软件秘笈:设计模式那点事》郑阿奇(编者) -电子工业出版社

    3.3.3 抽象工厂模式的静态建模 3.4 故事的抽象工厂模式实现 3.4.1 抽象食物的建立 3.4.2 建立不同食物的抽象基类 3.4.3 创建具体的食物 3.4.4 建立工厂 3.4.5 创建客户类 3.4.6 故事情节的展现 3.5 设计原则...

    Simple Factory Pattern.rar【GoF的简单工厂模式(C#源码)】

    简单工厂(Simple Factory)模式又称为静态工厂方法(Static Factory Method)模式,属于类的创建型模式,通常它根据自变量的不同返回不同的类的实例。 简单工厂模式的实质是由一个工厂类根据传入的参量,动态决定...

    使用简单工厂模式来进行Python的设计模式编程

    简单工厂模式又叫静态工厂方法模式,工厂模式家族中最简单的一种模式。这个模式的基本工作方式: 通过一个工厂来决定创建哪种具体的产品实例。 下面是一个简单的工厂实例: def create_animal(name): if name == '...

    php设计模式之简单工厂模式详解

    简单工厂模式 【静态工厂方法模式】(Static Factory Method) 是类的创建模式 工厂模式的几种形态: 1、简单工厂模式(Simple Factory)又叫做 静态工厂方法模式(Static Factory Method) 2、工厂方法模式(Factory ...

Global site tag (gtag.js) - Google Analytics