工厂模式
复杂对象的创建适合采用工厂模式,确保创造对象的步骤是集中的不是分散在各个类中的。
工厂模式和抽象工厂模式
工厂模式是采用最简单的方法,一个工厂创建相似的不同的产品。
抽象工厂模式是存在另一个维度抽象,即工厂维度的抽象,存在多个不同工厂的实现类,然后不同的工厂创建不同的相似的产品。
特征
- 创建复杂对象
- 创建对象的过程集中在一起
- 暴露一个对外创建对象的方法
- 类与类之间的解耦,不需要 new Object(),而是采用工厂类创建对象
用例
一个车工厂,创建 3 中不同类型的车,small、sedan(轿车)、luxury(豪车)
CarType
CarType 枚举类,持有三种不同的车的类型
public enum CarType {
SMALL, SEDAN, LUXURY
}
Car
Car 是一个具体车型的抽象类,定义了车的公共逻辑和车的类型。
public abstract class Car {
public Car(CarType model) {
this.model = model;
arrangeParts();
}
private void arrangeParts() {
// Do one time processing here
}
// Do subclass level processing in this method
protected abstract void construct();
private CarType model = null;
public CarType getModel() {
return model;
}
public void setModel(CarType model) {
this.model = model;
}
}
LuxuryCar
LuxuryCar 豪车
public class LuxuryCar extends Car {
LuxuryCar() {
super(CarType.LUXURY);
construct();
}
@Override
protected void construct() {
System.out.println("Building luxury car");
// add accessories
}
}
SmallCar
小型车
public class SmallCar extends Car {
SmallCar() {
super(CarType.SMALL);
construct();
}
@Override
protected void construct() {
System.out.println("Building small car");
// add accessories
}
}
SedanCar
轿车
public class SedanCar extends Car {
SedanCar() {
super(CarType.SEDAN);
construct();
}
@Override
protected void construct() {
System.out.println("Building sedan car");
// add accessories
}
}
CarFactory
创建 Car 的工厂类
public class CarFactory {
public static Car buildCar(CarType model) {
Car car = null;
switch (model) {
case SMALL:
car = new SmallCar();
break;
case SEDAN:
car = new SedanCar();
break;
case LUXURY:
car = new LuxuryCar();
break;
default:
// throw some exception
break;
}
return car;
}
}
Test
调用实例
public class TestFactoryPattern {
public static void main(String[] args) {
System.out.println(CarFactory.buildCar(CarType.SMALL));
System.out.println(CarFactory.buildCar(CarType.SEDAN));
System.out.println(CarFactory.buildCar(CarType.LUXURY));
}
}
常见示例
- java.sql.DriverManager.getConnection()
抽象工厂模式
在工厂模式中,对工厂维度进行了抽象,就是抽象工厂模式,适用于多个不同的工厂,不同的工厂创建不同的系列产品。
特征
- 在工厂模式中
- 对工厂维度的抽象
- 不同的工厂,创建出不同的系列产品
实例
为了支持汽车的全球化业务,满足不同地区的对不同汽车风格需求,比如方向盘在左边,还是在右边,从而出现了工厂抽象,存在不同位置的工厂,比如 美国工厂、亚洲工厂、默认本地工厂,从而出现了工厂维度的抽象。
Car
满足不同地区,不同车型,从而车有了产地这个维度。
public abstract class Car {
public Car(CarType model, Location location){
this.model = model;
this.location = location;
}
protected abstract void construct();
private CarType model = null;
private Location location = null;
//getters and setters
@Override
public String toString() {
return "Model- "+model + " built in "+location;
}
}
Location
车的产地
public enum Location {
DEFAULT, USA, ASIA
}
LuxuryCar
豪车
public class LuxuryCar extends Car
{
public LuxuryCar(Location location)
{
super(CarType.LUXURY, location);
construct();
}
@Override
protected void construct() {
System.out.println("Building luxury car");
//add accessories
}
}
AsiaCarFactory
亚洲车工厂
public class AsiaCarFactory
{
public static Car buildCar(CarType model)
{
Car car = null;
switch (model)
{
case SMALL:
car = new SmallCar(Location.ASIA);
break;
case SEDAN:
car = new SedanCar(Location.ASIA);
break;
case LUXURY:
car = new LuxuryCar(Location.ASIA);
break;
default:
//throw some exception
break;
}
return car;
}
}
DefaultCarFactory
默认本地车工厂
public class DefaultCarFactory
{
public static Car buildCar(CarType model)
{
Car car = null;
switch (model)
{
case SMALL:
car = new SmallCar(Location.DEFAULT);
break;
case SEDAN:
car = new SedanCar(Location.DEFAULT);
break;
case LUXURY:
car = new LuxuryCar(Location.DEFAULT);
break;
default:
//throw some exception
break;
}
return car;
}
}
USACarFactory
美国车工厂
public class USACarFactory
{
public static Car buildCar(CarType model)
{
Car car = null;
switch (model)
{
case SMALL:
car = new SmallCar(Location.USA);
break;
case SEDAN:
car = new SedanCar(Location.USA);
break;
case LUXURY:
car = new LuxuryCar(Location.USA);
break;
default:
//throw some exception
break;
}
return car;
}
}
CarFactory
已经有了三种不同的车工厂,现在抽象出有哪个工厂去创建车
public class CarFactory
{
private CarFactory() {
//Prevent instantiation
}
public static Car buildCar(CarType type)
{
Car car = null;
Location location = Location.ASIA; //Read location property somewhere from configuration
//Use location specific car factory
switch(location)
{
case USA:
car = USACarFactory.buildCar(type);
break;
case ASIA:
car = AsiaCarFactory.buildCar(type);
break;
default:
car = DefaultCarFactory.buildCar(type);
}
return car;
}
}
TestFactoryPattern
public class TestFactoryPattern
{
public static void main(String[] args)
{
System.out.println(CarFactory.buildCar(CarType.SMALL));
System.out.println(CarFactory.buildCar(CarType.SEDAN));
System.out.println(CarFactory.buildCar(CarType.LUXURY));
}
}
场景
- MyBatis 中连接池和非连接池数据源,存在连接池工厂创建连接池数据源,非连接池工厂创建非连接池数据源。
网友评论