抽象工厂模式
1.基础知识
定义∶
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口
无须指定它们具体的类
类型∶创建型
适用场景
客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
优点
具体产品在应用层代码隔离,无须关心创建细节
将一个系列的产品族统一到一起创建
缺点
规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,,需要修改抽象工厂的接口
增加了系统的抽象性和理解难度
抽象工厂模式就是解决产品族的问题的
2.实战
总算到这个模式了,一直想用KFC和麦当劳举例子,感觉很有意思,很好玩,走起!
这里的KFC工厂就是一个产品族,生产各式各样的单品,比如华莱士那就是一个新的factory了。
UML如图:
/**
* @Author LYS
* @Date 2022/1/17 22:39
* @Version 1.0
*/
public interface ChickFactory {
IceCream makeIceCream();
Hamburger makeHamburger();
}
/**
* @Author LYS
* @Date 2022/1/17 22:39
* @Version 1.0
*/
public abstract class Hamburger {
public abstract void getHamburger();
}
/**
* @Author LYS
* @Date 2022/1/17 22:40
* @Version 1.0
*/
public abstract class IceCream {
public abstract void getIceCream();
}
/**
* @Author LYS
* @Date 2022/1/17 22:48
* @Version 1.0
*/
public class KFCChickFactory implements ChickFactory{
@Override
public IceCream makeIceCream() {
return new KFCIceCream();
}
@Override
public Hamburger makeHamburger() {
return new KFCHamburger();
}
}
/**
* @Author LYS
* @Date 2022/1/17 22:41
* @Version 1.0
*/
public class KFCHamburger extends Hamburger{
@Override
public void getHamburger() {
System.out.println("生产肯德基文和友香辣小龙虾烤鸡汉堡");
}
}
/**
* @Author LYS
* @Date 2022/1/17 22:45
* @Version 1.0
*/
public class KFCIceCream extends IceCream{
@Override
public void getIceCream() {
System.out.println("生产肯德基北海道冰淇淋");
}
}
/**
* @Author LYS
* @Date 2022/1/17 22:50
* @Version 1.0
*/
public class McDonaldChickFactory implements ChickFactory{
@Override
public IceCream makeIceCream() {
return new McDonaldIceCream();
}
@Override
public Hamburger makeHamburger() {
return new McDonaldHamburger();
}
}
/**
* @Author LYS
* @Date 2022/1/17 22:43
* @Version 1.0
*/
public class McDonaldHamburger extends Hamburger{
@Override
public void getHamburger() {
System.out.println("生产麦当劳安格斯max厚牛培根汉堡");
}
}
/**
* @Author LYS
* @Date 2022/1/17 22:46
* @Version 1.0
*/
public class McDonaldIceCream extends IceCream{
@Override
public void getIceCream() {
System.out.println("生产麦当劳麦旋风");
}
}
/**
* @Author LYS
* @Date 2022/1/17 22:50
* @Version 1.0
*/
public class Test {
public static void main(String[] args) {
ChickFactory chickFactory1 = new KFCChickFactory();
Hamburger hamburger1 = chickFactory1.makeHamburger();
IceCream iceCream1 = chickFactory1.makeIceCream();
hamburger1.getHamburger();
iceCream1.getIceCream();
ChickFactory chickFactory2 = new McDonaldChickFactory();
Hamburger hamburger2 = chickFactory2.makeHamburger();
IceCream iceCream2 = chickFactory2.makeIceCream();
hamburger2.getHamburger();
iceCream2.getIceCream();
}
}
控制台输出:
3.源码
比如sql的Connection接口,这里的Statement,PreparedStatement都是Connection的产品族
public interface Connection extends Wrapper, AutoCloseable {
Statement createStatement() throws SQLException;
PreparedStatement prepareStatement(String sql)
throws SQLException;
SqlSessionFactory 返回的SqlSession和Configuration也是一个产品族
import java.sql.Connection;
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection);
Configuration getConfiguration();
}
可以看看这个类的具体实现
SqlSession openSession(ExecutorType execType, boolean autoCommit);
DefaultSqlSessionFactory类实现了这个方法,接口设置的返回类型是SqlSession,但实际返回的是DefaultSqlSession,是其子类
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
4.工厂方法和抽象工厂的区别
工厂方法模式解决同一产品等级的问题
抽象工厂模式解决产品族的问题