在前几篇文章中,我们详细探讨了多种结构型设计模式,今天来进行一个大总结——结构型设计模式主要关注类与对象的组合和组织,确保我们能够构建出稳固、灵活且易于维护的软件系统。无论你是初学者还是有经验的开发者,这篇文章都会帮你更好地掌握结构型模式的精髓。
结构型模式简介
结构型设计模式通过确定类与对象之间的关系,帮助我们形成更复杂且可维护的系统架构,它们通常涉及如何组合对象以实现更大的功能,并且可以分为七种主要模式:
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
- 组合模式(Composite Pattern)
- 装饰者模式(Decorator Pattern)
- 外观模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
一、适配器模式
核心思想
适配器模式通过将一个类的接口转换为另一个接口,使得原本由于接口不兼容而无法一起工作的类可以共同工作,适配器模式在兼容旧系统和第三方库时非常有用。
实现方式
Python实现
class OldInterface:
def old_method(self):
return "Old Interface"
class NewInterface:
def new_method(self):
return "New Interface"
class Adapter(NewInterface):
def __init__(self, old_interface):
self.old_interface = old_interface
def new_method(self):
return self.old_interface.old_method()
Java实现
public class OldInterface {
public String oldMethod() {
return "Old Interface";
}
}
public interface NewInterface {
String newMethod();
}
public class Adapter implements NewInterface {
private OldInterface oldInterface;
public Adapter(OldInterface oldInterface) {
this.oldInterface = oldInterface;
}
@Override
public String newMethod() {
return oldInterface.oldMethod();
}
}
应用场景
- 当你需要兼容旧系统或第三方库时;
- 当你需要将现有类与新接口兼容时。
二、桥接模式
核心思想
桥接模式通过分离抽象部分与实现部分,使得它们可以独立变化,桥接模式特别适用于需要跨越多个平台或支持多种实现方式的场景。
实现方式
Python实现
class DrawingAPI:
def draw_circle(self, x, y, radius):
pass
class OpenGLAPI(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"OpenGL Drawing: Circle at ({x}, {y}) with radius {radius}")
class Shape:
def __init__(self, drawing_api):
self.drawing_api = drawing_api
def draw(self):
pass
class Circle(Shape):
def __init__(self, x, y, radius, drawing_api):
super().__init__(drawing_api)
self.x = x
self.y = y
self.radius = radius
def draw(self):
self.drawing_api.draw_circle(self.x, self.y, self.radius)
Java实现
public interface DrawingAPI {
void drawCircle(double x, double y, double radius);
}
public class OpenGLAPI implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.println("OpenGL Drawing: Circle at (" + x + ", " + y + ") with radius " + radius);
}
}
public abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI drawingAPI) {
this.drawingAPI = drawingAPI;
}
public abstract void draw();
}
public class Circle extends Shape {
private double x, y, radius;
public Circle(double x, double y, double radius, DrawingAPI drawingAPI) {
super(drawingAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
}
应用场景
- 当你需要跨越多个平台或支持多种实现方式时;
- 当你需要将抽象和实现解耦时。
三、组合模式
核心思想
组合模式允许你将对象组合成树形结构,以表示“部分-整体”的层次结构,使得客户端可以以一致的方式处理单个对象和组合对象。
实现方式
Python实现
class Graphic:
def draw(self):
pass
class Line(Graphic):
def draw(self):
print("Drawing a Line")
class Rectangle(Graphic):
def draw(self):
print("Drawing a Rectangle")
class CompositeGraphic(Graphic):
def __init__(self):
self.graphics = []
def add(self, graphic):
self.graphics.append(graphic)
def draw(self):
for graphic in self.graphics:
graphic.draw()
Java实现
import java.util.ArrayList;
import java.util.List;
public abstract class Graphic {
public abstract void draw();
}
public class Line extends Graphic {
@Override
public void draw() {
System.out.println("Drawing a Line");
}
}
public class Rectangle extends Graphic {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class CompositeGraphic extends Graphic {
private List<Graphic> graphics = new ArrayList<>();
public void add(Graphic graphic) {
graphics.add(graphic);
}
@Override
public void draw() {
for (Graphic graphic : graphics) {
graphic.draw();
}
}
}
应用场景
- 当你需要表示对象的部分-整体层次结构时;
- 当你希望客户端以统一的方式处理单个对象和组合对象时。
四、装饰者模式
核心思想
装饰者模式允许动态地为对象添加新功能,而不影响其他同类对象的功能。它通过将对象放入包含行为的装饰器对象中来实现功能扩展。
实现方式
Python实现
class Coffee:
def cost(self):
return 10
class MilkDecorator(Coffee):
def __init__(self, coffee):
self.coffee = coffee
def cost(self):
return self.coffee.cost() + 2
Java实现
public class Coffee {
public int cost() {
return 10;
}
}
public class MilkDecorator extends Coffee {
private Coffee coffee;
public MilkDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public int cost() {
return coffee.cost() + 2;
}
}
应用场景
- 当你需要在不修改对象结构的情况下添加功能时;
- 当你希望组合多个装饰者以实现更复杂的功能时。
五、外观模式
核心思想
外观模式为子系统中的一组接口提供了一个一致的界面,使得该子系统更容易使用。外观模式通过简化子系统接口,隐藏了复杂性。
实现方式
Python实现
class CPU:
def freeze(self):
print("CPU freeze")
def jump(self, position):
print(f"CPU jump to {position}")
def execute(self):
print("CPU execute")
class Memory:
def load(self, position, data):
print(f"Memory load data at {position}")
class HardDrive:
def read(self, lba, size):
return "data"
class ComputerFacade:
def __init__(self):
self.cpu = CPU()
self.memory = Memory()
self.hard_drive = HardDrive()
def start(self):
self.cpu.freeze()
self.memory.load(0, self.hard_drive.read(100, 1024))
self.cpu.jump(0)
self.cpu.execute()
Java实现
public class CPU {
public void freeze() {
System.out.println("CPU freeze");
}
public void jump(long position) {
System.out.println("CPU jump to " + position);
}
public void execute() {
System.out.println("CPU execute");
}
}
public class Memory {
public void load(long position, String data) {
System.out.println("Memory load data at " + position);
}
}
public class HardDrive {
public String read(long lba, int size) {
return "data";
}
}
public class ComputerFacade {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;
public ComputerFacade() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
public void start() {
cpu.freeze();
memory.load(0, hardDrive.read(100, 1024));
cpu.jump(0);
cpu.execute();
}
}
应用场景
- 当你希望简化复杂子系统的接口时;
- 当你需要为多个子系统提供统一接口时。
六、享元模式
核心思想
享元模式通过共享尽可能多的相似对象来减少内存使用,它通常用于处理大量细粒度对象的场景,比如图形对象或字符对象。
实现方式
Python实现
class Flyweight:
def __init__(self, intrinsic_state):
self.intrinsic_state = intrinsic_state
def operation(self, extrinsic_state):
print(f"Intrinsic: {self.intrinsic_state}, Extrinsic: {extrinsic_state}")
class FlyweightFactory:
_flyweights = {}
@staticmethod
def get_flyweight(key):
if key not in FlyweightFactory._flyweights:
FlyweightFactory._flyweights[key] = Flyweight(key)
return FlyweightFactory._flyweights[key]
Java实现
import java.util.HashMap;
import java.util.Map;
public class Flyweight {
private final String intrinsicState;
public Flyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
public void operation(String extrinsicState) {
System.out.println("Intrinsic: " + intrinsicState + ", Extrinsic: " + extrinsicState);
}
}
public class FlyweightFactory {
private static final Map<String, Flyweight> flyweights = new HashMap<>();
public static Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
flyweights.put(key, new Flyweight(key));
}
return flyweights.get(key);
}
}
应用场景
- 当你需要处理大量相似对象时;
- 当你希望通过共享来节省内存时。
七、代理模式
核心思想
代理模式为其他对象提供了一种代理以控制对这个对象的访问。代理模式可以用于延迟对象的创建、控制访问权限或添加额外的操作。
实现方式
Python实现
class RealSubject:
def request(self):
print("RealSubject: Handling request")
class Proxy:
def __init__(self):
self.real_subject = RealSubject()
def request(self):
print("Proxy: Before request")
self.real_subject.request()
print("Proxy: After request")
Java实现
public class RealSubject {
public void request() {
System.out.println("RealSubject: Handling request");
}
}
public class Proxy {
private RealSubject realSubject;
public Proxy() {
this.realSubject = new RealSubject();
}
public void request() {
System.out.println("Proxy: Before request");
realSubject.request();
System.out.println("Proxy: After request");
}
}
应用场景
- 当你需要控制对象的访问时;
- 当你需要延迟加载对象时。
总结
结构型设计模式为我们提供了组织代码、管理类与对象关系的强大工具,在实际开发中,灵活运用这些模式,可以大大提升代码的灵活性、可维护性和可扩展性。理解每个模式的核心思想和适用场景,能够帮助你在实际项目中选择最合适的设计模式。
希望通过这篇总结,大家能更清晰地了解结构型模式的精髓,并在实际开发中熟练运用。如果你有任何疑问或想法,欢迎在下方留言!别忘了关注我们的公众号,获取更多有趣的编程知识和实用的代码技巧,我们期待与你的交流与分享!