Design Pattern - Adapter

(史帝芬, 2006/05/07, hi.steven@gmail.com)
Adapter Pattern的目的在於將類別的介面轉換成外界預期的另一種介面,讓原先囿於介面不相容 問題而無法協力合作的類別能夠兜在一起用。實作Adapter Pattern的方法有兩種, (a) 繼承 (b) 委讓。底下例子為Banner是舊版程式,因為需求改變,目前需要一個提供printWeak和printStrong 兩個method,但是我們不打算改寫Banner,那麼要如何用Adapter Pattern來解決這個問題? 底下將分別為這兩種方法用C#寫一個範例程式。
  • 舊程式

  • using System;
    
    namespace Adapter
    {
    	public class Banner
    	{
    		private string text;
    
    		public Banner(string text)
    		{
    			this.text = text;
    		}
    
    		public void showWithParen() 
    		{
    			Console.WriteLine("(" + text + ")");
    		}
    
    		public void showWithAster() 
    		{
    			Console.WriteLine("*" + text + "*");
    		}
    	}
    }
    

  • 新介面

  • using System;
    
    namespace Adapter
    {
    	public interface Print
    	{
    		void printWeak();
    		void printStrong();
    	}
    }
    

  • 繼承


  • using System;
    
    namespace Adapter
    {
    	public class PrintBanner : Banner, Print
    	{
    		public PrintBanner(string text) : base(text)
    		{
    			
    		}
    
    		#region Print 成員
    
    		public void printWeak()
    		{
    			showWithParen();
    		}
    
    		public void printStrong()
    		{
    			showWithAster();
    		}
    
    		#endregion
    	}
    }
    

  • 委讓


  • using System;
    
    namespace Adapter
    {
    	public class PrintBanner : Print
    	{
    		Banner banner;
    		public PrintBanner(string text)
    		{
    			banner = new Banner(text);
    		}
    
    		#region Print 成員
    
    		public void printWeak()
    		{
    			banner.showWithParen();
    		}
    
    		public void printStrong()
    		{
    			banner.showWithAster();
    		}
    
    		#endregion
    	}
    }
    

  • 測試程式

  • using System;
    
    namespace Adapter
    {
    	class Class1
    	{
    		[STAThread]
    		static void Main(string[] args)
    		{
    			Print p = new PrintBanner("Hello");
    			p.printWeak();
    			p.printStrong();
    		}
    	}
    }
    

  • 執行結果

  • (Hello)
    *Hello*


    繼承與合成的比較
     優點缺點
    繼承a. 需撰寫的程式碼較少
    b. 執行效率較好
    類別間的耦合度較高
    合成類別間的耦合度較低a. 需撰寫的程式碼較多
    b. 執行效率較差