一般认为简单工厂模式,产品部分能够在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的静态方法。
分享到:
相关推荐
简单工厂模式是最简单的工厂模式实现,它提供一个静态方法或者类来创建对象,这个类通常被称为“工厂”。用户只需要知道具体的产品类型,而无需了解如何创建对象。简单工厂模式适用于产品种类较少且相对固定的情况...
简单工厂模式是一种静态工厂方法,它提供一个公共的工厂类来创建对象。在C++中,这个工厂类通常包含一个静态方法,根据传入的参数或者条件决定创建哪个类的实例。这种模式的优点是客户端无需知道具体产品的类名,只...
简单工厂模式是一种静态工厂方法,它提供一个公共的工厂类来创建对象。这个工厂类根据传入的参数或者条件来决定创建哪种类型的实例。在简单工厂模式中,通常有一个中心工厂类,它负责知道如何创建各种产品。这种模式...
1. 简单工厂模式:也称为静态工厂方法模式,它通过一个静态方法来创建对象。在这个例子中,`FruitGardener` 类就是简单工厂,它根据输入的字符串(如 "apple"、"strawberry" 或 "grape")返回相应的 `Fruit` 实例(`...
这是最基础的工厂模式,它包含一个静态工厂方法,根据输入参数决定创建哪个产品类的实例。这种方式易于使用,但不利于扩展,因为如果要添加新产品,需要修改工厂类。 2. 工厂方法模式: 工厂方法模式将对象的创建...
1. **简单工厂模式**:这是最直观的形式,包含一个静态工厂方法,根据传入的参数决定返回哪个类的实例。这种模式简单易用,但不支持增加新的产品类型,因为静态方法不易扩展。 2. **工厂方法模式**:每个子类都有一...
简单工厂模式(Simple Factory Pattern)是一种静态工厂方法,它通过一个公共的工厂类来创建对象。这个工厂类通常包含一个或多个静态方法,用于根据输入参数创建不同类型的实例。这种模式的优点在于客户端代码无需...
这些模式在不同的开发环境中都展现出其价值,包括单例模式、工厂模式、观察者模式、装饰器模式、适配器模式、建造者模式等。 在C#中,我们可以利用面向对象的特性,如类、接口和继承,来实现这些设计模式。例如,...
- 简单工厂模式是一种静态工厂方法,它提供一个统一的接口来创建一组相关或相互依赖的对象,而无需指定具体的类。 - 在C++中,这通常表现为一个类(工厂类)包含一个静态方法,该方法根据输入参数返回一个实例。...
**简单工厂模式**是软件设计模式中的一种,属于创建型模式。在Java编程中,它是一种用于创建对象的简便方法,将对象的实例化过程封装到一个单独的工厂类中,使得客户端代码无需直接调用具体类的构造函数,而是通过...
工厂模式分为三种主要类型:简单工厂模式、普通工厂模式(也称为工厂方法模式)和抽象工厂模式。 1. **简单工厂模式**: - 简单工厂模式中,有一个中心工厂类,它负责根据输入条件(通常是一个参数)来创建具体的...
在Java中,通常通过私有构造函数和静态工厂方法来实现单例。单例模式常用于控制共享资源,如线程池、数据库连接或者配置对象。其优点在于节省内存,减少对系统资源的消耗,同时保证了对象间的同步。 **工厂模式**是...
- 简单工厂模式是一种静态工厂方法模式,它包含一个静态工厂类,负责创建对象。在这个例子中,可能有一个名为`Factory`的类,其中包含一个静态方法,如`createInstance()`,这个方法根据输入参数返回相应的对象实例...
《C#设计模式——工厂模式详解》 工厂模式是一种常用的设计模式,它的主要目的是通过抽象出产品创建过程,使得客户端代码不再直接new对象,而是通过工厂来获取对象,从而降低了代码之间的耦合度,提高了系统的可...
简单工厂模式是一种创建型设计模式,它提供一个静态工厂方法来创建对象,而不是使用new关键字。`simplefactory`文件可能包含一个简单的工厂类,它负责根据输入条件(如参数)返回相应类型的实例。这种模式将对象的...
- 定义:在简单工厂模式中,有一个静态工厂类负责创建对象,这个工厂类根据传入的参数决定返回哪个具体类的实例。 - UML图表示:简单工厂模式通常包含一个工厂类、一个抽象产品类(或接口)和若干个具体产品类。在...
通过抽象工厂模式的静态建模,我们可以看到客户通过抽象工厂接口请求产品,而具体的工厂负责生产具体的产品。 在实现抽象工厂模式时,我们首先需要定义抽象食物以及食物接口。然后,我们需要创建不同食物的抽象基类...
(3)静态工厂:工厂本身不用创建对象;通过静态方法调用,对象 = 工厂类.工厂方法名(); (4)实例工厂:工厂本身需要创建对象;如下: 工厂类 工厂对象 = new 工厂类(); 工厂对象.getAirPlane(“张三”);
简单工厂模式是一种静态工厂方法,它创建一个具体的对象而无需暴露创建逻辑。在C#中,我们可以定义一个工厂类,该类包含一个静态方法,用于根据输入参数返回不同类型的实例。例如,一个形状工厂可以生成圆形、...