目录
组合模式
定义:
业务实现例子:
桥接模式
JDBC中的桥接模式
组合模式
将对象组合通过树形结构进行展示,使得用户——>不管对单个对象or组合对象的使用具有一致性
可以理解为部分-整体模式——>简单来说就是树的递归回溯
角色介绍:
Component:一个业务构件,为我们leaf叶子节点和Composite容器对象声明接口
leaf:叶子节点,实现管理构件的方法
Composite:容器对象,包含叶子节点,可以递归调用子节点的业务方法
比如多个部门,每个部门下面又有子部门,我们需要统计部门人员的总薪资,这时候我们可以用组合模式的思想进行统计(是一个树状,对树进行遍历统计)
部门包含子部门和员工,这是一种嵌套结构,可以表示成树这种数据结构。计算每个部分的薪资开支这样一个需求,可以通过在树上的遍历算法来实现。所以,从这个角度来看,这个应用场景可以使用组合模式来设计和实现
类介绍:
HumanResource 是部门类(Department)和员工类(Employee)抽象出来的父类,为的是能统一薪资的处理逻辑(递归得子钱,一步步返回得大钱)。Demo 中的代码负责从数据库中读取数据并在内存中构建组织架构图
public abstract class HumanResource {
protected long id;
protected double salary;
public HumanResource(long id) {
this.id = id;
}
public long getId() {
return id;
}
public abstract double calculateSalary();
}
public class Employee extends HumanResource {
public Employee(long id, double salary) {
super(id);
this.salary = salary;
}
@Override
public double calculateSalary() {
return salary;
}
}
public class Department extends HumanResource {
private List subNodes = new ArrayList<>();
public Department(long id) {
super(id);
}
@Override
public double calculateSalary() {
double totalSalary = 0;
for (HumanResource hr : subNodes) {
totalSalary += hr.calculateSalary();
}
this.salary = totalSalary;
return totalSalary;
}
public void addSubNode(HumanResource hr) {
subNodes.add(hr);
}
}
// 构建组织架构的代码
public class Demo {
private static final long ORGANIZATION_ROOT_ID = 1001;
private DepartmentRepo departmentRepo; // 依赖注入
private EmployeeRepo employeeRepo; // 依赖注入
public void buildOrganization() {
Department rootDepartment = new Department(ORGANIZATION_ROOT_ID);
buildOrganization(rootDepartment);
}
private void buildOrganization(Department department) {
List subDepartmentIds = departmentRepo.getSubDepartmentIds(department
for (Long subDepartmentId : subDepartmentIds) {
Department subDepartment = new Department(subDepartmentId);
department.addSubNode(subDepartment);
buildOrganization(subDepartment);
}
List employeeIds = employeeRepo.getDepartmentEmployeeIds(department.g
for (Long employeeId : employeeIds) {
double salary = employeeRepo.getEmployeeSalary(employeeId);
department.addSubNode(new Employee(employeeId, salary));
}
}
}
桥接模式
场景: 当有两个类:糖水燕窝和其他的燕窝种类,然后销售方式有两种,那么如果我们继承的花,每加一个类就会造成指数型的增长(你可以想象为一个二维数组,如果+一个销售渠道和一个燕窝类型就变为3x3)
模式优点
(1)实现了抽象和实现部分的分离
桥接模式分离了抽象部分和实现部分,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,分别定义接口,这有助于系统进行分层设计,从而产生更好的结构化系统。对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了。
(2)可动态的切换实现
由于桥接模式实现了抽象和实现的分离,所以在实现桥接模式时,就可以实现动态的选择和使用具体的实现。
(3)更好的可扩展性
由于桥接模式把抽象部分和实现部分分离了,从而分别定义接口,这就使得抽象部分和实现部分可以分别独立扩展,而不会相互影响,大大的提供了系统的可扩展性。(4)实现细节对客户端透明,可以对用户隐藏实现细节
桥接模式进行优化
本质就是将抽象和实现进行解耦,创建一个连接类,实现功能类的组合,而不再是继承,减少了创建类的开销——>x变为+
代码实现案例
参考这位的
(40条消息) 桥接模式(Bridge Pattern)-(最通俗易懂的案例)_你上来晒太阳的的博客-CSDN博客_桥接模式
ColorAPI :用于画各种颜色的接口
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public interface ColorAPI {
public void paint();
}
BlueColorAPI :画蓝色的实现类
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public class BlueColorAPI implements ColorAPI {
@Override
public void paint() {
System.out.println("画上蓝色");
}
}
RedColorAPI :画红色的实现类
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public class RedColorAPI implements ColorAPI
{
@Override
public void paint() {
System.out.println("画上红色");
}
}
Shape :抽象形状类
我们通过客户端给形状注入客户想要的颜色(setColor),draw方法在后面的形状子类也会进行重写——>本质是调用颜色的paint()方法
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public abstract class Shape {
protected ColorAPI colorAPI; //添加一个颜色的成员变量以调用ColorAPI 的方法来实现给不同的形状上色
public void setDrawAPI(ColorAPI colorAPI) { //注入颜色成员变量
this.colorAPI= colorAPI;
}
public abstract void draw();
}
Circle :圆形类
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public class Circle extends Shape {
@Override
public void draw() {
System.out.print("我是圆形");
colorAPI.paint();
}
}
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public class Rectangle extends Shape {
@Override
public void draw() {
System.out.print("我是长方形");
colorAPI.paint();
}
}
client客户端:set客户想要的颜色进行组合
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public class Client {
public static void main(String[] args) {
//创建一个圆形
Shape shape = new Circle();
//给圆形蓝色的颜料
shape.setDrawAPI(new BlueColorAPI());
//上色
shape.draw();
//创建一个长方形
Shape shape1 = new Rectangle();
//给长方形红色的颜料
shape1.setDrawAPI(new RedColorAPI());
//上色
shape1.draw();
}
}
添加一个新的类三角形,就只需要添加一个三角形类即可
/**
* Created on 2020/3/18
* Package com.design_pattern.bridge
*
* @author dsy
*/
public class Triangle extends Shape {
@Override
public void draw() {
System.out.println("我是三角形");
colorAPI.paint();
}
}
MySQL 的 Connection 接口实现的是 java.sql.Connection 接口,同时 Oracle 数据库也一样可以实现 java.sql.Connection 接口,他们向下都可以有更多的实现子类。
然后 DriverManager 相当于桥接模块(类似于上面的Shape基类),聚合 java.sql.Connection 接口,供客户端调用。
和我们上面所说有点不同,就是 DriverManager 不是抽象类,而是直接的具体实现。