code_junkie

How to implement and extend Joshua's builder pattern in .net?

Nov 12th, 2011
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.39 KB | None | 0 0
  1. public class NutritionFacts
  2. {
  3. public static NutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
  4. {
  5. return new NutritionFacts.Builder(name, servingSize, servingsPerContainer);
  6. }
  7.  
  8. public sealed class Builder
  9. {
  10. public Builder(String name, int servingSize,
  11. int servingsPerContainer)
  12. {
  13. }
  14. public Builder totalFat(int val) { }
  15. public Builder saturatedFat(int val) { }
  16. public Builder transFat(int val) { }
  17. public Builder cholesterol(int val) { }
  18. //... 15 more setters
  19. public NutritionFacts build()
  20. {
  21. return new NutritionFacts(this);
  22. }
  23. }
  24. private NutritionFacts(Builder builder) { }
  25. protected NutritionFacts() { }
  26. }
  27.  
  28. public class MoreNutritionFacts : NutritionFacts
  29. {
  30. public new static MoreNutritionFacts.Builder Build(string name, int servingSize, int servingsPerContainer)
  31. {
  32. return new MoreNutritionFacts.Builder(name, servingSize, servingsPerContainer);
  33. }
  34. public new sealed class Builder
  35. {
  36. public Builder(String name, int servingSize,
  37. int servingsPerContainer) {}
  38. public Builder totalFat(int val) { }
  39. public Builder saturatedFat(int val) { }
  40. public Builder transFat(int val) { }
  41. public Builder cholesterol(int val) { }
  42. //... 15 more setters
  43. public Builder newProperty(int val) { }
  44. public MoreNutritionFacts build()
  45. {
  46. return new MoreNutritionFacts(this);
  47. }
  48. }
  49. private MoreNutritionFacts(MoreNutritionFacts.Builder builder) { }
  50. }
  51.  
  52. public class CustomerBuilder
  53. {
  54.  
  55. ......
  56.  
  57. public static implicit operator Customer( CustomerBuilder builder )
  58. {
  59. return builder.Build();
  60. }
  61. }
  62.  
  63. public sealed class SomeMessage
  64. {
  65. public string Name { get; private set; }
  66. public int Age { get; private set; }
  67.  
  68. // Can only be called in this class and nested types
  69. private SomeMessage() {}
  70.  
  71. public sealed class Builder
  72. {
  73. private SomeMessage message = new SomeMessage();
  74.  
  75. public string Name
  76. {
  77. get { return message.Name; }
  78. set { message.Name = value; }
  79. }
  80.  
  81. public int Age
  82. {
  83. get { return message.Age; }
  84. set { message.Age = value; }
  85. }
  86.  
  87. public SomeMessage Build()
  88. {
  89. // Check for optional fields etc here
  90. SomeMessage ret = message;
  91. message = null; // Builder is invalid after this
  92. return ret;
  93. }
  94. }
  95. }
  96.  
  97. public interface IFactory<T>
  98. {
  99. T Create();
  100. }
  101.  
  102. public interface IBuilder<T> : IFactory<T>
  103. {
  104. bool HasInstance { get; }
  105.  
  106. T Instance { get; }
  107.  
  108. void ClearInstance();
  109. }
  110.  
  111. public abstract class Builder<T> : IBuilder<T>
  112. {
  113. public static implicit operator T(Builder<T> builder)
  114. {
  115. return builder.Instance;
  116. }
  117.  
  118. T _instance;
  119.  
  120. public abstract T Create();
  121.  
  122. public bool HasInstance { get; private set; }
  123.  
  124. public T Instance
  125. {
  126. get
  127. {
  128. if(!this.HasInstance)
  129. {
  130. _instance = Create();
  131.  
  132. this.HasInstance = true;
  133. }
  134.  
  135. return _instance;
  136. }
  137. }
  138.  
  139. public void ClearInstance()
  140. {
  141. this.HasInstance = false;
  142.  
  143. _instance = default(T);
  144. }
  145. }
  146.  
  147. public class Order
  148. {
  149. public string ReferenceNumber { get; private set; }
  150.  
  151. public DateTime? ApprovedDateTime { get; private set; }
  152.  
  153. public void Approve()
  154. {
  155. this.ApprovedDateTime = DateTime.Now;
  156. }
  157. }
  158.  
  159. public Order(string referenceNumber)
  160. {
  161. // ... validate ...
  162.  
  163. this.ReferenceNumber = referenceNumber;
  164. }
  165.  
  166. internal Order(string referenceNumber, DateTime? approvedDateTime)
  167. {
  168. this.ReferenceNumber = referenceNumber;
  169. this.ApprovedDateTime = approvedDateTime;
  170. }
  171.  
  172. public class OrderBuilder : Builder<Order>
  173. {
  174. string _referenceNumber;
  175. DateTime? _approvedDateTime;
  176.  
  177. public override Order Create()
  178. {
  179. return new Order(_referenceNumber, _approvedDateTime);
  180. }
  181.  
  182. public string ReferenceNumber
  183. {
  184. get { return _referenceNumber; }
  185. set
  186. {
  187. if(value != _referenceNumber)
  188. {
  189. _referenceNumber = value;
  190.  
  191. ClearInstance();
  192. }
  193. }
  194. }
  195.  
  196. public DateTime? ApprovedDateTime
  197. {
  198. get { return _approvedDateTime; }
  199. set
  200. {
  201. if(value != _approvedDateTime)
  202. {
  203. _approvedDateTime = value;
  204.  
  205. ClearInstance();
  206. }
  207. }
  208. }
  209. }
  210.  
  211. Order order = new OrderBuilder
  212. {
  213. ReferenceNumber = "ABC123",
  214. ApprovedDateTime = new DateTime(2008, 11, 25)
  215. };
  216.  
  217. public class NutritionFacts
  218. {
  219. public int servingSize { get; private set; }
  220. public int servings { get; private set; }
  221. public int calories { get; private set; }
  222. public int fat { get; private set; }
  223. public int carbohydrate { get; private set; }
  224. public int sodium { get; private set; }
  225.  
  226. public NutritionFacts(int servingSize, int servings, int calories = 0, int fat = 0, int carbohydrate = 0, int sodium = 0)
  227. {
  228. this.servingSize = servingSize;
  229. this.servings = servings;
  230. this.calories = calories;
  231. this.fat = fat;
  232. this.carbohydrate = carbohydrate;
  233. this.sodium = sodium;
  234. }
  235. }
  236.  
  237. NutritionFacts nf2 = new NutritionFacts(240, 2, calories: 100, fat: 40);
Add Comment
Please, Sign In to add comment