[C#]橋接模式(Bridge)

[C#]橋接模式(Bridge)

目的

為了解決一個介面已經被多個類別給實作,這時候如果我們需要再為此介面新增方法的時候,就會面臨到多支類別都要擴充此方法,就會造成擴充不易,甚至有些可能不需要此方法,這時候就可以多加一個新的介面,然後把原本的介面當成屬性加在新的介面裡面,然後直接呼叫新介面就也會有擁有原本想擴充介面的屬性,也同時擁有新介面的方法或屬性。

情境模擬

在實務上很多都是會定義service對應到某個table的名稱,比如說我們有一個table名為account,那大概就會有相對應的AccountDao和AccountService,那以Service來說我們可能就會擁有了IAccountService,GoogleAccountService和FaceBookAccountService,底下則是程式碼示例

IAccountService

 public interface IAccountService      
 {                                     
     string GetAll();                  
     void ModifyPwd();                 
     string Login();                   
     bool IsLogin();                   
     void Remove();                    
 }                                     

類別實作部份

    public class FaceBookAccountService : IAccountService
    {
        public string GetAll()
        {
            return "Get All FB Account";
        }

        public bool IsLogin()
        {
            return true;
        }

        public string Login()
        {
            return "Anson is login";
        }

        public void ModifyPwd()
        {
            Console.WriteLine("Modify success of FB account");
        }

        public void Remove()
        {
            Console.WriteLine("Remove success of FB account");
        }
    }

    public class GoogleAccountService : IAccountService
    {
        public string GetAll()
        {
            return "Get All Google Account";
        }

        public bool IsLogin()
        {
            return true;
        }

        public string Login()
        {
            return "Anson is login";
        }

        public void ModifyPwd()
        {
            Console.WriteLine("Modify success of google account");
        }

        public void Remove()
        {
            Console.WriteLine("Remove success of google account");
        }
    }

呼叫端

        static void Main(string[] args)
        {
            IAccountService _service = new GoogleAccountService();
            Console.Write(_service.GetAll());
            Console.ReadKey();
        }

結果

Get All Google Account

可以想像如果有三支或四支共同實做了此介面,那我們介面如果要加一個方法,四支類別都得異動,新增了方法不打緊,就怕根本不需要會造成違反里氏替換原則(不要欺騙實做端,有得呼叫就一定得實做),那接下來就來看一下橋接模式後的程式碼會長什麼樣子呢,假設我們介面新增了一個TransferAccount的方法,目的是為了要sso轉移去另一個平台。

ISsoService

 public interface ISsoService
    {
        IAccountService AccountService { get; set; }
        void TransferAccount();
    }

SsoService

    public class SsoService : ISsoService
    {
        IAccountService _accountService = new GoogleAccountService(); //預設會是google的帳號

        public IAccountService AccountService //提供屬性讓外面可以替換
        {
            get
            {
                return _accountService;
            }

            set
            {
                _accountService = value;
            }
        }

        public void TransferAccount()
        {
            Console.WriteLine("Success of transfer to another web site");
        }
    }

呼叫端

        static void Main(string[] args)
        {
            ISsoService service = new SsoService();
            Console.WriteLine(service.AccountService.GetAll());
            service.TransferAccount();
            service.AccountService = new FaceBookAccountService();
            Console.WriteLine(service.AccountService.GetAll());
            Console.ReadKey();
        }

結果

Get All Google Account
Success of transfer to another web site
Get All FB Account

最後完整程式碼

    class Program
    {
        static void Main(string[] args)
        {
            ISsoService service = new SsoService();
            Console.WriteLine(service.AccountService.GetAll());
            service.TransferAccount();
            service.AccountService = new FaceBookAccountService();
            Console.WriteLine(service.AccountService.GetAll());
            Console.ReadKey();
        }
    }

    public interface IAccountService
    {
        string GetAll();
        void ModifyPwd();
        string Login();
        bool IsLogin();
        void Remove();
    }

    public interface ISsoService
    {
        IAccountService AccountService { get; set; }
        void TransferAccount();
    }

    public class SsoService : ISsoService
    {
        IAccountService _accountService = new GoogleAccountService(); //預設會是google的帳號

        public IAccountService AccountService //提供屬性讓外面可以替換
        {
            get
            {
                return _accountService;
            }

            set
            {
                _accountService = value;
            }
        }

        public void TransferAccount()
        {
            Console.WriteLine("Success of transfer to another web site");
        }
    }

    public class FaceBookAccountService : IAccountService
    {
        public string GetAll()
        {
            return "Get All FB Account";
        }

        public bool IsLogin()
        {
            return true;
        }

        public string Login()
        {
            return "Anson is login";
        }

        public void ModifyPwd()
        {
            Console.WriteLine("Modify success of FB account");
        }

        public void Remove()
        {
            Console.WriteLine("Remove success of FB account");
        }
    }

    public class GoogleAccountService : IAccountService
    {
        public string GetAll()
        {
            return "Get All Google Account";
        }

        public bool IsLogin()
        {
            return true;
        }

        public string Login()
        {
            return "Anson is login";
        }

        public void ModifyPwd()
        {
            Console.WriteLine("Modify success of google account");
        }

        public void Remove()
        {
            Console.WriteLine("Remove success of google account");
        }
    }