抽象工厂设计模式
定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类
类型:创建型
抽象工厂-适用场景
1.客户端(应用层)不依赖与产品类示例如何被创建、实现等细节
2.强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
3.提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖与具体实现
优点:
1.具体产品在应用层代码隔离,无需关心创建细节
2.将一个系列的产品族统一到一起创建
缺点:
1.规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
2.增加了系统的抽象性和理解难度
抽象工厂图示:同一种图形表示同一个类型工厂,同一种颜色表示同一个产品族
具体解释图:
假设场景:
假设现在有一个操作用户信息的数据库操作,假设如下代码是操作mysql数据访问链接的方式,那么现在要求更改为oracle的方式,这样的话由于访问方式不一样,需要修改的地方可能会很多或者从新写一个,但是假如以后增加sqlServcer数据库或者别的能,都是需要进行修改的。那么我们能不能提前定义多个数据库访问方式根据具体需求只需要修改少量地方来完成需求
public class User {
private Long id;
private String name;
public User(Long id) {
this.id = id;
}
}
public class UserService {
public void insert(User user){
System.out.println("插入用户信息");
}
public User get(Long id){
System.out.println("获取用户信息");
return new User(id);
}
}
//假设操作信息
public class Main {
public static void main(String[] args) {
User user = new User(9L);
UserService us = new UserService();
User user1 = us.get(8L);
us.insert(user);
}
}
抽象工厂方式:
定义连接类型的工厂接口,由具体连接工厂来实现操作细节
//辅助domain
public class User {
private Long id;
private String name;
public User(Long id) {
this.id = id;
}
}
public class Dept {
private Long id;
private String deptName;
public Dept(Long id) {
this.id = id;
}
}
//产品族接口定义相当于上图中的冰箱、空调,洗衣机的定义
//用户操作产品族-假设空调
public interface IUserService {
//具体操作行为
public User getIUser(Long id);
public void insert(User user);
}
//部门操作产品族-假设冰箱
public interface IDeptService {
//具体操作行为
public Dept getIDept(Long id);
public void insertDept(Dept dept);
}
//--------------------------------工厂部分
//抽象工厂接口
public interface DbFactory {
public IDeptService getIDept();
public IUserService getIUser();
}
//相当于是美的工厂
public class MysqlFacotry implements DbFactory {
@Override
public IDeptService getIDept() {//生产冰箱
return new MysqlDeptService();
}
@Override
public IUserService getIUser() {//生产空调
return new MysqlUserService();
}
}
//相当于是海尔工厂
public class OracleFactory implements DbFactory {
@Override
public IDeptService getIDept() {//生产冰箱
return new OracleDeptService();
}
@Override
public IUserService getIUser() {//生产空调
return new OracleUserService();
}
}
//相当于工厂生产的具体产品
//美的工厂生产的空调
public class MysqlUserService implements IUserService{
@Override
public User getIUser(Long id) {//
System.out.println("mysql 获取用户信息");
return new User(id);
}
@Override
public void insert(User user) {//
System.out.println("mysql 插入用户信息");
}
}
//美的工厂生产的冰箱
public class MysqlDeptService implements IDeptService {
@Override
public Dept getIDept(Long id) {
System.out.println("使用mysql 获取部门信息");
return new Dept(id);
}
@Override
public void insertDept(Dept dept) {
System.out.println("使用mysql 插入部门信息");
}
}
//海尔工厂生产的空调
public class OracleUserService implements IUserService {
@Override
public User getIUser(Long id) {
System.out.println("oracle 获取用户信息");
return new User(id);
}
@Override
public void insert(User user) {
System.out.println("oracle 插入用户信息");
}
}
//海尔工厂生产的冰箱
public class OracleDeptService implements IDeptService {
@Override
public Dept getIDept(Long id) {
System.out.println("使用oracle 获取部门信息");
return new Dept(id);
}
@Override
public void insertDept(Dept dept) {
System.out.println("使用oracle 插入部门信息");
}
}
//测试
public class MainTest {
public static void main(String[] args) {
//更换数据库连接只需new的实例发生变化即可
// DbFactory db = new MysqlFacotry();
DbFactory db = new OracleFactory();
//下面代码实现了与具体生产细节的解耦
IDeptService iDept = db.getIDept();
Dept iDept1 = iDept.getIDept(8L);
iDept.insertDept(new Dept(9L));
IUserService iUser = db.getIUser();
User iUser1 = iUser.getIUser(1L);
iUser.insert(new User(2L));
}
}
抽象工厂与工厂方法的关系:
工厂方法模式是一种极端情况的抽象工厂模式(即只生产一种产品的抽象工厂模式),而抽象工厂模式可以看成是工厂方法模式的一种推广。
具体区别可看:https://www.cnblogs.com/qiaoconglovelife/p/5750290.html
来源于:大话设计模式书籍、慕课网geely老师的视频