文章出處

索引

意圖

通過明確地附加角色對象到目標對象中,以使對象可以適配不同的客戶需求。每個角色對象都代表著目標對象在客戶上下文中的一種角色。每種上下文都存在于特定的應用程序中,因此可使對象在不同的應用程序間解耦。

Adapt an object to different client’s needs through transparently attached role objects, each one representing a role the object has to play in that client’s context. Each context may be its own application, which therefore gets decoupled from the other applications.

結構

參與者

Component

  • 定義關鍵的抽象接口。
  • 定義添加、刪除、測試和查詢角色對象的接口協議。Client 可以指定一個 specification 來獲取一個 ConcreteRole 實例。

ComponentCore

  • 實現 Component 接口,包括角色管理協議。
  • 負責創建 ConcreteRole 實例。
  • 管理角色對象。

ComponentRole

  • 存儲一個經過裝飾的 ComponentCore 對象的引用。
  • 實現 Component 接口,并將接口請求轉發到 ComponentCore 中。

ConcreteRole

  • 定義和實現特定上下文的 Component 接口的實現。
  • 構造函數包含一個 ComponentCore 參數。

Client

  • 請求協作對象。

適用性

當以下情況成立時可以使用 Role Object 模式:

  • 你需要在不同的客戶上下文間保持關鍵的抽象定義,每種抽象定義的實現都存在于其特定的應用范圍內,同時你不想將這些與客戶上下文相關的接口耦合在同一個接口內。
  • 你需要能夠動態的處理角色,以便可以在運行時按需的添加或移除角色,而不是在編譯時使用固定的對象定義。
  • 你需要保持角色與客戶成對兒關系,在不同的角色與客戶對之間保持獨立性,當更改一個角色時并不影響其他客戶。

效果

  • 可以簡潔地定義對象的關鍵抽象。Component 接口僅需關注必要的狀態的行為,而不會涉及具體上下文中的職責。
  • 角色對象易于演進,彼此之間保持獨立。
  • 角色對象可以動態的添加和移除。
  • 應用程序可以更好的解耦和。

相關模式

  • Decorator 模式與 Role Object 模式有著類似的結構,但行為不同。Decorator 模式使開發人員可以對一個對象進行鏈式的裝飾,而 Role Object 模式則不允許這樣。并且,Decorator 通常不會擴大對象的功能,而 Role Object 會引入新的操作。
  • Extension Object 模式也在解決類似的問題,通過對對象的擴展來滿足特定的客戶上下文的需求。盡管如此,Extension Object 并沒有考慮透明性(Transparently),即保持對象關鍵抽象(Key Abstraction)的定義,而 Role Object 則正是強調了這一點。

實現

實現方式(一):Role Object 的示例實現。

  1 namespace RoleObjectPattern.Implementation1
  2 {
  3   public abstract class Customer
  4   {
  5     public abstract CustomerRole GetRole(string spec);
  6     public abstract void AddRole(string spec);
  7     public abstract void RemoveRole(string spec);
  8     public abstract bool HasRole(string spec);
  9     public abstract void SomeCommonOperation1();
 10   }
 11 
 12   public class CustomerCore : Customer
 13   {
 14     private Dictionary<string, CustomerRole> _roles
 15       = new Dictionary<string, CustomerRole>();
 16     private CustomerRoleFactory _roleFactory;
 17 
 18     public CustomerCore(CustomerRoleFactory roleFactory)
 19     {
 20       _roleFactory = roleFactory;
 21     }
 22 
 23     public override CustomerRole GetRole(string spec)
 24     {
 25       if (_roles.ContainsKey(spec))
 26         return _roles[spec];
 27       else
 28         return null;
 29     }
 30 
 31     public override void AddRole(string spec)
 32     {
 33       CustomerRole role = GetRole(spec);
 34       if (role == null)
 35       {
 36         role = _roleFactory.CreateRole(spec, this);
 37         if (role != null)
 38         {
 39           _roles.Add(spec, role);
 40         }
 41       }
 42     }
 43 
 44     public override void RemoveRole(string spec)
 45     {
 46       _roles.Remove(spec);
 47     }
 48 
 49     public override bool HasRole(string spec)
 50     {
 51       return _roles.ContainsKey(spec);
 52     }
 53 
 54     public override void SomeCommonOperation1()
 55     {
 56       // do some business logic
 57     }
 58   }
 59 
 60   public class CustomerRole : Customer
 61   {
 62     private CustomerCore _decoratedCore;
 63 
 64     public CustomerRole(CustomerCore core)
 65     {
 66       _decoratedCore = core;
 67     }
 68 
 69     public override CustomerRole GetRole(string spec)
 70     {
 71       return _decoratedCore.GetRole(spec);
 72     }
 73 
 74     public override void AddRole(string spec)
 75     {
 76       _decoratedCore.AddRole(spec);
 77     }
 78 
 79     public override void RemoveRole(string spec)
 80     {
 81       _decoratedCore.RemoveRole(spec);
 82     }
 83 
 84     public override bool HasRole(string spec)
 85     {
 86       return _decoratedCore.HasRole(spec);
 87     }
 88 
 89     public override void SomeCommonOperation1()
 90     {
 91       _decoratedCore.SomeCommonOperation1();
 92     }
 93   }
 94 
 95   public class Borrower : CustomerRole
 96   {
 97     public Borrower(CustomerCore core)
 98       : base(core)
 99     {
100     }
101 
102     public void SomeOperationForBorrower()
103     {
104       // do something for borrower
105     }
106   }
107 
108   public class Investor : CustomerRole
109   {
110     public Investor(CustomerCore core)
111       : base(core)
112     {
113     }
114 
115     public void SomeOperationForInvestor()
116     {
117       // do something for investor
118     }
119   }
120 
121   public class CustomerRoleFactory
122   {
123     public CustomerRole CreateRole(string spec, CustomerCore core)
124     {
125       CustomerRole newRole = null;
126 
127       if (spec == "Borrower")
128       {
129         newRole = new Borrower(core);
130       }
131       else if (spec == "Investor")
132       {
133         newRole = new Investor(core);
134       }
135 
136       return newRole;
137     }
138   }
139 
140   public class Client
141   {
142     public void TestCase1()
143     {
144       Customer customer = new CustomerCore(new CustomerRoleFactory());
145       customer.AddRole("Borrower");
146       customer.AddRole("Investor");
147 
148       CustomerRole customerRole1 = customer.GetRole("Borrower");
149       Borrower borrower = (Borrower)customerRole1;
150       borrower.SomeCommonOperation1();
151       borrower.SomeOperationForBorrower();
152 
153       CustomerRole customerRole2 = customer.GetRole("Investor");
154       Investor investor = (Investor)customerRole2;
155       investor.SomeCommonOperation1();
156       investor.SomeOperationForInvestor();
157     }
158   }
159 }

設計模式之美》為 Dennis Gao 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()