设计模式(四)--桥接模式

桥接模式

假设场景:农民有一个果园,里面可以种植各种水果,比如可以种植苹果、葡萄,又有两种土地可以种植:红土地,黑土地。

使用类的继承来实现:
package bridge;


class  Fruit{
    public void plant(){
        System.out.println("种植了水果");
    }
}

class Apple extends Fruit{
    @Override
    public void plant(){
        System.out.println("种植了苹果");
    }
}

class Grape extends Fruit{
    @Override
    public void plant(){
        System.out.println("种植了葡萄");
    }
}

class RedApple extends Apple{
    @Override
    public void plant(){
        System.out.println("在红土地种植了苹果");
    }
}

class BlackApple extends Apple{
    @Override
    public void plant(){
        System.out.println("在黑土地种植了青苹果");
    }
}

class RedGrape extends Grape{
    @Override
    public void plant(){
        System.out.println("在红土地种植了紫葡萄");
    }
}

class BlackGrape extends Grape{
    @Override
    public void plant(){
        System.out.println("在黑土地种植了青葡萄");
    }
}


public class Main {
     public static void main(String[] args) {
        BlackApple greenApple=new BlackApple();
        greenApple.plant();
    }
}

在这里插入图片描述

分析: 这样的设计是脆弱的,仔细分析就可以发现,它还是存在很多问题,首先它在遵循开放-封闭原则的同时,违背了类的单一职责原则,即一个类只有一个引起它变化的原因,而这里引起变化的原因却有两个,即水果类型的变化和水果颜色类型的变化;

再次是类的结构过于复杂,继承关系太多,难于维护,最后最致命的一点是扩展性太差。如果变化沿着水果的类型和不同的水果颜色两个方向变化,我们会看到这个类的结构会迅速的变庞大。

应用桥接模式来改善

package bridge.fruit;



abstract class Fruit {
    PlantApi plantApi;

    Fruit(PlantApi plantApi) {
        this.plantApi = plantApi;
    }

    public abstract void plant();
}

class Apple extends Fruit {
    public Apple(PlantApi plantApi) {
        super(plantApi);
    }

    @Override
    public void plant() {
        System.out.print("苹果");
        plantApi.plantApple();
    }
}

class Grape extends Fruit {
    public Grape(PlantApi plantApi) {
        super(plantApi);
    }

    @Override
    public void plant() {
        System.out.print("葡萄");
        plantApi.plantApple();
    }
}

interface PlantApi {

    public void plantApple();
}
 class RedDirt  implements PlantApi {
    @Override
    public void plantApple() {
        System.out.println("种在红土地上");
    }
}

class BlackDirt implements PlantApi {
    @Override
    public void plantApple() {
        System.out.println("种在黑土地上");
    }
}

public class Main {
    public static void main(String[] args) {
        Fruit fruit=new Apple(new RedDirt());
        fruit.plant();
    }
}

在这里插入图片描述
分析: 可以看到,通过对象组合的方式,Bridge 模式把两个角色之间的继承关系改为了耦合的关系,从而使这两者可以从容自若的各自独立的变化,这也是Bridge模式的本意。 这样增加了客户程序与水果与种植土地的耦合。其实这样的担心是没有必要的,因为这种耦合性是由于对象的创建所带来的,完全可以用创建型模式去解决。在应用时结合创建型设计模式来处理具体的问题。

结合上面的例子,增加一个维度"人",不同的人在不同的土地上种植不同的水果(三个维度)

package bridge.fruit;



abstract class Fruit {
    PlantApi plantApi;

    Fruit(PlantApi plantApi) {
        this.plantApi = plantApi;
    }

    public abstract void plant();
}

class Apple extends Fruit {
    public Apple(PlantApi plantApi) {
        super(plantApi);
    }

    @Override
    public void plant() {
        System.out.print("苹果");
        plantApi.plantApple();
    }
}

class Grape extends Fruit {
    public Grape(PlantApi plantApi) {
        super(plantApi);
    }

    @Override
    public void plant() {
        System.out.print("葡萄");
        plantApi.plantApple();
    }
}

interface PlantApi {
    public void plantApple();
}
 class RedDirt  implements PlantApi {
    @Override
    public void plantApple() {
        System.out.println("种在红土地上");
    }
}

class BlackDirt implements PlantApi {
    @Override
    public void plantApple() {
        System.out.println("种在黑土地上");
    }
}


abstract class Person{
    Fruit fruit;

    Person(Fruit fruit) {
        this.fruit = fruit;
    }

    public abstract void plant();
}

class Farmers extends Person{

    public Farmers(Fruit fruit) {
        super(fruit);
    }

    @Override
    public void plant() {
        System.out.print("农民把");
        fruit.plant();
    }
}

class Businessman extends Person{

    public Businessman(Fruit fruit) {
        super(fruit);
    }

    @Override
    public void plant() {
        System.out.print("商人把");
        fruit.plant();
    }
}
public class Main {
    public static void main(String[] args) {
        Fruit fruit=new Apple(new RedDirt());
        Person person=new Farmers(fruit);
        person.plant();
    }
}

在这里插入图片描述

效果及实现要点:

1.Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。
2.所谓抽象和实现沿着各自维度的变化,即“子类化”它们,得到各个子类之后,便可以任意它们,从而获得种植在不同土地的不同水果。
3.Bridge模式有时候类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
4.Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。

适用性:
在以下的情况下应当使用桥梁模式:
1.如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
2.设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
3.一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。
4.虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值