设计模式系列1 工厂模式
Posted wenteryan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式系列1 工厂模式相关的知识,希望对你有一定的参考价值。
工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
使用场景
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,”POP3”、”IMAP”、”HTTP”,可以把这三个作为产品类,共同实现一个接口。
五种工厂模式
1)简单工厂(静态)
案例:生产车辆
抽象一个汽车基类,或者是接口
public abstract class CarPrototype
/**
* 生产汽车
*/
public abstract void produce();
生产奥迪汽车(具体的产品类)
public class AodeCar extends CarPrototype
@Override
public void produce()
// TODO Auto-generated method stub
System.out.println("生产一辆奥迪汽车。。。。。。。。。。。。");
生产宝马汽车(具体的产品类)
public class BaomaCar extends CarPrototype
@Override
public void produce()
// TODO Auto-generated method stub
System.out.println("生产一辆宝马汽车。。。。。。。。。。。。");
生产红旗汽车(具体的产品类)
public class HongqiCar extends CarPrototype
@Override
public void produce()
// TODO Auto-generated method stub
System.out.println("生产一辆红旗汽车。。。。。。。。。。。。");
汽车工厂(简单工厂类)
public class SimpleCarFactory
public static CarPrototype createCar(String type)
switch(type)
case "baoma":
return new BaomaCar();
case "aode":
return new AodeCar();
case "hongqi":
return new HongqiCar();
default:
throw new BaseException("工厂类无法匹配汽车,没法生产。。。。。");
测试生产汽车
public class TestCarFactory
public static void main(String[] args)
CarPrototype carPrototype = new SimpleCarFactory().createCar("baoma");
carPrototype.produce();
结果
生产一辆宝马汽车。。。。。。。。。。。。
特点
1 它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。
2 create()方法通常是静态的,所以也称之为静态工厂。
缺点
1 扩展性差(我想增加一种汽车,除了新增一个汽车产品类,还需要修改工厂类方法)
2 不同的产品需要不同额外参数的时候 不支持。
2)简单工厂(反射)
利用反射Class.forName(clz.getName()).newInstance()实现的简单工厂
public class ReflectionCarFactory
public static <T extends CarPrototype> T createCar(Class<T> prototype)
T result = null;
try
result = (T)Class.forName(prototype.getName()).newInstance();
catch (Exception e)
// TODO Auto-generated catch block
e.printStackTrace();
return result;
测试简单工厂(反射)
public class TestCarFactory
public static void main(String[] args)
// 简单工厂(静态)
/*CarPrototype carPrototype = new SimpleCarFactory().createCar("baoma");
carPrototype.produce();*/
// 简单工厂(反射)
CarPrototype carPrototype = ReflectionCarFactory.createCar(AodeCar.class);
carPrototype.produce();
结果
生产一辆奥迪汽车。。。。。。。。。。。。
特点
1 它也是一个具体的类,非接口 抽象类。但它的create()方法,是利用反射机制生成对象返回,好处是增加一种产品时,不需要修改create()的代码。
缺点
这种写法粗看牛逼,细想之下,不谈reflection的效率还有以下问题:
1 个人觉得不好,因为Class.forName(clz.getName()).newInstance()调用的是无参构造函数生成对象,它和new Object()是一样的性质,而工厂方法应该用于复杂对象的初始化 ,当需要调用有参的构造函数时便无能为力了,这样像为了工厂而工厂。
2 不同的产品需要不同额外参数的时候 不支持。
3)多方法工厂(常用)
不同的产品需要不同额外参数的时候 不支持。
而且如果使用时传递的type、Class出错,将不能得到正确的对象,容错率不高。
而多方法的工厂模式为不同产品,提供不同的生产方法,使用时 需要哪种产品就调用该种产品的方法,使用方便、容错率高。
工厂如下
public class ManyWayCarFactory
/**
* 生产奥迪汽车
* @return
*/
public static CarPrototype createAodeCar()
return new AodeCar();
/**
* 生产宝马汽车
* @return
*/
public static CarPrototype createBaomaCar()
return new BaomaCar();
/**
* 生产红旗汽车
* @return
*/
public static CarPrototype createHongqiCar()
return new HongqiCar();
测试多方法工厂(常用)
public class TestCarFactory
public static void main(String[] args)
// 简单工厂(静态)
/*CarPrototype carPrototype = new SimpleCarFactory().createCar("baoma");
carPrototype.produce();*/
// 简单工厂(反射)
/*CarPrototype carPrototype = ReflectionCarFactory.createCar(AodeCar.class);
carPrototype.produce();*/
// 多方法静态工厂(模仿Executor类)
CarPrototype carPrototype = new ManyWayCarFactory().createHongqiCar();
carPrototype.produce();
结果
生产一辆红旗汽车。。。。。。。。。。。。
4)普通工厂
普通工厂就是把简单工厂中具体的工厂类,划分成两层:抽象工厂层+具体的工厂子类层。(一般->特殊)
汽车工厂(抽象工厂类),作用就是生产汽车:
public abstract class CarFactory
public abstract CarPrototype create();
生产奥迪工厂(具体工厂子类)
public class AodeFactory extends CarFactory
public CarPrototype create()
// TODO Auto-generated method stub
return new AodeCar();
生产宝马工厂(具体工厂子类)
public class BaomaFactory extends CarFactory
public CarPrototype create()
// TODO Auto-generated method stub
return new BaomaCar();
生产红旗工厂(具体工厂子类)
public class HongqiFactory extends CarFactory
public CarPrototype create()
// TODO Auto-generated method stub
return new HongqiCar();
测试普通工厂
public class TestCarFactory
public static void main(String[] args)
// 简单工厂(静态)
/*CarPrototype carPrototype = new SimpleCarFactory().createCar("baoma");
carPrototype.produce();*/
// 简单工厂(反射)
/*CarPrototype carPrototype = ReflectionCarFactory.createCar(AodeCar.class);
carPrototype.produce();*/
// 多方法静态工厂(模仿Executor类)
/*CarPrototype carPrototype = new ManyWayCarFactory().createHongqiCar();
carPrototype.produce();*/
// 普通工厂
CarPrototype carPrototype = new BaomaFactory().create();
carPrototype.produce();
结果
生产一辆宝马汽车。。。。。。。。。。。。
普通工厂与简单工厂模式的区别:
可以看出,普通工厂模式特点:不仅仅做出来的产品要抽象, 工厂也应该需要抽象。
工厂方法使一个产品类的实例化延迟到其具体工厂子类。
工厂方法的好处就是更拥抱变化。当需求变化,只需要增删相应的类,不需要修改已有的类。
而简单工厂需要修改工厂类的create()方法,多方法静态工厂模式需要增加一个静态方法。
缺点:
引入抽象工厂层后,每次新增一个具体产品类,也要同时新增一个具体工厂类,所以我更青睐 多方法静态工厂。
5)抽象工厂
以上介绍的工厂都是单产品系的。抽象工厂是多产品系 (貌似也有产品家族的说法)。
举个例子来说,每个店(工厂)不仅仅生产汽车,还生产零件。
生产零件,零件是产品,先抽象一个产品类,零件:
public abstract class ComponentsPrototype
/**
* 生产零件
*/
public abstract void produce();
生产车门
public class CarDoorComponents extends ComponentsPrototype
@Override
public void produce()
// TODO Auto-generated method stub
System.out.println("生产车门-------------");
生产发动机
public class EngineComponents extends ComponentsPrototype
@Override
public void produce()
// TODO Auto-generated method stub
System.out.println("生产发动机-------------");
抽象汽车工厂(抽象工厂类)
public abstract class AbstractCarFactory
/**
* 生产汽车
* @return
*/
public abstract CarPrototype createCar();
/**
* 生产零件
* @return
*/
public abstract ComponentsPrototype createComponents();
测试抽象工厂
public class TestCarFactory
public static void main(String[] args)
// 简单工厂(静态)
/*CarPrototype carPrototype = new SimpleCarFactory().createCar("baoma");
carPrototype.produce();*/
// 简单工厂(反射)
/*CarPrototype carPrototype = ReflectionCarFactory.createCar(AodeCar.class);
carPrototype.produce();*/
// 多方法静态工厂(模仿Executor类)
/*CarPrototype carPrototype = new ManyWayCarFactory().createHongqiCar();
carPrototype.produce();*/
// 普通工厂
/*CarPrototype carPrototype = new BaomaFactory().create();
carPrototype.produce();*/
// 抽象工厂
CarPrototype carPrototype = new ChinaCarFactory().createCar();
carPrototype.produce();
ComponentsPrototype componentsPrototype = new ChinaCarFactory().createComponents();
componentsPrototype.produce();
结果
生产一辆宝马汽车。。。。。。。。。。。。
生产发动机-------------
以上是关于设计模式系列1 工厂模式的主要内容,如果未能解决你的问题,请参考以下文章