您的位置:首页 > 其它

工厂模式

2015-08-15 11:23 381 查看
what

Define an interface for creating an object,but let subclasses decide which class to

instantiate.Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 )

why

产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化,降低模块间的耦合,利于代码的扩展。

工厂方法模式是典型的解耦框架。 高层模块值需要知道产品的抽象类, 其他的实现类都不用关心。

how

抽象产品类

public abstract class Product {
// 产品类的公共方法
public void method1() {
// 业务逻辑处理
}
// 抽象方法
public abstract void method2();
}

具体产品类
public class ConcreteProduct1 extends Product {
public void method2() {
//业务逻辑处理
}
}

public class ConcreteProduct2 extends Product {
public void method2() {
//业务逻辑处理
}
}


抽象工厂

public abstract class Creator {
/*
* 创建一个产品对象, 其输入参数类型可以自 行设置
* 通常为String、 Enum、 Class等, 当然也可以为空
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
具体工厂

public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c) {
Product product=null;
try {
product = (Product) Class.forName(c.getName( )).newInstance( );
} catch (Exception e) {
//异常处理
}
return (T)product;
}
}
场景类

public class Client {
public static void main( String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/*
* 继续业务处理
*/
}
}


比如创建DAO时可以在properties文件中写好对应DAO的路径(如mysql或oracle的实现)那样在更换不同的数据库时高层代码就不用修改

private DAOFactory() {
prop = new Properties();
try {
prop.load(DAOFactory.class.getClassLoader().getResourceAsStream(
"manager/utils/db.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}



public <T extends BaseDAO> T createDAO(Class<T> clazz) {
try {
String name = clazz.getName();
String className = prop.getProperty("name")
return (T) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace(); throw new RuntimeException(e);
}
}


extension

1.缩小为简单工厂模式

public class HumanFactory {
public static <T extends Human> T createHuman(Class<T> c) {
//定义一个生产出的人种
Human human=null;
try {
//产生一个人种
human = (Human)Class.forName( c.getName()).newInstance();
} catch (Exception e) {
System.out.println( "人种生成错误! ") ;
}
return (T)human;
}
}
2.升级为多个工厂类

public abstract class AbstractHumanFactory {
public abstract Human createHuman();
}
public class BlackHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new BlackHuman() ;
}
}


public class YellowHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new YellowHuman();
}
}

public class whiteHumanFactory extends AbstractHumanFactory {
public Human createHuman() {
return new WhiteHuman();
}
}

在复杂的应用中一般采用多工厂的方法, 然后再增加一个协调类, 避免调用者与各个子工厂交流, 协调类的作用是封装子工厂类, 对高层模块提供统一的访问接口

3.
替代单例模式

public class Singleton {
//不允许通过new产生一个对象
private Singleton() {
}
public void doSomething() {
//业务处理
}
}


public class SingletonFactory {
private static Singleton singleton;
static{
try {
Class cl= Class.forName( Singleton.class.getName());
//获得无参构造
Constructor constructor=cl.getDeclaredConstructor();
//设置无参构造是可访问的
constructor.setAccessible(true) ;
//产生一个实例对象
singleton = (Singleton) constructor.newInstance();
} catch ( Exception e) {
//异常处理
}
}
public static Singleton getSingleton() {
return singleton;
}
}

4.
延迟初始化

public class ProductFactory {
private static final Map<String, Product> prMap = new HashMap();
public static synchronized Product createProduct(String type) throws Exception{
Product product =null;
//如果Map中已经有这个对象
if(prMap.containsKey(type)) {
product = prMap.get(type);
} else{
if( type.equals("Product1")) {
product = new ConcreteProduct1();
} else{
product = new ConcreteProduct2();
}
//同时把对象放到缓存容器中
prMap.put( type, product);
}
return product;
}
}

ProductFactory负责产品类对象的创建工作,并且通过prMap变量产生一个缓存,对需要再次被重用的对象保留
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: