趣解设计模式之《当代毕加索小王》

〇、小故事

小王最近对画油画非常的感兴趣 ,尤其是当他参观完毕加索画展之后,更觉得自己有画画天赋了,"这画我自己也能画啊!这以后一幅画随随便便买它2、3个亿,这不发财了!"于是,他就开始着手购买画油画的工具了。

假设画某种线条,有三种笔,分别为:粗毛笔中毛笔细毛笔 ;同时也有两种颜色,分别为:红墨水蓝墨水 ;所以,总共我们可以画出6种样式的线条。最容易想到的实现就是我们要创建这6种线条类型的对象实例。如下图所示:

但是,如果这样设计,以后如果再有其他颜色的墨水,那么类会越来越多,所以,我们想到把毛笔抽象一层,如下图所示:

那既然毛笔已经抽象出一层了,墨水当然也可以抽象出一层,那么最终的结构如下图所示:

这样,我们有了两个大类 ,分别为:毛笔类墨水类,以后无论添加什么样式的毛笔或者添加什么颜色的墨水,就可以创造出各式各样的线条了。

再比如:我们想做一个支持多品牌电视的遥控器 ,那么此时,我创建了一个遥控器的父类,叫RemoteController,然后我们接入了两个品牌(RCASony)的电视遥控器接入合约,我们针对这两个品牌,分别做了RCARemoteControllerSonyRemoteController。看似一切进展顺利,那么随着我们口碑的建立,越来越多的电视厂商,邀请我们做他们公司的遥控器。我们随后又接入了10家公司。那么我们现在就有12种遥控器了。

随着商品屏幕化的进程,大屏手机,带屏幕的电饭煲、电风扇、空调等等。我们的遥控器也要加入带屏幕的版本 。那么针对这个请求,我们就需要为已有的12种厂商遥控器都加入带屏幕的版本,那么总的RemoteController子类就突增为24种了...... 我们的子类实现噩梦还远远没有结束。

为了解决以上问题,我们就来引出今天的设计模式------桥接模式

一、模式定义

桥接模式Bridge Pattern

将抽象部分和实现部分,分离解耦,使得两者可以独立地变化。

桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立变化

桥接模式的优点

1 】将实现予以解耦,让它和应用之间不再永久绑定。

2 】抽象和实现可以独立扩展,不会影响到对方。

3】对于"具体的抽象类"所做的改变,不会影响到客户。

二、模式类图

根据以上毛笔的例子,我们来绘制一下模式的类图。在这里我们来抽象出变化和不变的部分。首先,不变的是需要毛笔颜料 这两大类。变化的是,需要针对不同毛笔粗细和颜料的颜色具有不同的具体的实现 。那么,通过将毛笔和燃料进行Has-A的聚合,来实现桥接。具体如下所示:

三、代码实现

抽象画笔类BrushPenAbstraction.java

java 复制代码
@Data
public abstract class BrushPenAbstraction {
    // 颜色接口
    protected ColorImplementor color;

    // 绘画操作
    public abstract void draw();
}

粗毛笔实现类BigBurshPen.java

java 复制代码
public class BigBurshPen extends BrushPenAbstraction {
    @Override
    public void draw() {
        System.out.println("Big and " + color.getColor() + " drawing!");
    }
}

中毛笔实现类MiddleBurshPen.java

java 复制代码
public class MiddleBurshPen extends BrushPenAbstraction {
    @Override
    public void draw() {
        System.out.println("Middle and " + color.getColor() + " drawing!");
    }
}

细毛笔实现类SmallBurshPen.java

java 复制代码
public class SmallBurshPen extends BrushPenAbstraction {
    @Override
    public void draw() {
        System.out.println("Small and " + color.getColor() + " drawing!");
    }
}

颜色大类ColorImplementor.java

java 复制代码
public interface ColorImplementor {
    String getColor();
}

红色墨水类RedColor.java

java 复制代码
public class RedColor implements ColorImplementor {
    @Override
    public String getColor() {
        return "Red";
    }
}

蓝色墨水BlueColor.java

java 复制代码
public class BlueColor implements ColorImplementor {
    @Override
    public String getColor() {
        return "Blue";
    }
}

桥梁模式测试类BridgeTest.java

java 复制代码
public class BridgeTest {
    public static void main(String[] args) {
        BrushPenAbstraction brushPen = new BigBurshPen();
        brushPen.setColor(new RedColor());
        brushPen.draw();

        brushPen.setColor(new BlueColor());
        brushPen.draw();

        brushPen = new SmallBurshPen();
        brushPen.setColor(new BlueColor());
        brushPen.draw();
    }
}

运行结果

java 复制代码
Big and Red drawing!
Big and Blue drawing!
Small and Blue drawing!

Process finished with exit code 0

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号"爪哇缪斯" ~ \(^o^)/ ~ 「干货分享,每天更新」

相关推荐
will_we1 小时前
Tauri 2 安卓开发初体验
后端
jhfuture1 小时前
从源码分析,为什么要使用TTL(TransmittableThreadLocal)而不是inheritableThreadLocals
后端·面试
cwkiller3 小时前
伏魔挑战赛-ASP/ASP.NET赛道10+绕过样本思路分享
后端
Code季风3 小时前
深入理解 Gin 框架的路由机制:从基础使用到核心原理
ide·后端·macos·go·web·xcode·gin
Vallelonga4 小时前
关于 Rust 异步(无栈协程)的相关疑问
开发语言·后端·rust
Barcke4 小时前
缓存界的 "双保险":打工人救星来了!(本地缓存 + Redis 双剑合璧,轻松应对高并发)
java·后端
子洋5 小时前
现代化 ls 命令替代工具:EZA
前端·后端·shell
Victor3567 小时前
MySQL(190)如何优化MySQL的网络传输?
后端
Victor3567 小时前
MySQL(189)如何分析MySQL的锁等待问题?
后端
Warren987 小时前
使用 Spring Boot 集成七牛云实现图片/文件上传
java·前端·javascript·vue.js·spring boot·后端·ecmascript