1. 问题引出
实现某件产品,某产品有多种品牌(brand)和类型(kind)。
比较直观的一种实现方式,多重继承如下图所示,多重继承的两大缺点:
- 会导致有过多的类(类的数量=品牌数量*类型数量);
- 新增品牌则需要新增所有的类型类,新增类型则需要新增所有的品牌类,违反了单一职责原则(单一职责原则:对类来说的,即一个类应该只负责一项职责。如类 A 负责两个不同职责:职责 1,职责 2。当职责 1 需求变更 而改变 A 时,可能造成职责 2 执行错误,所以需要将类 A 的粒度分解为 A1,A2)。
2. 桥接模式解决问题
桥接模式中有4个角色:抽象化(Abstraction),改善后的抽象化(RefinedAbstraction),实现者(Implementor),具体实现者(ConcreteImplementor)。
- 抽象化:类的功能层次结构最上层。
- 改善后的抽象化:在抽象化角色基础上增加了新功能的角色。
- 实现者:定义了用于实现抽象化角色的接口的方法。
- 具体实现者:负责实现实现者角色中定义的方法。
Product 的角色是抽象化,抽象化的实现 Brand1、Brand2、Brand3,实现者 Kind,具体的实现者 Kind1、Kind2、Kind3。
显然使用桥接模式解决了上述的两个缺点。
3. 代码示例
Product.java, 抽象化角色 :
/**
* 抽象化角色:类的功能层次结构最上层
* @author syrdbt
* @date 2020-02-25
*/
public abstract class Product {
private Kind kind;
public Product(Kind kind) {
this.kind = kind;
}
public void make() {
kind.make();
}
}
Brand1.java:
/**
* 改善后的抽象化角色
* @author syrdbt
* @date 2020-02-25
*/
public class Brand1 extends Product {
public Brand1(Kind kind) {
super(kind);
}
@Override
public void make() {
System.out.println("这个产品属于 Brand1");
super.make();
}
}
Brand2.java:
/**
* 改善后的抽象化角色
* @author syrdbt
* @date 2020-02-25
*/
public class Brand2 extends Product {
public Brand2(Kind kind) {
super(kind);
}
@Override
public void make() {
System.out.println("这个产品属于 Brand2");
super.make();
}
}
Brand3.java:
/**
* 改善后的抽象化角色
* @author syrdbt
* @date 2020-02-25
*/
public class Brand3 extends Product {
public Brand3(Kind kind) {
super(kind);
}
@Override
public void make() {
System.out.println("这个产品属于 Brand3");
super.make();
}
}
Kind.java
/**
* 实现者角色
* @author syrdbt
* @date 2020-02-25
*/
public interface Kind {
void make();
}
Kind1.java
/**
* 具体的实现者
* @author syrdbt
* @date 2020-02-25
*/
public class Kind1 implements Kind {
@Override
public void make() {
System.out.println("制作 Kind1 类型的产品");
}
}
Kind2.java:
/**
* 具体的实现者
* @author syrdbt
* @date 2020-02-25
*/
public class Kind2 implements Kind{
@Override
public void make() {
System.out.println("制作 Kind1 类型的产品");
}
}
Kind3.java:
/**
* 具体的实现者
* @author syrdbt
* @date 2020-02-25
*/
public class Kind3 implements Kind {
@Override
public void make() {
System.out.println("制作 Kind3 类型的产品");
}
}
测试类,BridgeMain.java:
/**
* 测试类
* @author syrdbt
* @date 2020-02-25
*/
public class BridgeMain {
public static void main(String[] args) {
Product product = new Brand1(new Kind1());
product.make();
}
}
运行截图:
参考文献
- 图解设计模式 结城浩
- 图解设计模式 尚硅谷