ITPub博客

首页 > 数据库 > 数据库开发技术 > 结构型设计模式(三):享元模式 & 代理模式 & 桥接模式

结构型设计模式(三):享元模式 & 代理模式 & 桥接模式

原创 数据库开发技术 作者:灸哥漫谈 时间:2023-12-17 15:11:28 0 删除 编辑

享元模式 Flyweight

1、什么是享元模式

享元模式的核心思想是共享对象,即通过尽可能多地共享相似对象来减少内存占用或计算开销。这意味着相同或相似的对象在内存中只存在一个共享实例。

2、为什么使用享元模式

  1. 减少内存使用:通过共享相似对象,减少了系统中对象的数量,从而减少了内存的使用。

  2. 提高性能:由于共享对象减少了创建和销毁的开销,提高了系统的性能。

  3. 简化代码:享元模式使得系统中的对象更加简单,因为需要相似的对象可以共享相同的状态。

3、如何使用享元模式

设计和实现一个文本编辑器,针对大量相似的字符对象,通过享元模式来共享相同字符对象

import java.util.HashMap;import java.util.Map;
// 抽象享元角色interface CharFlyweight { void display();}
// 具体享元角色class ConcreteCharFlyweight implements CharFlyweight { private char character;
public ConcreteCharFlyweight(char character) { this.character = character; }
@Override public void display() { System.out.print(character); }}
// 享元工厂class CharFlyweightFactory { private Map<Character, CharFlyweight> flyweights = new HashMap<>();
public CharFlyweight getCharFlyweight(char character) { if (!flyweights.containsKey(character)) { flyweights.put(character, new ConcreteCharFlyweight(character)); } return flyweights.get(character); }}
// 客户端代码public class Client { public static void main(String[] args) { CharFlyweightFactory factory = new CharFlyweightFactory();
CharFlyweight a = factory.getCharFlyweight('a'); CharFlyweight b = factory.getCharFlyweight('b'); CharFlyweight aAgain = factory.getCharFlyweight('a');
a.display(); // 输出:a b.display(); // 输出:b aAgain.display(); // 输出:a
// 对比对象是否相同 System.out.println("\nIs a the same object as aAgain? " + (a == aAgain)); }}

4、是否存在缺陷和不足

  1. 共享状态限制:享元模式主要适用于具有大量相似对象的情况,且这些对象可以共享状态。如果对象的状态不可共享,则不适合使用享元模式。

  2. 复杂性增加:在一些场景下,为了实现共享,需要将对象的一部分状态外部话,导致系统的复杂性增加。

5、如何缓解缺陷和不足

  1. 外部状态和内部状态分离:尽量将对象的外部状态(不可共享的状态)和内部状态(可共享的状态)清晰地分离,以便在不同的环境中使用。

  2. 合理使用享元模式:只有在系统中存在大量相似对象且能够共享状态时,才考虑使用享元模式,在其他情况下,可能并不切实际。

代理模式 Proxy

1、什么是代理模式

代理模式通过引入代理对象来控制对其他对象的访问。代理对象充当被代理对象的接口,可以在访问的时候添加额外的功能,比如安全性检查、缓存引入等操作功能。

2、为什么使用代理模式

  1. 控制访问:代理模式允许在访问对象时进行控制,可以添加额外的逻辑,比如权限检查、缓存引入等。

  2. 解耦:代理模式将客户端与目标对象解耦,客户端无需直接访问目标对象,降低了系统的耦合度。

  3. 延迟加载:代理模式可以实现延迟加载,在需要的时候再创建目标对象,提高系统的性能。

3、如何使用代理模式

设计实现一个 Image 接口,具体的实现类是 RealImage。通过代理模式,因为 ProxyImage 来控制对 RealImage 的访问

// 目标接口interface Image {    void display();}
// 具体目标类class RealImage implements Image { private String filename;
public RealImage(String filename) { this.filename = filename; loadFromDisk(); }
private void loadFromDisk() { System.out.println("Loading image: " + filename); }
@Override public void display() { System.out.println("Displaying image: " + filename); }}
// 代理类class ProxyImage implements Image { private RealImage realImage; private String filename;
public ProxyImage(String filename) { this.filename = filename; }
@Override public void display() { if (realImage == null) { realImage = new RealImage(filename); } realImage.display(); }}
// 客户端代码public class Client { public static void main(String[] args) { Image image = new ProxyImage("example.jpg");
// 图像第一次加载 image.display();
// 图像第二次加载,使用缓存 image.display(); }}

4、是否存在缺陷和不足

  1. 复杂性增加:引入代理对象可能会增加系统的复杂性,因为需要额外的类来管理代理和目标对象。

  2. 性能开销:在某些情况下,代理模式可能引入一定的性能开销,尤其是在代理对象的创建和销毁方面。

5、如何缓解缺陷和不足

  1. 智能代理:使用智能代理,根据具体情况选择是否创建目标对象,什么时候需要什么时候创建。

  2. 动态代理:使用动态代理,通过反射机制动态创建代理对象,减少手动创建代理对象的复杂性。

桥接模式 Bridge

1、什么是桥接模式

桥接模式的核心思想是将抽象部分和实现部分分离,使它们可以独立地发生变化。通过抽象类和实现类设计为两个独立的层次方案,并使用组合组合关系将他们连接起来。

2、为什么使用桥接模式

  1. 解耦抽象和实现:桥接模式将抽象和实现分离,使得他们可以独立地发生变化,降低系统的耦合度。

  2. 提高灵活性:桥接模式提高了系统的灵活性,可以更容易地添加新的抽象类和实现类。

  3. 复用性:可以在不修改已有代码的情况下引入新的抽象和实现。

3、如何使用桥接模式

设计实现一个图形绘制的场景,有不同类型的图形和不同的绘制方式,要求通过桥接模式将图形和绘制方式解耦。

// 实现部分 - 绘制方式interface DrawingAPI {    void drawCircle(int x, int y, int radius);}
// 具体实现部分 - 红色绘制方式class RedDrawingAPI implements DrawingAPI { @Override public void drawCircle(int x, int y, int radius) { System.out.println("Drawing Red Circle at (" + x + "," + y + ") with radius " + radius); }}
// 具体实现部分 - 绿色绘制方式class GreenDrawingAPI 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;
protected Shape(DrawingAPI drawingAPI) { this.drawingAPI = drawingAPI; }
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 void draw() { drawingAPI.drawCircle(x, y, radius); }}
// 客户端代码public class Client { public static void main(String[] args) { DrawingAPI redAPI = new RedDrawingAPI(); DrawingAPI greenAPI = new GreenDrawingAPI();
Shape redCircle = new Circle(100, 100, 10, redAPI); Shape greenCircle = new Circle(200, 200, 20, greenAPI);
redCircle.draw(); greenCircle.draw(); }}

4、是否存在缺陷和不足

  1. 增加复杂性:桥接模式可能会增加系统的复杂性,因为需要设计多个抽象类和实现的类层次结构。

5、如何缓解缺陷和不足

  1. 谨慎设计类的层次结构:设计抽象和实现的类层次结构时,需要谨慎考虑,避免过度设计。

  2. 使用合适的模式:根据系统的需求,考虑其他结构型模式,选择最适合的模式。

原文作者:灸哥漫谈;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-11-26

  • 博文量
    368
  • 访问量
    173281