回顾上节:
- 随着对象种类、属性容量的扩大,创建具体对象、管理属性装配、快速复制等,都面临难题,这时产生了工厂、建造者、原型等设计模式;
- 单例模式也保护了全局变量,提高了全局访问、使用全局对象和接口的 安全性、规范性、可用性 等等
目录
1 适配器模式 (Adapter)
方法依赖别的接口,但不重载?
这种时候需要适配器模式
- 定义 适配器,聚合 被适配的接口,实现 需求的接口
类图和代码实现
类图:
代码实现:
class HuaweiComputer implements Computer{
String readSD(SDCard sd){
return sd.readSD();
} // Computer 接口这里就不写了
}
interface SDCard {
String readSD();
}
interface HardDisk {
String readHD();
}
class SD2HD_Adapter implements SDCard {
HardDisk hd;
@Override
String readSD(){
return hd.readHD();
}
}
2 装饰器模式 (Decorator)
递归引用地 添加 多层功能
增强接口通过装饰器的递归调用实现,而整体的功能增强其实就是链表
类图和代码实现
测试类:
Computer cpt = new HuaweiComputer();
cpt = new RTX4090(cpt);
cpt = new Memory16G(cpt);
cpt = new Memory16G(cpt);
cpt = new Disk256G(cpt);
System.out.println("总共花费:" + cpt.cost() + "元");
/**
* 输出结果:
外加外存:256G || 799 元
外加内存条:16G || 899 元
外加内存条:16G || 899 元
外加显卡:RTX4090 || 7999 元
Huawei基础电脑 || 8999 元
总共花费:19595元
*/
类定义:
class HuaweiComputer implements Computer{
int cost(){
System.out.println("Huawei基础电脑 || 8999 元");
return 8999;
}
}
class RTX4090 extends ComputerDecorator {
Computer cpt;
RTX4090(Computer cpt){
this.cpt = cpt;
}
int cost(){
System.out.println("外加显卡:RTX4090 || 7999 元");
return 7999 + cpt.cost();
}
}
class Memory16G extends ComputerDecorator {
Computer cpt;
Memory16G(Computer cpt){
this.cpt = cpt;
}
int cost(){
System.out.println("外加内存条:16G || 899 元");
return 899 + cpt.cost();
}
}
class Disk256G extends ComputerDecorator {
Computer cpt;
Disk256G(Computer cpt){
this.cpt = cpt;
}
int cost(){
System.out.println("外加外存:256G || 799 元");
return 799 + cpt.cost();
}
}
3 组合模式
多叉树的聚合
对于不同层级的集合,不定义每一层级的类,而是取它们的共性类作为节点类,建立一颗树,避免了继承和实现,减少了类爆炸
类图和代码实现
类图:略,主要是多叉树的结构
// 员工类
@AllArgumentsConstructor
class Emp {
String name; // 姓名
String position; // 职位
int salary; // 薪水
ArrayList<Emp> directSublist;// 直接下级
// 获得员工信息
public String getCorpInfo() {
return String.format(
"姓名: %s 职位: %s 薪水: %d 元",
name, position, salary
);
}
// 添加直属下级
public void addDirectSubEmps(Emp... emps) {
directSublist.addAll(Arrays.asList(emps));
}
// 返回直属下级列表
public List<AbsEmp> getDirectSubEmps() {
return directSublist;
}
}