当前位置: 首页 > article >正文

【设计模式】结构型模式(三):桥接模式、外观模式

结构型模式(三):桥接模式

  • 4.桥接模式(Bridge)
    • 4.1 结构
    • 4.2 示例
      • 4.2.1 抽象类
      • 4.2.2 细化抽象类
      • 4.2.3 实现类接口
      • 4.2.4 具体实现类
      • 4.2.5 客户端
  • 5.外观模式(Facade)

在这里插入图片描述

4.桥接模式(Bridge)

桥接模式Bridge Pattern)是设计模式中的一种结构型模式,主要用于 将抽象部分与实现部分分离,使它们可以独立变化。这种模式在多种场景下非常有用,尤其是在需要将抽象和实现解耦的情况下。以下是桥接模式的主要特点和应用场景:

  • 分离抽象和实现:将抽象部分和实现部分分离,使它们可以独立变化。
  • 减少类的爆炸性增长:通过将抽象和实现解耦,可以减少类的数量,提高系统的可维护性。
  • 动态切换实现:可以在运行时动态切换实现部分,而不需要修改客户端代码。

4.1 结构

  • Abstraction抽象类):定义抽象类的接口,包含一个对实现部分的引用
  • RefinedAbstraction细化抽象类):扩展抽象类,提供更具体的实现。
  • Implementor实现类接口):定义实现类的接口,具体实现类需要实现这个接口。
  • ConcreteImplementor具体实现类):实现实现类接口,提供具体的实现。

4.2 示例

假设我们有一个图形绘制系统,需要支持不同的图形(圆形、方形等)和不同的绘制方式(如使用不同的颜色或填充方式)。我们可以使用桥接模式来实现这个系统。

4.2.1 抽象类

// 抽象类
public abstract class Shape {
    protected DrawAPI drawAPI;

    protected Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }

    public abstract void draw();
}

4.2.2 细化抽象类



// 细化抽象类
public class Circle extends Shape {
    private int x, y, radius;

    public Circle(int x, int y, int radius, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    @Override
    public void draw() {
        drawAPI.drawCircle(x, y, radius);
    }
}

public class Rectangle extends Shape {
    private int x, y, width, height;

    public Rectangle(int x, int y, int width, int height, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    @Override
    public void draw() {
        drawAPI.drawRectangle(x, y, width, height);
    }
}

4.2.3 实现类接口

// 实现类接口
public interface DrawAPI {
    void drawCircle(int x, int y, int radius);
    void drawRectangle(int x, int y, int width, int height);
}

4.2.4 具体实现类

// 具体实现类
public class RedDrawAPI implements DrawAPI {
    @Override
    public void drawCircle(int x, int y, int radius) {
        System.out.println("Drawing Circle [Color: Red, x: " + x + ", y: " + y + ", radius: " + radius);
    }

    @Override
    public void drawRectangle(int x, int y, int width, int height) {
        System.out.println("Drawing Rectangle [Color: Red, x: " + x + ", y: " + y + ", width: " + width + ", height: " + height);
    }
}

public class BlueDrawAPI implements DrawAPI {
    @Override
    public void drawCircle(int x, int y, int radius) {
        System.out.println("Drawing Circle [Color: Blue, x: " + x + ", y: " + y + ", radius: " + radius);
    }

