---
# System prepended metadata

title: 橋梁模式 Bridge
tags: [Structural Patterns]

---

---
tags: Structural Patterns
---

# 橋梁模式 Bridge

**橋接模式是策略模式/Strategy Pattern的延伸**

Abstraction: 將原本的主體抽換到只剩下虛擬的概念，例如(人類:只是吃喝拉撒睡的主體、遙控器:只是開機關機調整的主體)
RefineAbstraction: 根據不同的需求實作主體
Implementator: 將原本主體的實際功能抽離，成為這個的Hierarchy(繼承結構)，例如(人類:人類的吃和拉撒睡拉出在此結構實作)
ConcreteImplementator: 根據不同的需求開發真實的行為

Class Diagram：
![](https://i.imgur.com/AMZsM8X.png)

總結：
1. 撰寫ConcreteImplementator的class
2. RefineAbstraction會繼承Abstraction，RefineAbstraction複寫Abstraction的行為。
3. 宣告一個主體(RefineAbstraction)時，把主體的行為(ConcreteImplementator)加進去。
**有新的行為時，只需要撰寫ConcreteImplementator的class就好了。**

**英雄介面 程式介紹**

> 在知道Bridge Pattern前我應該會這麼設計這功能，創建英雄介面，並且讓戰士和魔法師繼承與實作。在實作的function中根據今天要水火源素去做if/else判斷
如果今天英雄新增到了一百個，突然在遊戲更新後發現其中一個元素有BUG的化，那不就完蛋了嗎(需要更改100個英雄的方法邏輯)。
如果今天元素也新增到了一百個，那行為的方法裡面的邏輯想到就讓人覺得害怕。
如果使用Bridge Patter將英雄轉為抽象概念(英雄只是一連串動作的主體)，而在創建英雄時將行為主體注入。就算未來其中一個行為有Bug那只要更動一個Class，擴增英雄和行為都可以非常方便(增加繼承)


```javascript
//HeroAction是一個Implementator
interface HeroAction {
    void kick();
    void slash();
    void beat();
}
//FireHeroAction為火魔法、IceHeroAction為冰魔法，都實作了ConcreteImplementator
class FireHeroAction implements HeroAction {
    @Override
    public void kick() {
        System.out.println("Fire kick");
    }
    @Override
    public void slash() {
        System.out.println("Fire slash");
    }
    @Override
    public void beat() {
        System.out.println("Fire beat");
    }
}
class IceHeroAction implements HeroAction {
    @Override
    public void kick() {
        System.out.println("Ice kick");
    }
    @Override
    public void slash() {
        System.out.println("Ice slash");
    }
    @Override
    public void beat() {
        System.out.println("Ice beat");
    }
}
//宣告一個抽象當作Abstraction
abstract class Hero {
    private HeroAction heroAction;
    Hero() {
    }
    Hero(HeroAction heroAction) {
        this.heroAction = heroAction;
    }
    public void setHeroAction(HeroAction heroAction) {
        this.heroAction = heroAction;
    }
    public HeroAction getHeroAction() {
        return heroAction;
    }
    abstract void kick();
    abstract void attack();
}
//宣告兩個英雄class繼承Hero
//宣告下方任一個class時，會把角色魔法傳給Hero
class Magician extends Hero {
    Magician(HeroAction heroAction) {
        super(heroAction);
    }
    @Override
    void kick() {
        getHeroAction().kick();
    }
    @Override
    void attack() {
        getHeroAction().beat();
    }
}
class Warrior extends Hero {
    Warrior(HeroAction heroAction) {
        super(heroAction);
    }
    @Override
    void kick() {
        getHeroAction().kick();
    }
    @Override
    void attack() {
        getHeroAction().slash();
    }
}
// 實作
public class Bridge {
    public static void main(String[] args) {
        Hero warrior = new Warrior(new IceHeroAction());
        Hero magician = new Magician(new FireHeroAction());
        warrior.attack();
        magician.attack();
    }
}

```

> [name=閔致]