1.概要
2.内容
1.结构型模式概述
以下是23种设计模式中7种结构型模式的详细介绍,包含定义、特点、应用场景和示例代码:
1. 适配器模式(Adapter Pattern)
- 定义:将一个类的接口转换成客户端期望的另一个接口,使原本不兼容的类能协同工作。
- 特点:通过继承或组合实现接口转换,提高代码复用性。
- 应用场景:集成第三方库、旧系统兼容、替换算法实现等。
- 示例代码:
// 目标接口 interface Target { void request(); } // 待适配类 class Adaptee { public void specificRequest() { System.out.println("Adaptee's specific request"); } } // 适配器类 class Adapter extends Adaptee implements Target { @Override public void request() { specificRequest(); } } // 使用 public class Main { public static void main(String[] args) { Target target = new Adapter(); target.request(); // 输出: Adaptee's specific request } }
2. 桥接模式(Bridge Pattern)
- 定义:将抽象部分与实现部分分离,使二者可独立变化。
- 特点:解耦抽象和实现,支持多维度扩展。
- 应用场景:跨平台图形渲染、设备驱动开发、多数据库支持等。
- 示例代码:
// 实现接口 interface DrawingAPI { void drawCircle(int x, int y, int radius); } // 具体实现类 class GreenCircle implements DrawingAPI { @Override public void drawCircle(int x, int y, int radius) { System.out.println("Drawing green circle at (" + x + "," + y + ") with radius " + radius); } } // 抽象形状类 abstract class Shape { protected DrawingAPI drawingAPI; public Shape(DrawingAPI drawingAPI) { this.drawingAPI = drawingAPI; } public abstract void draw(); } // 具体形状类 class Circle extends Shape { private int x, y, radius; public Circle(int x, int y, int radius, DrawingAPI drawingAPI) { super(drawingAPI); this.x = x; this.y = y; this.radius = radius; } @Override public void draw() { drawingAPI.drawCircle(x, y, radius); } } // 使用 public class Main { public static void main(String[] args) { Shape greenCircle = new Circle(100, 100, 50, new GreenCircle()); greenCircle.draw(); } }
3. 组合模式(Composite Pattern)
- 定义:将对象组合成树形结构,表示“整体-部分”层次结构。
- 特点:统一处理单个对象和组合对象,简化客户端代码。
- 应用场景:文件系统、GUI组件、组织结构管理等。
- 示例代码:
// 组件接口 interface Component { void operation(); } // 叶子节点 class Leaf implements Component { private String name; public Leaf(String name) { this.name = name; } @Override public void operation() { System.out.println("Leaf " + name + ": performing operation"); } } // 复合节点 class Composite implements Component { private List<Component> children = new ArrayList<>(); public void add(Component component) { children.add(component); } public void remove(Component component) { children.remove(component); } @Override public void operation() { for (Component child : children) { child.operation(); } } } // 使用 public class Main { public static void main(String[] args) { Composite root = new Composite(); root.add(new Leaf("Leaf 1")); root.add(new Leaf("Leaf 2")); Composite composite = new Composite(); composite.add(new Leaf("Leaf 3")); root.add(composite); root.operation(); } }
4. 装饰器模式(Decorator Pattern)
- 定义:动态地为对象添加额外职责,而不改变其原有代码。
- 特点:灵活扩展功能,避免继承带来的子类爆炸问题。
- 应用场景:GUI组件扩展、日志记录、权限控制等。
- 示例代码:
// 抽象组件 interface Component { void operation(); } // 具体组件 class ConcreteComponent implements Component { @Override public void operation() { System.out.println("ConcreteComponent operation"); } } // 抽象装饰器 abstract class Decorator implements Component { protected Component component; public Decorator(Component component) { this.component = component; } @Override public void operation() { component.operation(); } } // 具体装饰器 class ConcreteDecorator extends Decorator { public ConcreteDecorator(Component component) { super(component); } @Override public void operation() { super.operation(); System.out.println("ConcreteDecorator added behavior"); } } // 使用 public class Main { public static void main(String[] args) { Component component = new ConcreteComponent(); component = new ConcreteDecorator(component); component.operation(); } }
5. 外观模式(Facade Pattern)
- 定义:为复杂子系统提供一个简化接口。
- 特点:隐藏子系统复杂性,提高系统易用性。
- 应用场景:简化API调用、分层架构中的层间通信等。
- 示例代码:
// 子系统类1 class SubsystemA { public void methodA() { System.out.println("SubsystemA method"); } } // 子系统类2 class SubsystemB { public void methodB() { System.out.println("SubsystemB method"); } } // 外观类 class Facade { private SubsystemA subsystemA = new SubsystemA(); private SubsystemB subsystemB = new SubsystemB(); public void simpleOperation() { subsystemA.methodA(); subsystemB.methodB(); } } // 使用 public class Main { public static void main(String[] args) { Facade facade = new Facade(); facade.simpleOperation(); } }
6. 享元模式(Flyweight Pattern)
- 定义:通过共享技术减少大量细粒度对象的内存占用。
- 特点:减少对象创建开销,提高系统性能。
- 应用场景:文本编辑器、图形编辑器、游戏对象管理等。
- 示例代码:
// 享元接口 interface Flyweight { void operation(String extrinsicState); } // 具体享元类 class ConcreteFlyweight implements Flyweight { private String intrinsicState; public ConcreteFlyweight(String intrinsicState) { this.intrinsicState = intrinsicState; } @Override public void operation(String extrinsicState) { System.out.println("Intrinsic: " + intrinsicState + ", Extrinsic: " + extrinsicState); } } // 享元工厂 class FlyweightFactory { private Map<String, Flyweight> flyweights = new HashMap<>(); public Flyweight getFlyweight(String key) { Flyweight flyweight = flyweights.get(key); if (flyweight == null) { flyweight = new ConcreteFlyweight(key); flyweights.put(key, flyweight); } return flyweight; } } // 使用 public class Main { public static void main(String[] args) { FlyweightFactory factory = new FlyweightFactory(); Flyweight flyweight1 = factory.getFlyweight("State A"); Flyweight flyweight2 = factory.getFlyweight("State B"); flyweight1.operation("External State 1"); flyweight2.operation("External State 2"); } }
7. 代理模式(Proxy Pattern)
- 定义:为其他对象提供一种代理,控制对该对象的访问。
- 特点:延迟加载、权限控制、远程代理等。
- 应用场景:图片懒加载、数据库连接池、远程方法调用等。
- 示例代码:
// 抽象主题 interface Subject { void request(); } // 真实主题 class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject processing request"); } } // 代理类 class Proxy implements Subject { private RealSubject realSubject; @Override public void request() { if (realSubject == null) { realSubject = new RealSubject(); } realSubject.request(); } } // 使用 public class Main { public static void main(String[] args) { Proxy proxy = new Proxy(); proxy.request(); // 输出: RealSubject processing request } }
结构型模式总结
模式名称 | 核心思想 | 典型应用场景 |
---|---|---|
适配器模式 | 接口转换 | 旧系统兼容、第三方库集成 |
桥接模式 | 抽象与实现分离 | 跨平台开发、多维度变化 |
组合模式 | 树形结构统一处理 | 文件系统、GUI组件管理 |
装饰器模式 | 动态扩展职责 | 功能增强、避免继承爆炸 |
外观模式 | 简化子系统接口 | 复杂系统封装、分层架构通信 |
享元模式 | 对象共享 | 大量细粒度对象管理 |
代理模式 | 访问控制 | 延迟加载、远程代理、权限控制 |
这些模式通过不同的组合方式,帮助开发者构建更灵活、可扩展和易维护的系统结构。在实际项目中,可以根据具体需求选择合适的模式进行组合应用。
2.用坦克大战实现结构性模式
适配器、组合、外观、代理这几种模式的特点笔记明显,甚至可以说是需求模式,就是有类似的需求就可以采用这种模式。所以不适合用坦克大战这个需求就行对比演示;而相对的桥接、组合、装饰、享元,者是通用性比较强的模式,所以如下用坦克大战这个需求演示一下,以体现模式的特点。
1.装饰模式
需求:用装饰模式装饰坦克的功能,坦克的功能有射击,跑,红外瞄准,gps等
以下是使用Java实现装饰模式装饰坦克功能的示例代码:
// 1. 定义坦克基础接口
interface Tank {
String move();
String getDescription();
}
// 2. 创建基础坦克类
class BasicTank implements Tank {
@Override
public String move() {
return "坦克正在移动";
}
@Override
public String getDescription() {
return "基础型坦克";
}
}
// 3. 创建装饰器基类
abstract class TankDecorator implements Tank {
protected Tank decoratedTank;
public TankDecorator(Tank tank) {
this.decoratedTank = tank;
}
@Override
public String move() {
return decoratedTank.move();
}
@Override
public String getDescription() {
return decoratedTank.getDescription();
}
}
// 4. 实现具体装饰器
class InfraredAimDecorator extends TankDecorator {
public InfraredAimDecorator(Tank tank) {
super(tank);
}
public String aim() {
return "红外瞄准已启动";
}
@Override
public String getDescription() {
return super.getDescription() + " + 红外瞄准";
}
}
class GPSDecorator extends TankDecorator {
public GPSDecorator(Tank tank) {
super(tank);
}
public String navigate() {
return "GPS导航已激活";
}
@Override
public String getDescription() {
return super.getDescription() + " + GPS导航";
}
}
class DesignUpgradeDecorator extends TankDecorator {
public DesignUpgradeDecorator(Tank tank) {
super(tank);
}
@Override
public String getDescription() {
return super.getDescription() + "(改进型设计)";
}
}
// 5. 使用示例
public class Main {
public static void main(String[] args) {
// 创建基础坦克
Tank tank = new BasicTank();
System.out.println(tank.getDescription()); // 输出: 基础型坦克
System.out.println(tank.move()); // 输出: 坦克正在移动
// 添加红外瞄准功能
tank = new InfraredAimDecorator(tank);
System.out.println("\n" + tank.getDescription()); // 输出: 基础型坦克 + 红外瞄准
System.out.println(((InfraredAimDecorator) tank).aim()); // 输出: 红外瞄准已启动
// 添加GPS导航功能
tank = new GPSDecorator(tank);
System.out.println("\n" + tank.getDescription()); // 输出: 基础型坦克 + 红外瞄准 + GPS导航
System.out.println(((GPSDecorator) tank).navigate()); // 输出: GPS导航已激活
// 添加设计升级
tank = new DesignUpgradeDecorator(tank);
System.out.println("\n" + tank.getDescription()); // 输出: 基础型坦克 + 红外瞄准 + GPS导航(改进型设计)
}
}
代码说明:
- 接口定义:
Tank
接口定义了坦克的核心方法move()
和getDescription()
- 基础实现:
BasicTank
类提供了基础功能的实现 - 装饰器基类:
TankDecorator
作为抽象装饰器,持有被装饰对象的引用 - 具体装饰器:
InfraredAimDecorator
:添加红外瞄准功能GPSDecorator
:添加GPS导航功能DesignUpgradeDecorator
:添加设计升级描述
- 动态组合:通过嵌套装饰器实现功能的叠加,可以灵活组合不同功能模块
扩展建议:
- 可以继续添加新的装饰器(如
NightVisionDecorator
夜视功能) - 可以创建
ReactiveArmorDecorator
反应装甲装饰器 - 可以通过工厂模式来管理装饰器的创建组合
- 可以添加更多坦克基础功能(如射击、通讯等)并创建对应的装饰器
这种实现方式遵循了开闭原则,新增功能时无需修改现有类,只需创建新的装饰器即可,非常符合装饰模式的核心思想。
2.桥接模式
需求:用桥接模式装饰坦克的功能,坦克有两个功能是,本身功能是跑。桥接的功能是射击,设计根据不同的型号设置不同的射程。跑的功能可以根据不同的型号拥有不同的速度
以下是使用Java桥接模式实现坦克不同功能组合的示例代码:
// 1. 定义功能接口
interface Movement {
String move();
}
interface Shooting {
String shoot();
}
// 2. 实现具体功能类
class FastMovement implements Movement {
@Override
public String move() {
return "高速移动:80 km/h";
}
}
class SlowMovement implements Movement {
@Override
public String move() {
return "低速移动:40 km/h";
}
}
class LongRangeShooting implements Shooting {
@Override
public String shoot() {
return "远程射击:射程 2000m";
}
}
class ShortRangeShooting implements Shooting {
@Override
public String shoot() {
return "近程射击:射程 800m";
}
}
// 3. 定义抽象坦克类
abstract class Tank {
protected Movement movement;
protected Shooting shooting;
public Tank(Movement movement, Shooting shooting) {
this.movement = movement;
this.shooting = shooting;
}
public String run() {
return movement.move();
}
public String fire() {
return shooting.shoot();
}
public abstract String getType();
}
// 4. 实现具体坦克子类
class LightTank extends Tank {
public LightTank(Movement movement, Shooting shooting) {
super(movement, shooting);
}
@Override
public String getType() {
return "轻型坦克";
}
}
class HeavyTank extends Tank {
public HeavyTank(Movement movement, Shooting shooting) {
super(movement, shooting);
}
@Override
public String getType() {
return "重型坦克";
}
}
// 5. 使用示例
public class Main {
public static void main(String[] args) {
// 创建不同配置的坦克
Tank lightTank = new LightTank(new FastMovement(), new ShortRangeShooting());
Tank heavyTank = new HeavyTank(new SlowMovement(), new LongRangeShooting());
// 测试轻型坦克
System.out.println(lightTank.getType());
System.out.println(lightTank.run()); // 输出: 高速移动:80 km/h
System.out.println(lightTank.fire()); // 输出: 近程射击:射程 800m
// 测试重型坦克
System.out.println("\n" + heavyTank.getType());
System.out.println(heavyTank.run()); // 输出: 低速移动:40 km/h
System.out.println(heavyTank.fire()); // 输出: 远程射击:射程 2000m
}
}
代码结构说明:
- 功能接口:
Movement
:定义移动行为Shooting
:定义射击行为
- 具体功能实现:
FastMovement
/SlowMovement
:不同移动速度的实现LongRangeShooting
/ShortRangeShooting
:不同射程的实现
- 抽象坦克类:
- 通过构造函数注入移动和射击功能
- 定义通用的
run()
和fire()
方法
- 具体坦克子类:
LightTank
:轻型坦克HeavyTank
:重型坦克
- 组合使用:
- 通过组合不同的功能实现类,可以灵活创建不同配置的坦克
- 修改配置只需更换对应的功能实现类
扩展建议:
- 可以添加更多功能维度(如装甲类型、通讯系统等)
- 可以创建更多坦克型号(如中型坦克、侦察坦克)
- 可以添加功能参数化(如射程值、速度值作为构造参数)
- 可以结合工厂模式来创建坦克实例
这种实现方式符合桥接模式的核心思想:将抽象部分与实现部分分离,使它们可以独立变化。当需要扩展新功能或新坦克型号时,只需添加新的接口实现类,而不需要修改现有类结构。
3.享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,主要用于减少创建对象的数量,通过共享技术来有效支持大量细粒度对象的复用。以下是如何使用享元模式创建不同射程坦克的详细设计:
1. 享元模式核心结构
(1)抽象享元类(TankFlyweight)
public abstract class TankFlyweight {
// 内部状态(共享部分):坦克型号
protected final String model;
public TankFlyweight(String model) {
this.model = model;
}
// 抽象操作:发射炮弹(需要外部状态射程)
public abstract void fire(int range);
}
(2)具体享元类(ConcreteTank)
public class ConcreteTank extends TankFlyweight {
// 内部状态:可共享的坦克属性(如装甲类型、炮管长度等)
private final String armorType;
private final double barrelLength;
public ConcreteTank(String model, String armorType, double barrelLength) {
super(model);
this.armorType = armorType;
this.barrelLength = barrelLength;
}
@Override
public void fire(int range) {
System.out.printf("型号[%s] 射程[%d] 装甲[%s] 炮管[%s] 的坦克正在发射!%n",
model, range, armorType, barrelLength);
}
}
(3)享元工厂(TankFlyweightFactory)
import java.util.HashMap;
import java.util.Map;
public class TankFlyweightFactory {
// 享元池(键:型号,值:享元对象)
private static final Map<String, TankFlyweight> tankPool = new HashMap<>();
public static TankFlyweight getTank(String model, String armorType, double barrelLength) {
TankFlyweight tank = tankPool.get(model);
if (tank == null) {
tank = new ConcreteTank(model, armorType, barrelLength);
tankPool.put(model, tank);
System.out.println("创建新坦克型号: " + model);
}
return tank;
}
}
2. 客户端使用示例
public class Client {
public static void main(String[] args) {
// 创建不同射程的坦克(共享相同型号)
TankFlyweight tank1 = TankFlyweightFactory.getTank("M1A2", "复合装甲", 120);
tank1.fire(2500); // 射程2500米
TankFlyweight tank2 = TankFlyweightFactory.getTank("M1A2", "复合装甲", 120);
tank2.fire(3000); // 射程3000米
// 新型号坦克
TankFlyweight tank3 = TankFlyweightFactory.getTank("豹2A7", "间隙装甲", 125);
tank3.fire(2800);
}
}
3. 执行结果
创建新坦克型号: M1A2
型号[M1A2] 射程[2500] 装甲[复合装甲] 炮管[120.0] 的坦克正在发射!
型号[M1A2] 射程[3000] 装甲[复合装甲] 炮管[120.0] 的坦克正在发射!
创建新坦克型号: 豹2A7
型号[豹2A7] 射程[2800] 装甲[间隙装甲] 炮管[125.0] 的坦克正在发射!
4. 设计要点分析
- 状态分离:
- 内部状态(共享):型号、装甲类型、炮管长度等不变属性
- 外部状态(非共享):射程、燃料量等可变属性通过方法参数传入
- 享元池管理:
- 使用HashMap实现快速查找
- 线程安全可通过ConcurrentHashMap优化
- 扩展性:
- 新增坦克型号时自动创建新享元
- 相同型号的不同射程坦克共享基础属性
- 内存优化:
- 当需要1000辆M1A2坦克时,只需1个享元对象
- 射程等运行时状态由客户端维护
5. 适用场景
- 需要创建大量相似对象
- 对象的大部分状态可以外部化
- 系统内存资源紧张
- 对象创建成本较高(如复杂初始化)
该模式在军事模拟、游戏开发等需要管理大量相似实体的场景中特别有效,通过共享不变属性显著降低内存消耗。