设计模式—桥接模式
前言
這里以電視遙控器為例子引出橋接模式,首先每個牌子的電視都有一個遙控器,可以設(shè)計吧遙控器作為一個抽象類,抽象類中提供遙控器的所有實現(xiàn),其他具體電視品牌的遙控器都繼承這個抽象類
?
這樣的實現(xiàn)使得每個不同型號的電視都有自己的遙控器實現(xiàn),這樣的設(shè)計對于電視劇品牌的改變可以很好的應(yīng)對,只要添加一個派生類就可以了。但是隨著時間的推移,用戶需要改變遙控器的功能,如:用戶可能需要添加一個返回上個臺的功能,這是就需要修改抽象類了,這樣就違反了設(shè)計原則,如果用戶同時改變電視劇的品牌型號和遙控器功能時,此時的設(shè)計就更麻煩了,而使用橋接模式可以很好的解決問題
?
橋接模式介紹
橋接模式即將抽象部分與實現(xiàn)部分脫耦,使它們可以獨(dú)立改變。對于上面的問題,抽象化也就是RemoteControl類,實現(xiàn)部分就是on(),off(),nextchannel(),這樣的方法。上面設(shè)計中抽象化和實現(xiàn)部分在一起,橋接模式的目的就是使兩者分開,我們把實現(xiàn)部分的變化封裝到另外一個類中,這樣一個思路就是橋接模式的實現(xiàn)
1)實際例子
抽象化部分代碼
?
//注釋:里面方法定義成virtual 以方便如果有類繼承此類時可以任意重寫其中的方法/// <summary>/// 抽象概念中的遙控器,扮演抽象化角色/// </summary>public class RemoteControl{private TV implementor;public TV Implementor{get { return implementor; }set { implementor = value; }}//public virtual void MdadCity()//{// implementor.MadeCity();//}/// <summary>/// 開電視機(jī),這里抽象類中不再提供實現(xiàn)了,而是調(diào)用實現(xiàn)類中的實現(xiàn)/// </summary>public virtual void On(){implementor.On();}/// <summary>/// 關(guān)電視機(jī)/// </summary>public virtual void Off(){implementor.Off();}/// <summary>/// 換頻道/// </summary>public virtual void RuneChannel(){implementor.RuneChannel();}}/// <summary>/// 具體遙控器/// </summary>public class ConcreteRemote : RemoteControl{public override void RuneChannel(){Console.WriteLine("---------------------");base.RuneChannel();Console.WriteLine("---------------------");}}?
?實現(xiàn)方法的部分代碼我們用另外一個抽象類TV封裝了遙控器的功能變化,具體實現(xiàn)交給具體型號電視去完成
//注釋:定義成抽象類,如果有公共的方法可以在該抽象類中進(jìn)行實習(xí),如果是接口的話有些公共的方法就不能復(fù)用了/// <summary>/// 電視機(jī),提供抽象方法/// </summary>public abstract class TV{//public void MadeCity()//{// Console.WriteLine("made in china");//}public abstract void On();public abstract void Off();public abstract void RuneChannel();}/// <summary>/// 長虹牌電視機(jī),重寫基類的抽象方法/// 提供具體的實現(xiàn)/// </summary>public class ChangHong : TV{public override void On(){Console.WriteLine("長虹牌電視機(jī)打開");}public override void Off(){Console.WriteLine("長虹牌電視機(jī)關(guān)閉");}public override void RuneChannel(){Console.WriteLine("長虹牌電視機(jī)換臺");}}/// <summary>/// 三星牌電視機(jī),重寫基類的抽象方法/// </summary>public class SanXing : TV{public override void On(){Console.WriteLine("三星牌電視機(jī)打開");}public override void Off(){Console.WriteLine("三星牌電視機(jī)關(guān)閉");}public override void RuneChannel(){Console.WriteLine("三星牌電視機(jī)換臺");}}?客戶端調(diào)用時
static void Main1(string[] args){RemoteControl remoteControl = new ConcreteRemote();remoteControl.Implementor = new ChangHong();remoteControl.On();remoteControl.RuneChannel();remoteControl.Off();Console.WriteLine();remoteControl.Implementor = new SanXing();remoteControl.On();remoteControl.RuneChannel();remoteControl.Off();Console.Read();}?運(yùn)行結(jié)果:
上面打代碼實現(xiàn)中,遙控器的實現(xiàn)方法不再遙控器抽象類中實現(xiàn)了,而是把實現(xiàn)部分用另一個電視類去封裝,遙控器中只包含電視劇類的引用。通過橋接模式,我們把抽象化和實現(xiàn)部分代碼分離,這樣就可以很好的應(yīng)對這兩個方面的變化了。
?
2)橋接模式介紹
3)橋接模式分析
優(yōu)點(diǎn):抽象接口與其實現(xiàn)解耦
???????? 抽象和實現(xiàn)可以獨(dú)立擴(kuò)展,不會影響對方
缺點(diǎn):增加了系統(tǒng)的復(fù)雜度
4)使用場景
如果一個系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間添加更多的靈活性,避免在兩個層次之間建立靜態(tài)的聯(lián)系
設(shè)計要求實現(xiàn)化角色的任何改變不應(yīng)擔(dān)影響客戶端,或者實現(xiàn)化角色的改變對客戶端是完全透明的
需要跨越多個平臺的圖形和窗口系統(tǒng)上
一個類存在兩個對立變化的緯度,且兩個緯度都需要進(jìn)行擴(kuò)展
5)實際例子
橋接模式經(jīng)常用于具體的系統(tǒng)開發(fā)中,對于三層架構(gòu)中就應(yīng)用了橋接模式,三層架構(gòu)中的業(yè)務(wù)邏輯層bll中通過橋接模式與數(shù)據(jù)庫操作層解耦,其實現(xiàn)方式就是在bll層中引用了dal層中一個引用,這樣數(shù)據(jù)操作的實現(xiàn)可以在不改變客戶端代碼的情況下動態(tài)進(jìn)行更換了
?
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApplication1 {// BLL 層public class BusinessObject{private DataAccess dataAccess;private string city;public BusinessObject(string city){this.city = city;}public DataAccess DataAccess{get { return dataAccess; }set { dataAccess = value; }}public virtual void Add(string name){dataAccess.AddRecord(name);}public virtual void Delete(string name){dataAccess.DeleteRecord(name);}public virtual void Update(string name){dataAccess.UpdateRecord(name);}public virtual string Get(int index){return dataAccess.GetRecord(index);}public virtual void ShowAll(){Console.WriteLine();Console.WriteLine("{0}的顧客有:", city);dataAccess.ShowAllRecords();}}public class CustomersBusinessObject : BusinessObject{public CustomersBusinessObject(string city) : base(city) { }public override void ShowAll(){Console.WriteLine("----------");base.ShowAll();Console.WriteLine("___________");}}/// <summary>/// 相當(dāng)于三層架構(gòu)中數(shù)據(jù)訪問層(DAL)/// </summary>public abstract class DataAccess{// 對記錄的增刪改查操作public abstract void AddRecord(string name);public abstract void DeleteRecord(string name);public abstract void UpdateRecord(string name);public abstract string GetRecord(int index);public abstract void ShowAllRecords();}public class CustomersDataAccess : DataAccess{private List<string> customers = new List<string>();public CustomersDataAccess(){customers.Add("Learning Hard");customers.Add("張三");customers.Add("李四");customers.Add("王五");}public override void AddRecord(string name){customers.Add(name);}public override void DeleteRecord(string name){customers.Remove(name);}public override void UpdateRecord(string updatename){customers[0] = updatename;}public override string GetRecord(int index){return customers[index];}public override void ShowAllRecords(){foreach (string name in customers){Console.WriteLine(" " + name);}}} }?
?客戶端調(diào)用:
// 類似Web應(yīng)用程序static void Main(string[] args){BusinessObject customers = new CustomersBusinessObject("shanghai");customers.DataAccess = new CustomersDataAccess();customers.Add("小六");Console.WriteLine("增加了一位成員的結(jié)果:");customers.ShowAll();customers.Delete("王五");Console.WriteLine("刪除了一位成員的結(jié)果:");customers.ShowAll();customers.Update("Learning_Hard");Console.WriteLine("更新了一位成員的結(jié)果:");customers.ShowAll();Console.Read();}?運(yùn)行結(jié)果:
?
轉(zhuǎn)載于:https://www.cnblogs.com/xishuqingchun/p/5012074.html
總結(jié)
- 上一篇: CPC客户端安装教程(2022/4/1)
- 下一篇: CPC客户端打开报错:未在本地计算机上注