设计模式之工厂方法模式
Posted 独孤九戒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之工厂方法模式相关的知识,希望对你有一定的参考价值。
设计模式之工厂方法模式
工厂方法模式定义:Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。)
通用类图:
其中,抽象产品类负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体实现工厂ConcreateCreator完成的。
通用源码
抽象产品类
public abstract class Product
//产品类的公用方法
public void method1()
//抽象方法
public abstract void method2();
具体产品类1
public class ConcreteProduct1 extends Product
public void method2()
具体产品类2
public class ConcreteProduct2 extends Product
public void method2()
抽象工厂类
public abstract class Creator
//创建一个产品对象
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)
// TODO Auto-generated method stub
Creator creator=new ConcreteCreator();
Product product=creator.createProduct(ConcreteProduct1.class);
例子:女娲造人
人类总称
public interface Human
public void getColor();
public void talk();
黑人
public class BlackHunman implements Human
public void getColor()
System.out.println("黑色");
public void talk()
System.out.println("黑人说黑话");
黄人
public class YellowHuman implements Human
public void getColor()
System.out.println("黄色");
public void talk()
System.out.println("黄人说汉语");
白人
public class WhiteHuman implements Human
public void getColor()
System.out.println("白色");
public void talk()
System.out.println("白人说英语");
抽象工厂
public abstract class AbstractHumanFactory
public abstract <T extends Human> T createHuman(Class<T> c);
具体工厂
public class HumanFactory extends AbstractHumanFactory
public <T extends Human> T createHuman(Class<T> c)
Human human=null;
try
human=(T)Class.forName(c.getName()).newInstance();
catch(Exception e)
System.out.println("人种错误");
return (T)human;
女娲类
public class NvWa
public static void main(String[] args)
// TODO Auto-generated method stub
AbstractHumanFactory yinyanglu=new HumanFactory();
System.out.println("第一批人是白人");
Human whiteHuman=yinyanglu.createHuman(WhiteHuman.class);
whiteHuman.getColor();
whiteHuman.talk();
System.out.println("第二批人是黑人");
Human blackHuman=yinyanglu.createHuman(BlackHunman.class);
blackHuman.getColor();
blackHuman.talk();
System.out.println("第三批人是黄人");
Human yellowHuman=yinyanglu.createHuman(YellowHuman.class);
yellowHuman.getColor();
yellowHuman.talk();
工厂方法模式的优点:
1.良好的封装性,代码结构清晰,如调用者需要创建一个具体的产品对象,只要知道产品的类名即可,不需要知道创建具体过程,降低模块间耦合;
2.工厂方法扩展性非常优秀,在增加产品的情况下,只要适当的修改具体类的工厂类或者扩展一个工厂类即可;
3.屏蔽产品类,产品如何变花,调用者不需要关心,他只需要关心产品的接口,只要接口不变,系统的上层模块就不需要变化,因为产品的实例化工作是由工厂类负责的;
4.工厂方法模式是非常典型的及饿哦欧框架,高层模块只需要知道产品的抽象类,不用关心其它的实现类。
使用场景
1.工厂方法模型是new一个对象的替代品,在需要生成对象的地方都可以使用,但是需要慎重的考虑是否增加一个工厂类进行管理,增加代码的复杂度;
2.需要灵活地、可扩展的框架时,可以考虑采用工厂方法模型;
3.工厂方法模式可以使用在异构项目中;
4.可以使用在测试驱动开发的框架下。
工厂方法模型的扩展
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;
场景类
public class NvWa
public static void main(String[] args)
// TODO Auto-generated method stub
//AbstractHumanFactory yinyanglu=new HumanFactory();
System.out.println("第一批人是白人");
//Human whiteHuman=yinyanglu.createHuman(WhiteHuman.class);
Human whiteHuman=HumanFactory.createHuman(WhiteHuman.class);
whiteHuman.getColor();
whiteHuman.talk();
System.out.println("第二批人是黑人");
//Human blackHuman=yinyanglu.createHuman(BlackHunman.class);
Human blackHuman=HumanFactory.createHuman(BlackHunman.class);
blackHuman.getColor();
blackHuman.talk();
System.out.println("第三批人是黄人");
//Human yellowHuman=yinyanglu.createHuman(YellowHuman.class);
Human yellowHuman=HumanFactory.createHuman(YellowHuman.class);
yellowHuman.getColor();
yellowHuman.talk();
2.升级为多个工厂类
多工厂模式抽象工厂类
public abstract class AbstractHumanFactory
public abstract Human createHuman();
黑人工厂类
public class BlackHumanFactory extends AbstractHumanFactory
public Human createHuman()
return new BlackHunman();
黄人工厂类
public class YellowHumanFactory
public Human createHuman()
return new YellowHuman();
白人工厂类
public class WhiteHumanFactory
public Human createHuman()
return new WhiteHuman();
女娲类
public class NvWa
public static void main(String[] args)
// TODO Auto-generated method stub
//AbstractHumanFactory yinyanglu=new HumanFactory();
System.out.println("第一批人是白人");
//Human whiteHuman=yinyanglu.createHuman(WhiteHuman.class);
//Human whiteHuman=HumanFactory.createHuman(WhiteHuman.class);
Human whiteHuman=(new WhiteHumanFactory()).createHuman();
whiteHuman.getColor();
whiteHuman.talk();
System.out.println("第二批人是黑人");
//Human blackHuman=yinyanglu.createHuman(BlackHunman.class);
//Human blackHuman=HumanFactory.createHuman(BlackHunman.class);
Human blackHuman=(new BlackHumanFactory()).createHuman();
blackHuman.getColor();
blackHuman.talk();
System.out.println("第三批人是黄人");
//Human yellowHuman=yinyanglu.createHuman(YellowHuman.class);
//Human yellowHuman=HumanFactory.createHuman(YellowHuman.class);
Human yellowHuman=(new YellowHumanFactory()).createHuman();
yellowHuman.getColor();
yellowHuman.talk();
如果要扩展一个产品类,就需要建立一个相应的工厂类,这样就增加了扩展的难度。因为工厂类和产品类的数量相同,维护时需要考虑两个对象之间的关系。
3.替代单例模式
单例类
public class Singleton
private Singleton()
public void doSomething()
单例工厂
public class SingletonFactory
private static Singleton singleton;
static
try
Class c1=Class.forName(Singleton.class.getName());
//获得无参构造函数
Constructor constructor=c1.getDeclaredConstructor();
//设置无参构造函数的访问性
constructor.setAccessible(true);
//产生一个实例对象
singleton=(Singleton)constructor.newInstance();
catch(Exception e)
public static Singleton getSingleton()
return singleton;
4.延迟初始化
延迟初始化:一个对象被消费完毕后,并不立刻释放,工厂类保持其初始状态,等待被再次使用。
ProductFactory负责产品类对象的创建工作,并且通过prMap变量产生一个缓存,对需要再次被重用的对象保留。
public class ProductFactor
private static final Map<String,Product> prMap=new HashMap();
public static synchronized Product createProduct(String type)throw Exception
Product product=null;
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;
以上是关于设计模式之工厂方法模式的主要内容,如果未能解决你的问题,请参考以下文章