设计模式之桥接模式实例

一,桥接模式定义

        桥接模式将抽象部分与它的具体实现部分分离,使它们都可以独立地变化,属于结构型模式。桥接模式的核心在于解耦抽象和实现,基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。桥接模式主要目的是通过组合的方式建立两个类之间的联系,而不是继承。

二,使用场景

        当一个类内部具备两种或多种变化维度时,桥接模式适用于以下几种业务场景:

  1. 在抽象和具体实现之间需要增加更多的灵活性的场景
  2. 一个类存在两个或多个独立变化的维度,而这两个或多个维度都需要独立进行扩展
  3. 不希望使用继承,或因为多层继承导致系统类的个数剧增

三,桥接模式的组成角色

抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。

修正抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。

实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。

具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。

四,实例场景

        一个咖啡店卖咖啡,卖出的咖啡可以从几个角度来看(即一个类内部具备两种或多种变化维度时):

1. 口味:摩卡、拿铁、美式等;

2. 容量:大杯、中杯、小杯等;

3. 添加物:牛奶、糖、蜂蜜等;

4. 温度:热、常温、冷等;

如果需要设计一个点餐系统,来生成咖啡订单,如何在系统中将上面说到的拥有4个属性的咖啡生成呢?

第一种方法:

为每种咖啡组合编写不同的类,共有:3*3*3*3=81种类

第二种方法:

针对第一种方法,我们能不能单独定义每种属性,并让每种属性能够复用,然后将他们组合/聚合起来形成一杯咖啡呢?这样就减少每个属性的重复定义了。 例如: 1. 口味:摩卡、拿铁、美式等分别定义一个类,共3个类。 2. 容量:大杯、中杯、小杯等分别定义一个类,共3个类 。3. 添加物:牛奶、糖、蜂蜜等分别定义一个类,共3个类 。4. 温度:热、常温、冷等分别定义一个类,共3个类。所以共有3+3+3+3=12个类,类的数量大减。

桥接模式就是为了实现上面的第二种方法的,先进行抽象,然后通过桥接将属性连接起来。

进一步优化如下图:

        咖啡的最重要的属性就是口味(也可以说是本质的属性),其它的属性相对来说不是最重要的,那么我们就让口味直接通过继承的方式实现属性的集成,其它三个属性为了提升替换性/重用性,可以也进行一个抽象类的定义,然后去具体实现。这样设计后,通过组合/聚合实现了咖啡多个属性的集成,减少了类的数量。结构模式图如下:

结合组成角色分析:

抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用,就是上面所说的Coffe抽象类。

修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义,就是上面的口味实现类。

实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。就是上面的容量、温度、添加物抽象类。

具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现,就是上面的容量、温度、添加物实现类。

五,代码实现与分析

抽象化(Abstraction)角色:

Coffe抽象类-AbstractCoffe类的定义

public abstract class AbstractCoffe {
    // 重点:此处就是连接其它属性的关键,通过成员变量的方式聚合了其它属性
    ICapacity capacity;
    IAdditives additives;
    ITemperature temperature;

    // 此处通过有参构造的方式接受客户端想要的咖啡属性
    public AbstractCoffe(ICapacity capacity,IAdditives additives,ITemperature temperature){
        this.capacity = capacity;
        this.additives = additives;
        this.temperature = temperature;
    }

    public abstract void Order(int count);
}

修正抽象化(RefinedAbstraction)角色:

口味实现类-MocaCoffe类定义,只实现了一种类型,就是摩卡,还可以实现其它的口味类型,代码类似,此处就省略了。

public class MocaCoffe extends AbstractCoffe{

        public MocaCoffe(ICapacity capacity,IAdditives additives,ITemperature temperature){
        super(capacity, additives, temperature);
    }

    public void Order(int count) {
        System.out.println("开始制作摩卡咖啡:");
        capacity.SetCupCapacity();
        additives.AddAdditives();
        temperature.SetTemperature();
        System.out.println(count+" 杯Moca Coffe制作完成!");
    }
}

实现化(Implementor)角色:

容量、温度、添加物抽象类-ICapacity、ITemperature、IAdditives抽象接口定义

//容量抽象接口ICapacity
public interface ICapacity {
    public void SetCupCapacity();
}
//温度抽象接口ITemperature
public interface ITemperature {
    public void SetTemperature();
}
//添加物抽象接口IAdditives
public interface IAdditives {
    public void AddAdditives();
}

