设计模式-工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式分类三类:(在《设计模式》一书中将简单工厂模式与工厂方法模式合称为工厂方法模式)
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
简单工厂模式(Simple Factory)
建立一个工厂(一个函数或一个类方法)来制造新的对象。
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据自变量的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式优点
- 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
简单工厂模式缺点
- 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
简单工厂模式示例
定义抽象产品类
/**
* 交通工具
*
* @author jiangliuhong
*/
public abstract class Vehicle {
public abstract void run();
}
/**
* 汽车基础类
* @author jiangliuhong
*/
public class Car extends Vehicle {
private Double speed;
private String name;
Car(Double speed, String name) {
this.speed = speed;
this.name = name;
}
public Double getSpeed() {
return speed;
}
public void setSpeed(Double speed) {
this.speed = speed;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(getName() + " speed is :" + getSpeed());
}
}
定义具体的汽车实现类
/**
* 小汽车
* @author jiangliuhong
*/
public class SedanCar extends Car {
public SedanCar() {
super(200D,"SedanCar");
}
}
/**
* 摩托车
* @author jiangliuhong
*/
public class Motobike extends Car {
public Motobike() {
super(120D, "Motobike");
}
}
定义工厂类
/**
* 汽车工厂类
* @author jiangliuhong
* @date
*/
public class CarFactory {
public static Vehicle createCar(CarType carType) {
switch (carType) {
case MOTOBIKE:
return new Motobike();
case SEDANCAR:
return new SedanCar();
default:
return null;
}
}
}
/**
* 汽车类别
* @author jiangliuhong
*/
public enum CarType {
/** 小汽车 */
SEDANCAR,
/** 摩托车 */
MOTOBIKE;
}
模拟运行
/**
* @author jiangliuhong
*/
public class SimpleMain {
public static void main(String[] args) {
Vehicle v1 = CarFactory.createCar(CarType.MOTOBIKE);
v1.run();
Vehicle v2 = CarFactory.createCar(CarType.SEDANCAR);
v2.run();
}
}
控制台输出
Motobike speed is :120.0
SedanCar speed is :200.0
工厂方法模式(Factory Method)
工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method是一个类的实例化延迟到其子类。
在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
工厂方法模式优点
- 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无需关心创建细节,甚至无需知道具体产品类的类名
- 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,正是因为所有的具体工厂类都具有同一抽象父类
- 使用工厂方法模式的另一个优点是在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”
工厂方法模式缺点
- 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销
- 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度
工厂方法模式示例
Factory方法
/**
* 工厂方法接口
*
* @author jiangliuhong
*/
public interface VehicleFacotry {
/**
* 创建交通工具
* @return
*/
public Vehicle createVehicle();
}
public interface CarFactory extends VehicleFacotry {
}
public class MotobikeFactory implements CarFactory {
@Override
public Vehicle createVehicle() {
return new Motobike();
}
}
public class SedanCarFactory implements CarFactory {
@Override
public Vehicle createVehicle() {
return new SedanCar();
}
}
抽象工厂模式(Abstract Factory)
抽象工厂模式提供一个创建一系列或相互依赖的对象的接口,而无需指定它们具体的类。
抽象工厂模式优点
- 隔离了具体类的生成,使得用户不需要知道什么被创建了。
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
抽象工厂模式缺点
- 添加新的产品对像时,难以扩展抽象工厂以便生产新种类的产品。
抽象工厂模式示例
定义ProductB
public abstract class Tv {
public abstract void player();
}
public class LeTv extends Tv {
@Override
public void player() {
System.out.println("player LeTv");
}
}
public class ChangTv extends Tv {
@Override
public void player() {
System.out.println("player ChangTv");
}
}
定义Factory
public interface Factory {
public Tv createTv();
public Vehicle createVehicle();
}
public class ConOneFactory implements Factory {
@Override
public Tv createTv() {
return new LeTv();
}
@Override
public Vehicle createVehicle() {
return new Motobike();
}
}
public class ConTwoFactory implements Factory {
@Override
public Tv createTv() {
return new ChangTv();
}
@Override
public Vehicle createVehicle() {
return new SedanCar();
}
}
参考资料