桥接模式(Bridge)
1.问题引入:
关于手机品牌与手机软件的两种结构:
问题:再添加新的手机品牌或者新的软件类型都会非常麻烦。
这时候需要用到合成/聚合原则:优先使用合成/聚合,而不是类的继承。
问题的解决:
手机品牌和手机软件之间的关系是手机品牌包含手机软件,但软件并不是品牌的一部分,所以他们之间是聚合关系,而不是合成关系。
package computer;
public class Test {
public static void main(String[] args) {
HandsetBrand ab;
//M品牌的手机
ab=new HandsetBrandM();
//设置并运行手机软件
ab.setHandsetSoft(new HandsetGame());ab.run();
ab.setHandsetSoft(new AddressList());ab.run();
ab.setHandsetSoft(new MP3());ab.run();
//N品牌的手机
ab=new HandsetBrandN();
//设置并运行手机软件
ab.setHandsetSoft(new HandsetGame());ab.run();
ab.setHandsetSoft(new AddressList());ab.run();
ab.setHandsetSoft(new MP3());ab.run();
}
}
//手机软件类(抽象类)
abstract class HandsetSoft{
public abstract void run();
}
//手机品牌类(抽象类)
abstract class HandsetBrand{
protected HandsetSoft soft;
//设置手机软件
public void setHandsetSoft(HandsetSoft soft) {
this.soft=soft;
}
//运行软件(抽象)
public abstract void run();
}
//手机品牌M(具体手机品牌类)
class HandsetBrandM extends HandsetBrand{
//运行手机
public void run() {
System.out.println("手机M:");
//运行该类型手机中的软件
soft.run();
}
}
//手机品牌N(具体手机品牌类)
class HandsetBrandN extends HandsetBrand{
//运行手机
public void run() {
System.out.println("手机N:");
//运行该类型手机中的软件
soft.run();
}
}
//手机游戏类(具体软件类)
class HandsetGame extends HandsetSoft{
//运行软件
public void run() {
System.out.println("运行手机游戏");
}
}
//手机通讯录类(具体软件类)
class AddressList extends HandsetSoft{
public void run() {
System.out.println("运行手机通讯录");
}
}
//手机MP3类(具体手机软件类)
class MP3 extends HandsetSoft{
public void run() {
System.out.println("运行手机MP3");
}
}
此时要增加一种软件或者增加一种手机品牌,只需要增加一个类,不会影响其他任何类。
2.向其中添加一个手机拍照类和手机品牌S类
package computer;
public class Test {
public static void main(String[] args) {
HandsetBrand ab;
//M品牌的手机
ab=new HandsetBrandM();
//设置并运行手机软件
ab.setHandsetSoft(new HandsetGame());ab.run();
ab.setHandsetSoft(new AddressList());ab.run();
ab.setHandsetSoft(new MP3());ab.run();
//N品牌的手机
ab=new HandsetBrandN();
//设置并运行手机软件
ab.setHandsetSoft(new HandsetGame());ab.run();
ab.setHandsetSoft(new AddressList());ab.run();
ab.setHandsetSoft(new MP3());ab.run();
//新增的S品牌的手机
ab=new HandsetBrandS();
//设置并运行手机软件
ab.setHandsetSoft(new HandsetGame());ab.run();
ab.setHandsetSoft(new AddressList());ab.run();
ab.setHandsetSoft(new MP3());ab.run();
//新增的手机拍照类
ab.setHandsetSoft(new Photo());ab.run();
}
}
//手机软件类(抽象类)
abstract class HandsetSoft{
public abstract void run();
}
//手机品牌类(抽象类)
abstract class HandsetBrand{
protected HandsetSoft soft;
//设置手机软件
public void setHandsetSoft(HandsetSoft soft) {
this.soft=soft;
}
//运行软件(抽象)
public abstract void run();
}
//手机品牌M(具体手机品牌类)
class HandsetBrandM extends HandsetBrand{
//运行手机
public void run() {
System.out.println("手机M:");
//运行该类型手机中的软件
soft.run();
}
}
//手机品牌N(具体手机品牌类)
class HandsetBrandN extends HandsetBrand{
//运行手机
public void run() {
System.out.println("手机N:");
//运行该类型手机中的软件
soft.run();
}
}
//新增手机品牌S(具体手机品牌)
class HandsetBrandS extends HandsetBrand{
//运行手机
public void run() {
System.out.println("手机 S:");
soft.run();
}
}
//手机游戏类(具体软件类)
class HandsetGame extends HandsetSoft{
//运行软件
public void run() {
System.out.println("运行手机游戏");
}
}
//手机通讯录类(具体软件类)
class AddressList extends HandsetSoft{
public void run() {
System.out.println("运行手机通讯录");
}
}
//手机MP3类(具体手机软件类)
class MP3 extends HandsetSoft{
public void run() {
System.out.println("运行手机MP3");
}
}
//新增手机拍照软件(具体手机软件类)
class Photo extends HandsetSoft{
public void run() {
System.out.println("运行手机拍照");
}
}
这样的设计符合开放封闭原则和合成聚合原则。
3.桥接模式
package computer;
public class Test {
public static void main(String[] args) {
Abstraction ab=new RefinedAbstraction();
ab.setImplementor(new ConcreteImplementorA());
ab.operation();
ab.setImplementor(new ConcreteImplementorB());
ab.operation();
}
}
//实现
abstract class Implementor{
public abstract void operation();
}
//具体实现A
class ConcreteImplementorA extends Implementor{
public void operation() {
System.out.println("具体实现A 的方法执行!");
}
}
//具体实现B
class ConcreteImplementorB extends Implementor{
public void operation() {
System.out.println("具体实现B 的方法执行!");
}
}
//抽象
abstract class Abstraction{
protected Implementor implementor;
//设置实现的对象
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public void operation() {
implementor.operation();
}
}
//具体抽象
class RefinedAbstraction extends Abstraction{
//这里是重写Abstraction类的operation()方法,可以将父类的operation()方法设为虚函数
public void operation() {
implementor.operation();
}
}
桥接模式就是将抽象部分与它的实现分离。其实就是实现系统可能有多角度分类,每一种分类都可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。