    @Override
    public void drawRectangle(int x, int y, int width, int height) {
        System.out.println("Drawing Rectangle [Color: Blue, x: " + x + ", y: " + y + ", width: " + width + ", height: " + height);
    }
}

4.2.5 客户端

public class BridgePatternDemo {
    public static void main(String[] args) {
        Shape redCircle = new Circle(100, 100, 50, new RedDrawAPI());
        Shape blueRectangle = new Rectangle(10, 10, 100, 100, new BlueDrawAPI());

        redCircle.draw();
        blueRectangle.draw();
    }
}

输出结果:

Drawing BridgePatternDemo.Circle [Color: Red, x: 100, y: 100, radius: 50
Drawing BridgePatternDemo.Rectangle [Color: Blue, x: 10, y: 10, width: 100, height: 100

5.外观模式(Facade)

外观模式Facade Pattern)是一种设计模式,用于 为复杂的子系统提供一个简化的接口。它的主要目的是减少客户端与子系统之间的依赖关系,使客户端代码更容易理解和使用。以下是外观模式的几个关键点:

  • 简化接口:外观模式通过提供一个统一的高层接口,使客户端代码可以更简单地访问子系统的功能,而不需要了解子系统的内部复杂性。
  • 降低耦合度:客户端代码只需与外观类交互,而不必与子系统的多个类直接交互,从而降低了系统的耦合度。
  • 提高灵活性:外观类可以灵活地控制对子系统的访问,可以在不改变客户端代码的情况下,修改子系统的实现。

假设你有一个 家庭影院系统,包括 DVD 播放器、投影仪、屏幕、音响等设备。每个设备都有自己的控制接口,如果直接操作这些设备,客户端代码会非常复杂。通过外观模式,可以创建一个家庭影院外观类,提供一个简单的接口来控制整个系统。

public class HomeTheaterFacade {
    private DvdPlayer dvdPlayer;
    private Projector projector;
    private Screen screen;
    private Amplifier amplifier;

    public HomeTheaterFacade(DvdPlayer dvdPlayer, Projector projector, Screen screen, Amplifier amplifier) {
        this.dvdPlayer = dvdPlayer;
        this.projector = projector;
        this.screen = screen;
        this.amplifier = amplifier;
    }

    public void watchMovie(String movie) {
        System.out.println("Get ready to watch a movie...");
        screen.down();
        projector.on();
        dvdPlayer.play(movie);
        amplifier.on();
    }

    public void endMovie() {
        System.out.println("Shutting movie theater down...");
        screen.up();
        projector.off();
        dvdPlayer.stop();
        amplifier.off();
    }
}

通过这个外观类,客户端代码可以非常简单地控制整个家庭影院系统:

public class Client {
    public static void main(String[] args) {
        DvdPlayer dvdPlayer = new DvdPlayer();
        Projector projector = new Projector();
        Screen screen = new Screen();
        Amplifier amplifier = new Amplifier();

        HomeTheaterFacade facade = new HomeTheaterFacade(dvdPlayer, projector, screen, amplifier);

        facade.watchMovie("The Matrix");
        facade.endMovie();
    }
}

这样,客户端代码只需要调用外观类的 watchMovieendMovie 方法,而不需要关心每个设备的具体操作。


http://www.kler.cn/a/383548.html

相关文章:

  • Redis集群——针对实习面试
  • Neo4j入门:详解Cypher查询语言中的MATCH语句
  • Redis的内存淘汰机制
  • CPU Study - Instructions Fetch
  • java.lang.NoClassDefFoundError: kotlin/jvm/JvmInline
  • Java初学者指南
  • 如何建购物网站提升用户体验
  • 泷羽sec学习打卡-shodan扫描6
  • 完成程序《大奖赛评分B》
  • Python入门资料!笨办法学Python!编程小白的第一本Python入门书!
  • 解决微信小程序电脑能正常使用,手机端无法正常访问的问题
  • 100种算法【Python版】第56篇——Delaunay三角剖分之增量法
  • HTTP返回码和其含义
  • Flutter鸿蒙next 中使用 MobX 进行状态管理
  • Pinia-状态管理
  • Docker学习—Docker的安装与使用
  • 串联电抗器电感量误差较大的原因
  • chrome浏览器network控制台使用和功能介绍
  • C#/.NET/.NET Core优秀项目和框架2024年10月简报
  • 【简信CRM-注册安全分析报告】
  • 从0开始搭建一个生产级SpringBoot2.0.X项目(十一)SpringBoot 定时任务@Scheduled
  • T507 buildroot linux4.9之RLT8211F 1000M以太网开发调试
  • 【Android】Gradle 7.0+ 渠道打包配置
  • 插值字符串以$开头,并在大括号{}中可以直接插入变量和表达式
  • dockerfile/docker-compose构建镜像上下文目录编写要点
  • 华为HCIP —— QinQ技术实验配置