目录
组合模式
定义:
业务实现例子:
桥接模式
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;}@Overridepublic double calculateSalary() {return salary;}
}
public class Department extends HumanResource {private List<HumanResource> subNodes = new ArrayList<>();public Department(long id) {super(id);}@Overridepublic 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<Long> subDepartmentIds = departmentRepo.getSubDepartmentIds(departmentfor (Long subDepartmentId : subDepartmentIds) {Department subDepartment = new Department(subDepartmentId);department.addSubNode(subDepartment);buildOrganization(subDepartment);}List<Long> employeeIds = employeeRepo.getDepartmentEmployeeIds(department.gfor (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 {@Overridepublic void paint() {System.out.println("画上蓝色");}
}
RedColorAPI :画红色的实现类
/*** Created on 2020/3/18* Package com.design_pattern.bridge** @author dsy*/
public class RedColorAPI implements ColorAPI
{@Overridepublic 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 {@Overridepublic void draw() {System.out.print("我是圆形");colorAPI.paint();}
}
/*** Created on 2020/3/18* Package com.design_pattern.bridge** @author dsy*/
public class Rectangle extends Shape {@Overridepublic 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 {@Overridepublic void draw() {System.out.println("我是三角形");colorAPI.paint();}
}
JDBC中的桥接模式
MySQL 的 Connection 接口实现的是 java.sql.Connection 接口,同时 Oracle 数据库也一样可以实现 java.sql.Connection 接口,他们向下都可以有更多的实现子类。
然后 DriverManager 相当于桥接模块(类似于上面的Shape基类),聚合 java.sql.Connection 接口,供客户端调用。
和我们上面所说有点不同,就是 DriverManager 不是抽象类,而是直接的具体实现。