---
# System prepended metadata

title: 表象模式(Facade Pattern)
tags: [設計模式]

---

---
tags: 設計模式
---


# 表象模式(Facade Pattern)
> 提供了一個統一的介面，用來存取次系統中的一群介面。表象定義了一個較高層次的介面，讓次系統更容易使用。
> [name=深入淺出設計模式]

## 簡單範例

買了一個家庭劇院，擁有許多功能：播放器、投影機、自動螢幕、環繞音效、爆米花機。

但在我需要觀看電影時，我需要開啟螢幕、音效、爆米花機、播放器等流程才能看的了電影，該如何解決這種混亂？

我們利用表象模式呼叫表象物件中的方法幫我完成。


```csharp=
static void Main(string[] args)
{
    Console.WriteLine("Facade Pattern!");

    //Init
    Amplifier amplifier = new Amplifier();
    CdPlayer cdPlayer = new CdPlayer();
    Projector projector = new Projector();
    HomeTheaterFacade homeTheater = new HomeTheaterFacade(amplifier,cdPlayer,projector);

    homeTheater.WatchMovie();
    homeTheater.CloseMovie();
}

```


表象物件
```csharp=
public class HomeTheaterFacade
{
    Amplifier amplifier;
    CdPlayer cdPlayer;
    Projector projector;

    public HomeTheaterFacade(Amplifier amplifier,CdPlayer cdPlayer,Projector projector){
        this.amplifier = amplifier;
        this.cdPlayer = cdPlayer;
        this.projector = projector;
    }

    public void WatchMovie(){
        Console.WriteLine("WatchMovie starting....");
        amplifier.On();
        cdPlayer.Play();
        projector.On();
    }

    public void CloseMovie(){
        Console.WriteLine("CloseMovie starting....");
        amplifier.Off();
        cdPlayer.Stop();
        projector.Off();
    }
}

```

劇院子系統
```csharp=
public class Amplifier
{
    public void On(){
        Console.WriteLine("Amplifier On");
    }
    public void Off(){
        Console.WriteLine("Amplifier Off");
    }
}
```

```csharp=
public class Projector
{
    public void On(){
        Console.WriteLine("DvdPlayer Play");
    }
    public void Off(){
        Console.WriteLine("DvdPlayer Stop");
    }
}

```

```csharp=
public class CdPlayer
{
    public void Play(){
        Console.WriteLine("CdPlayer Play");
    }
    public void Stop(){
        Console.WriteLine("CdPlayer Stop");
    }
}
```

結果
![](https://i.imgur.com/ki54m59.png)


## 轉接器vs表象
* 轉接器
    * 改變介面符合客戶期望
* 表象
    * 提供次系統一個簡化介面

## 極少化守則
> 減少物件之間的互動，只和你的密友談話。
> 
> 當你正在設計一個系統，不管是任何物件，都要注意和他互動的物件有哪些，並注意他和這些類別如何互動。
> [name=深入淺出設計模式]

例如以某個物件而言，在這個物件內的方法中，只應該引用以下物件的方法：
* 該物件本身
* 被當作方法的參數而傳遞進來的動作
* 此方法所建立或實體化的物件
* 物件的任何元件

該物件本身：
```csharp=
class KeepSimple
{
    private void Method1(){
        Method2();
    }
    private void Method2(){
    
    }
}
```

被當作方法的參數而傳遞進來的動作:
```csharp=
class KeepSimple
{
    private void Method1(Class1 class1){
        class1.Method1();
    }
}

public abstract class Class1
{
    public abstract void Method1();
}
```
此方法所建立或實體化的物件:
```csharp=
class KeepSimple
{
    private void Method1(){
        Class1 class1 = new Class1();
        class1.Method1();
    }
}

public  class Class1
{
    public  void Method1(){

    }
}
```

物件的任何元件:
```csharp=
class KeepSimple
{
    Class1 class1 = new Class1();
    private void Method1(){
        class1.Method1();
    }
}
public  class Class1
{
    public  void Method1(){

    }
}
```
==違反守則情形==
```csharp=
class KeepSimple
{
    private void Method1(){
        Class1 class1 = new Class1();
        Class2 class2 = class1.Method1();
    }
}
public  class Class1
{
    public  Class2 Method1(){
        return null;
    }
}

public class Class2{
    public void Method1(){

    }
}
```