文章出處
文章列表
索引
通過明確地附加角色對象到目標對象中,以使對象可以適配不同的客戶需求。每個角色對象都代表著目標對象在客戶上下文中的一種角色。每種上下文都存在于特定的應用程序中,因此可使對象在不同的應用程序間解耦。
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 則正是強調了這一點。
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 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。
文章列表
全站熱搜