在介绍抽象工厂之前,我们先了解以下概念
产品等级
对于Cpu,有高通生产的Cpu,华为生产的麒麟Cpu,以及联发科的MTK Cpu,它们都属于Cpu这同一产品等级。对于空调,由美的空调、海尔空调,他们也属于同一个产品等级
产品族
由一个工厂生产的不同等级的产品构成了一个产品族,美的公司生产空调、电冰箱、洗衣机,这些产品构成了一个产品族。
抽象工厂和工厂模式最大的区别是
工厂模式解决的同一产品等级的问题
抽象共产解决的是产品族的问题
抽象工厂的定义
抽象工厂提供一个创建一系列相关或相互依赖对象的接口
我们在使用时不需要知道或关心它从这些工厂方法中获得对象的具体类型,因为我们客户端程序仅使用这些对象的通用接口
抽象工厂具体实现
- 首先定义两个产品等级,空调(AirConditioningSystem)和洗衣机(Refrigerator)。其中美的工厂生产美的洗衣机和美的空调,海尔工厂生产海尔洗衣机和海尔空调。
public interface AirConditioningSystem
{
void produce();
}
public class HaierAirConditioningSystem implements AirConditioningSystem
{
@Override
public void produce()
{
System.out.println("海尔空调");
}
}
public class MideaAirConditioningSystem implements AirConditioningSystem
{
@Override
public void produce()
{
System.out.println("美的空调");
}
}
public interface Refrigerator
{
void produce();
}
public class MideaRefrigerator implements Refrigerator
{
@Override
public void produce()
{
System.out.println("美的冰箱");
}
}
public class HaierRefrigerator implements Refrigerator
{
@Override
public void produce()
{
System.out.println("海尔冰箱");
}
}
- 定义工厂类
public interface JiadianFactory
{
Refrigerator produceRefrigetor();
AirConditioningSystem produceAirConditioningSystem();
}
public class HaierJiadianFactory implements JiadianFactory
{
@Override
public Refrigerator produceRefrigetor()
{
return new HaierRefrigerator();
}
@Override
public AirConditioningSystem produceAirConditioningSystem()
{
return new HaierAirConditioningSystem();
}
}
public class MideaJiadianFactory implements JiadianFactory
{
@Override
public Refrigerator produceRefrigetor()
{
return new MideaRefrigerator();
}
@Override
public AirConditioningSystem produceAirConditioningSystem()
{
return new MideaAirConditioningSystem();
}
}
- 定义客户类
public class Client
{
public static void main(String[] args)
{
JiadianFactory jiadianFactory = new HaierJiadianFactory();
JiadianFactory jiadianFactory2 = new MideaJiadianFactory();
Refrigerator refrigerator = jiadianFactory.produceRefrigetor();
AirConditioningSystem airConditioningSystem = jiadianFactory.produceAirConditioningSystem();
refrigerator.produce();
airConditioningSystem.produce();
}
}
这样我们应用层的代码是和具体的空调以及电冰箱是解耦的。我们在客户类里并没由导入海尔空调以及海尔电冰箱的类。
其UML类图如下
优点
- 应用层代码不和具体的产品进行依赖,它只和具体的工厂发生依赖关系
- 扩展性好,当我们新增具体的产品时,只需要增加其对应的工厂,并不需要修改其他类的代码
缺点
- 新增产品等级比较麻烦,需要修改对应的工厂接口以及每一个实现类
- 增加了系统的抽象性和理解难度
使用场景
- 应用层不依赖与产品类实例如何创建、实现细节
- 强调一系列相关的产品对象(属于同一-产品族)一起使用创建对象需要大量重复的代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
应用
jdbc中的Connection
jdbc中的Connection为一个接口,里面有许多方法,这里我们挑选几个
Statement createStatement() throws SQLException;
DatabaseMetaData getMetaData() throws SQLException;
其中这两个方法返回的Statement和DataBasemetaData均为接口,其在具体的工厂类中进行实例化。我们可以把Connection理解为抽象工厂类,Statement和DataBasemetaData为产品类。而每一种数据库驱动都会有该Connection的自己具体实现类,比如在Mysql中具体实现类为CommectionImpl,对于这两个方法,其分别返回了自己的实现类StatementImpl和com.mysql.jdbc.DataBasemetaData。在这里com.mysql.jdbc.DataBasemetaData是java.sql.DataBasemetaData的一个具体实现类
MyBatis中的SqlSessionFactory
mybatis中的SqlSeeionFactory定义如下
我们可以发现其内部定义的方法返回结果有SqlSession接口和Configuration类对象。
SqlSeesionFactory相当于一个抽象工厂。而其实现有
DefaultSqlSessionFactory
和SqlSessionManager
,在这两个类中我们都可以获取其对应的具体SqlSession和Configuration实现
网友评论