桥接模式

165 阅读3分钟

背景

我们可以在辛巴克的点餐面板上看到这样的选项。

咖啡的价格有2个维度,一个是杯子大小,一个是是否加糖。

思考

我们怎么求出它的价格呢?

价格模型如下:

实现方式一:if-else大法

我们可以用下面的代码模拟出我们求的咖啡价格。

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        int cupType = 1;//杯子类型 1 大杯 2 小杯
        int sugarType = 1;//糖类型 1 有糖 2 无糖
        if (cupType == 1 && sugarType == 1){
            //大杯 + 加糖
            getAmount(1);
        } else if (cupType == 1 && sugarType == 2){
            //大杯 + 不加糖
            getAmount(2);
        } else if (cupType == 2 && sugarType == 1){
            //小杯 + 加糖
            getAmount(3);
        } else if (cupType == 3 && sugarType == 2){
            //小杯 + 不加糖
            getAmount(4);
        }
    }

    public int getAmount(int type){
        int result = 0;
        if (type == 1){
            //大杯 + 加糖
            result = 4;
        } else if (type == 2){
            //大杯 + 不加糖
            result = 3;
        } else if (type == 3){
            //小杯 + 加糖
            result = 3;
        } else if (type == 4){
            //小杯 + 不加糖
            result = 2;
        }
        return result;
    }
}

这种方式可以吗?当然可以了。

思考1

如果我现在想增加一个中杯,口味增加一个草莓味,该怎么办呢?

我们得去修改这个if - else 的条件判断。

思考2

如果未来增加5中口味,杯形增加2种,该怎么呢?

if - else 的判断是非常多的,而且不容易扩展。

思考3

有没有一种简单的办法,可以实现这样的效果呢?

采用桥接模式,让他们进行组合。

实现方式2:桥接模式

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        SugarTaste sugarTaste = new SugarTaste();
        OriginTaste originTaste = new OriginTaste();

        int cupType = 1;//杯子类型 1 大杯 2 小杯
        int tasteType = 1;//糖类型 1 有糖 2 无糖

        // 可以将这个地方抽取成一个工厂,以后维护这两个工厂就行
        Taste taste = null;
        if (tasteType == 1) {
            taste = new SugarTaste();
        } else if (tasteType == 2) {
            taste = new OriginTaste();
        }

        // 可以将这个地方抽取成一个工厂,以后维护这两个工厂就行
        Cup cup = null;
        if (cupType == 1) {
            cup = new LargeCup(taste);
        } else if (cupType == 2) {
            cup = new SmallCup(taste);
        }

        // 通过将杯形和是否加糖抽取出来
		// 并且将他们进行组合。
// 以后当修改杯形和是否加糖,核心逻辑不会发生改变
        cup.getAmount();
    }

    /**
     * 杯形
     */
    public abstract class Cup {
        Taste mTaste;

        public Cup(Taste taste) {
            mTaste = taste;
        }

        abstract int getAmount();
    }

    public class LargeCup extends Cup {

        public LargeCup(Taste taste) {
            super(taste);
        }

        @Override
        int getAmount() {
            return 2 + mTaste.getTasteAmount();
        }
    }

    public class SmallCup extends Cup {

        public SmallCup(Taste taste) {
            super(taste);
        }

        @Override
        int getAmount() {
            return 1 + mTaste.getTasteAmount();
        }
    }

    /**
     * 口味
     */
    public abstract class Taste {
        abstract int getTasteAmount();
    }

    public class SugarTaste extends Taste {

        @Override
        int getTasteAmount() {
            return 2;
        }
    }

    public class OriginTaste extends Taste {

        @Override
        int getTasteAmount() {
            return 1;
        }
    }

}

优点:

1、扩展性强:以后要扩展杯形和口味,只需要修改杯形和口味的工厂类就好。

2、以后维护容易一点:核心逻辑不会变化,以后扩展的时候更加的方便。

桥接模式的理论升华

1、桥接模式即将抽象部分与它的实现部分分离开来,使他们都可以独立变化。

2、然后将抽象进行组合

优点

1、当有两个维度时,如果一个维度变化,不需要修改系统的设计。