具体实现化(ConcreteImplementor)角色:

容量、温度、添加物实现类-Capacity、Temperature、Additives抽象类定义

(1)Capacity实现类-3种

// 大杯
public class LargeCapacity implements ICapacity{
    @Override
    public void SetCupCapacity() {
        System.out.println("制作杯子尺寸:Large");
    }
}

//中杯
public class MiddleCapacity implements ICapacity{
    @Override
    public void SetCupCapacity() {
        System.out.println("制作杯子尺寸:Middle");
    }
}

//小杯
public class SmallCapacity implements ICapacity{
    @Override
    public void SetCupCapacity() {
        System.out.println("制作杯子尺寸:Small");
    }
}

(2)Temperature实现类-3种

// 热饮
public class HotTemperature implements ITemperature{
    @Override
    public void SetTemperature() {
        System.out.println("加热温度至:Hot");
    }
}

// 冷饮
public class NormalTemperature implements ITemperature{
    @Override
    public void SetTemperature() {
        System.out.println("加热温度至:Normal");
    }
}

// 常温
public class ColdTemperature implements ITemperature{
    @Override
    public void SetTemperature() {
        System.out.println("加热温度至:Cold");
    }
}

(3)Additives实现类-3种

// 加奶
public class MilkAdditives implements IAdditives{

    @Override
    public void AddAdditives() {
        System.out.println("添加 MILK 成功!");
    }
}

// 加糖
public class SugarAdditives implements IAdditives{
    @Override
    public void AddAdditives() {
        System.out.println("添加 SUGAR 成功!");
    }
}
// 加蜂蜜
public class HoneyAdditives implements IAdditives {
    @Override
    public void AddAdditives() {
        System.out.println("添加 HONEY 成功!");
    }
}

客户端测试类定义

public class Main {
    public static void main(String[] args) {
        // 客户端传入想要的咖啡各个属性的具体对象
        AbstractCoffe mocaCoffe = new MocaCoffe(new MiddleCapacity(),new SugarAdditives(),new ColdTemperature());
        mocaCoffe.Order(4);
    }
}

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
很高兴为您提供有关桥接模式的Java项目实例桥接模式是一种结构性设计模式,可用于将抽象与实现解耦。 以下是一个简单的桥接模式的Java项目实例: 1.先定义一个 Shape 接口和一个 Drawing 接口,如下所示: ```java public interface Shape { public void draw(); } public interface Drawing { public void drawCircle(int x, int y, int radius); public void drawRectangle(int x1, int y1, int x2, int y2); } ``` 2.然后实现具体的 Shape 类和 Drawing 类,如下所示: ```java public class CircleShape implements Shape { private int x, y, radius; private Drawing drawing; public CircleShape(int x, int y, int radius, Drawing drawing) { this.x = x; this.y = y; this.radius = radius; this.drawing = drawing; } public void draw() { drawing.drawCircle(x, y, radius); } } public class RectangleShape implements Shape { private int x1, y1, x2, y2; private Drawing drawing; public RectangleShape(int x1, int y1, int x2, int y2, Drawing drawing) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.drawing = drawing; } public void draw() { drawing.drawRectangle(x1, y1, x2, y2); } } public class DrawingImpl implements Drawing { public void drawCircle(int x, int y, int radius) { System.out.println("Drawing circle at (" + x + ", " + y + ") with radius " + radius); } public void drawRectangle(int x1, int y1, int x2, int y2) { System.out.println("Drawing rectangle from (" + x1 + ", " + y1 + ") to (" + x2 + ", " + y2 + ")"); } } ``` 3.最后,我们可以使用这些类来画出不同的形状,如下所示: ```java public static void main(String[] args) { Drawing drawing = new DrawingImpl(); Shape circle = new CircleShape(10, 10, 5, drawing); circle.draw(); Shape rectangle = new RectangleShape(20, 20, 30, 30, drawing); rectangle.draw(); } ``` 这是一个简单的桥接模式的Java项目实例。它演示了如何将抽象和实现分离,使得它们可以独立进行扩展。当我们需要添加新的形状或绘图方式时,只需要实现相应的类即可,而不用改变现有类的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值