Java常用设计模式————桥接模式

引言

在实际的业务中,经常会遇到多维度的概念组合,公园的门票,颐和园有年票、月票、日票,故宫也有年票、月票、日票。那么不同的公园票种类型就可以视为两种不同的纬度,它们之间会形成相互组合的关系。

在类的设计上,如果任由两种纬度的类任意组合的话,那么就会形成笛卡尔积的情况,使类泛滥,难以维护。

在设计模式中,桥接模式就是为了解决这个问题而提出的,它通过将两种或多种纬度以上层抽象的组合关系为基础,形成一种桥接模型,将业务的组合时机延迟到客户端调用使才发生,避免在编写类的时候,大量的枚举每一种具体情况。

一、待解决问题描述

类似上面公园和票种的纬度关系,这里提出一种简单的案例:形状和颜色。

假设我们需要两种不同的形状——圆形、正方形,和两种不同的颜色——红色、白色,并将它们组合以产生特定的类型,那么我们就需要四种不同:

这种做法虽然简单直观,但也大大增加了类的数量,而且两个维度的概念耦合性太强,如果增加了新的纬度,那么类的规模将成倍增长。

二、桥接模式类图

在学习桥接模式的时候,不仅应该掌握最主要的纬度的划分与如何实现桥接,还应该思考桥接模式之外的内容,比如上面的例子中,我们可以很清晰的划分出形状颜色两个维度,同时下面的类图也展示了通过怎样的编码技巧实现桥接的解耦。还有一点之外的内容就是,我们应该以哪种维度作为主干?为什么接入主干维度的其他维度要采用接口?而主干维度采用抽象类?

上图中,Shape是一个抽象类,这是对主干维度——形状的一个抽象,其实现类有Circle、Square,它们代表了一种具体的形状。

Color是一个接口,Red、White代表两种不同的具体的颜色。

在这个例子中,Color 和 Shape 相比,很显然Shape更像是一种主体纬度,而颜色,更适合作为一种附属属性依附于主体纬度,在这个例子中 Color 仅仅提供了一种行为,所以直接使用接口来描述,这当然不是必须的。

Color 与 Shape 的关系是聚合,采用的是 set 方法注入到 Shape 中,这需要根据具体的业务来判断两种纬度的依赖关系,聚合的耦合度更低,且更灵活,可以只在必要的时候将两种纬度聚合在一起。而组合可能在构造时就需要传入属性,这需要视具体情况而定。

三、桥接模式的具体实现

/**
 * 主干维度————形状
 */
public abstract class Shape {

	protected Color color;
	
	public void setColor(Color color) {
		this.color = color;
	}
	
	public abstract void draw();
}
/**
 * 颜色维度
 */
public interface Color {
	void paint(String shape);
}
public class Circle extends Shape {
	@Override
	public void draw() {
		color.paint("圆形");
	}
}
public class Square extends Shape {
	@Override
	public void draw() {
		color.paint("正方形");
	}
}
public class Red implements Color {
	@Override
	public void paint(String shape) {
		System.out.println("红色的" + shape);
	}
}
public class White implements Color {
	@Override
	public void paint(String shape) {
		System.out.println("白色的" + shape);
	}
}

 以上是桥接模式中的几个重要角色,以下是测试代码:

public class Client {
	public static void main(String[] args) {
		Shape square = new Square();
		square.setColor(new Red());
		square.draw();
		square.setColor(new White());
		square.draw();
		System.out.println("==============");
		Shape circle = new Circle();
		circle.setColor(new Red());
		circle.draw();
		circle.setColor(new White());
		circle.draw();
	}
}

输出结果:

红色的正方形
白色的正方形
==============
红色的圆形
白色的圆形

总结

桥接模式基于类的最小设计原则,其中包括几个重要的角色:

1、Client,客户端

2、Abstraction,抽象类

3、Refined Abstraction ,扩展抽象类

4、Implementor,行为实现类接口

5、ConcreteImplementor, 具体的行为实现

桥接模式标准类图如下: 

桥接模式有以下几点好处:

1、实现了抽象与行为的分离

2、更好的扩展性

3、可动态切换实现

4、实现细节对客户端透明,可以对用户隐藏实现细节

缺点也有几点:

1、增加了系统的理解难度和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。

2、桥接模式要求正确识别出系统中的两个独立变化的纬度,因此使用范围具有一定的局限性。

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页