diff --git a/Finished sample/.editorconfig b/Finished sample/.editorconfig
new file mode 100644
index 0000000..ddb2c49
--- /dev/null
+++ b/Finished sample/.editorconfig
@@ -0,0 +1,232 @@
+# Remove the line below if you want to inherit .editorconfig settings from higher directories
+root = true
+
+# C# files
+[*.cs]
+
+#### Core EditorConfig Options ####
+
+# Indentation and spacing
+indent_size = 4
+indent_style = space
+tab_width = 4
+
+# New line preferences
+end_of_line = crlf
+insert_final_newline = false
+
+#### .NET Coding Conventions ####
+
+# Organize usings
+dotnet_separate_import_directive_groups = false
+dotnet_sort_system_directives_first = true
+file_header_template = unset
+
+# this. and Me. preferences
+dotnet_style_qualification_for_event = false
+dotnet_style_qualification_for_field = false
+dotnet_style_qualification_for_method = false
+dotnet_style_qualification_for_property = false
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true
+dotnet_style_predefined_type_for_member_access = true
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary
+dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary
+dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = omit_if_default # I hate "private" everywhere!
+
+# Expression-level preferences
+dotnet_style_coalesce_expression = true
+dotnet_style_collection_initializer = true
+dotnet_style_explicit_tuple_names = true
+dotnet_style_namespace_match_folder = false # see README for explanation
+dotnet_style_null_propagation = true
+dotnet_style_object_initializer = true
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_prefer_auto_properties = true:warning
+dotnet_style_prefer_collection_expression = true
+dotnet_style_prefer_compound_assignment = true
+#Dick dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
+#Dick dotnet_style_prefer_conditional_expression_over_return = true:suggestion
+dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
+dotnet_style_prefer_inferred_anonymous_type_member_names = true
+dotnet_style_prefer_inferred_tuple_names = true
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true
+dotnet_style_prefer_simplified_boolean_expressions = true
+dotnet_style_prefer_simplified_interpolation = true
+
+# Field preferences
+dotnet_style_readonly_field = true
+
+# Parameter preferences
+dotnet_code_quality_unused_parameters = all
+
+# Suppression preferences
+dotnet_remove_unnecessary_suppression_exclusions = none
+
+# New line preferences
+dotnet_style_allow_multiple_blank_lines_experimental = false
+dotnet_style_allow_statement_immediately_after_block_experimental = true
+
+#### C# Coding Conventions ####
+
+# var preferences
+csharp_style_var_elsewhere = false
+csharp_style_var_for_built_in_types = true
+csharp_style_var_when_type_is_apparent = true
+
+# Expression-bodied members
+csharp_style_expression_bodied_accessors = true
+#Dick csharp_style_expression_bodied_constructors = true
+#Dick csharp_style_expression_bodied_indexers = true
+#Dick csharp_style_expression_bodied_lambdas = true:suggestion
+#Dick csharp_style_expression_bodied_local_functions = true:suggestion
+#Dick csharp_style_expression_bodied_methods = true
+#Dick csharp_style_expression_bodied_operators = true
+#Dick csharp_style_expression_bodied_properties = true
+
+# Pattern matching preferences
+csharp_style_pattern_matching_over_as_with_null_check = true
+csharp_style_pattern_matching_over_is_with_cast_check = true
+csharp_style_prefer_extended_property_pattern = true
+csharp_style_prefer_not_pattern = true
+csharp_style_prefer_pattern_matching = true
+csharp_style_prefer_switch_expression = true
+
+# Null-checking preferences
+csharp_style_conditional_delegate_call = true
+
+# Modifier preferences
+csharp_prefer_static_local_function = true
+csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
+csharp_style_prefer_readonly_struct = true
+csharp_style_prefer_readonly_struct_member = true
+
+# Code-block preferences
+csharp_prefer_braces = true
+csharp_prefer_simple_using_statement = true
+csharp_style_namespace_declarations = file_scoped
+csharp_style_prefer_method_group_conversion = true
+csharp_style_prefer_primary_constructors = true
+csharp_style_prefer_top_level_statements = true
+
+# Expression-level preferences
+csharp_prefer_simple_default_expression = true
+csharp_style_deconstructed_variable_declaration = true
+csharp_style_implicit_object_creation_when_type_is_apparent = true
+csharp_style_inlined_variable_declaration = true
+csharp_style_prefer_index_operator = true
+csharp_style_prefer_local_over_anonymous_function = true
+csharp_style_prefer_null_check_over_type_check = true
+csharp_style_prefer_range_operator = true
+csharp_style_prefer_tuple_swap = true
+csharp_style_prefer_utf8_string_literals = true
+csharp_style_throw_expression = true
+dotnet_diagnostic.IDE0058.severity = none
+#Dick csharp_style_unused_value_assignment_preference = discard_variable
+#Dick charp_style_unused_value_expression_statement_preference = discard_variable
+
+# 'using' directive preferences
+csharp_using_directive_placement = outside_namespace
+
+# New line preferences
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
+csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
+csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
+csharp_style_allow_embedded_statements_on_same_line_experimental = true
+
+#### C# Formatting Rules ####
+
+# New line preferences
+csharp_new_line_before_catch = true
+csharp_new_line_before_else = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_open_brace = all
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_case_contents_when_block = true
+csharp_indent_labels = one_less_than_current
+csharp_indent_switch_labels = true
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
diff --git a/Finished sample/AbstractFactory/Implementation.cs b/Finished sample/AbstractFactory/Implementation.cs
index 6e71024..e0b27f4 100644
--- a/Finished sample/AbstractFactory/Implementation.cs
+++ b/Finished sample/AbstractFactory/Implementation.cs
@@ -1,118 +1,100 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace AbstractFactory;
-namespace AbstractFactory
+///
+/// AbstractFactory
+///
+public interface IShoppingCartPurchaseFactory
{
- ///
- /// AbstractFactory
- ///
- public interface IShoppingCartPurchaseFactory
- {
- IDiscountService CreateDiscountService();
- IShippingCostsService CreateShippingCostsService();
- }
-
- ///
- /// AbstractProduct
- ///
- public interface IDiscountService
- {
- int DiscountPercentage { get; }
- }
-
- ///
- /// ConcreteProduct
- ///
- public class BelgiumDiscountService : IDiscountService
- {
- public int DiscountPercentage => 20;
- }
+ IDiscountService CreateDiscountService();
+ IShippingCostsService CreateShippingCostsService();
+}
- ///
- /// ConcreteProduct
- ///
- public class FranceDiscountService : IDiscountService
- {
- public int DiscountPercentage => 10;
- }
+///
+/// AbstractProduct
+///
+public interface IDiscountService
+{
+ int DiscountPercentage { get; }
+}
- ///
- /// AbstractProduct
- ///
- public interface IShippingCostsService
- {
- decimal ShippingCosts { get; }
- }
+///
+/// ConcreteProduct
+///
+public class BelgiumDiscountService : IDiscountService
+{
+ public int DiscountPercentage => 20;
+}
- ///
- /// ConcreteProduct
- ///
- public class BelgiumShippingCostsService : IShippingCostsService
- {
- public decimal ShippingCosts => 20;
- }
+///
+/// ConcreteProduct
+///
+public class FranceDiscountService : IDiscountService
+{
+ public int DiscountPercentage => 10;
+}
- ///
- /// ConcreteProduct
- ///
- public class FranceShippingCostsService : IShippingCostsService
- {
- public decimal ShippingCosts => 25;
- }
+///
+/// AbstractProduct
+///
+public interface IShippingCostsService
+{
+ decimal ShippingCosts { get; }
+}
+///
+/// ConcreteProduct
+///
+public class BelgiumShippingCostsService : IShippingCostsService
+{
+ public decimal ShippingCosts => 20;
+}
- public class BelgiumShoppingCartPurchaseFactory : IShoppingCartPurchaseFactory
- {
- public IDiscountService CreateDiscountService()
- {
- return new BelgiumDiscountService();
- }
+///
+/// ConcreteProduct
+///
+public class FranceShippingCostsService : IShippingCostsService
+{
+ public decimal ShippingCosts => 25;
+}
- public IShippingCostsService CreateShippingCostsService()
- {
- return new BelgiumShippingCostsService();
- }
- }
+///
+/// ConcreteFactory
+///
+public class BelgiumShoppingCartPurchaseFactory : IShoppingCartPurchaseFactory
+{
+ public IDiscountService CreateDiscountService() => new BelgiumDiscountService();
+ public IShippingCostsService CreateShippingCostsService() => new BelgiumShippingCostsService();
+}
- public class FranceShoppingCartPurchaseFactory : IShoppingCartPurchaseFactory
- {
- public IDiscountService CreateDiscountService()
- {
- return new FranceDiscountService();
- }
+///
+/// ConcreteFactory
+///
+public class FranceShoppingCartPurchaseFactory : IShoppingCartPurchaseFactory
+{
+ public IDiscountService CreateDiscountService() => new FranceDiscountService();
- public IShippingCostsService CreateShippingCostsService()
- {
- return new FranceShippingCostsService();
- }
- }
+ public IShippingCostsService CreateShippingCostsService() => new FranceShippingCostsService();
+}
+///
+/// Client class
+///
+public class ShoppingCart
+{
+ readonly IDiscountService _discountService;
+ readonly IShippingCostsService _shippingCostsService;
+ readonly int _orderCosts;
- ///
- /// Client class
- ///
- public class ShoppingCart
+ // Constructor
+ public ShoppingCart(IShoppingCartPurchaseFactory factory)
{
- private readonly IDiscountService _discountService;
- private readonly IShippingCostsService _shippingCostsService;
- private int _orderCosts;
-
- // Constructor
- public ShoppingCart(IShoppingCartPurchaseFactory factory)
- {
- _discountService = factory.CreateDiscountService();
- _shippingCostsService = factory.CreateShippingCostsService();
- // assume that the total cost of all the items we ordered = 200 euro
- _orderCosts = 200;
- }
+ _discountService = factory.CreateDiscountService();
+ _shippingCostsService = factory.CreateShippingCostsService();
+ // assume that the total cost of all the items we ordered = 200 euro
+ _orderCosts = 200;
+ }
- public void CalculateCosts()
- {
- Console.WriteLine($"Total costs = {_orderCosts - (_orderCosts / 100 * _discountService.DiscountPercentage) + _shippingCostsService.ShippingCosts }");
- }
- }
+ public void CalculateCosts() => Console.WriteLine("Total costs = " +
+ $"{_orderCosts - _orderCosts / 100 * _discountService.DiscountPercentage + _shippingCostsService.ShippingCosts}");
}
diff --git a/Finished sample/AbstractFactory/Program.cs b/Finished sample/AbstractFactory/Program.cs
index db3730d..f88bd2a 100644
--- a/Finished sample/AbstractFactory/Program.cs
+++ b/Finished sample/AbstractFactory/Program.cs
@@ -1,5 +1,7 @@
using AbstractFactory;
+Console.Title = "Abstract Factory";
+
var belgiumShoppingCartPurchaseFactory = new BelgiumShoppingCartPurchaseFactory();
var shoppingCartForBelgium = new ShoppingCart(belgiumShoppingCartPurchaseFactory);
shoppingCartForBelgium.CalculateCosts();
@@ -7,5 +9,5 @@
var franceShoppingCartPurchaseFactory = new FranceShoppingCartPurchaseFactory();
var shoppingCartForFrance = new ShoppingCart(franceShoppingCartPurchaseFactory);
shoppingCartForFrance.CalculateCosts();
-
-Console.ReadKey();
\ No newline at end of file
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Adapter/ClassAdapterImplementation.cs b/Finished sample/Adapter/ClassAdapterImplementation.cs
index 89a61b4..c7d6c0b 100644
--- a/Finished sample/Adapter/ClassAdapterImplementation.cs
+++ b/Finished sample/Adapter/ClassAdapterImplementation.cs
@@ -1,70 +1,61 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace ClassAdapter;
-namespace Adapter.ClassAdapter
+public class CityFromExternalSystem
{
- public class CityFromExternalSystem
- {
- public string Name { get; private set; }
- public string NickName { get; private set; }
- public int Inhabitants { get; private set; }
-
- public CityFromExternalSystem(string name, string nickName, int inhabitants)
- {
- Name = name;
- NickName = nickName;
- Inhabitants = inhabitants;
- }
- }
+ public string Name { get; }
+ public string NickName { get; }
+ public int Inhabitants { get; }
- ///
- /// Adaptee
- ///
- public class ExternalSystem
+ public CityFromExternalSystem(string name, string nickName, int inhabitants)
{
- public CityFromExternalSystem GetCity()
- {
- return new CityFromExternalSystem("Antwerp", "'t Stad", 500000);
- }
+ Name = name;
+ NickName = nickName;
+ Inhabitants = inhabitants;
}
+}
- public class City
- {
- public string FullName { get; private set; }
- public long Inhabitants { get; private set; }
+///
+/// Adaptee
+///
+public class ExternalSystem
+{
+ public CityFromExternalSystem GetCity() =>
+ new("Antwerp", "'t Stad", 500000);
+}
- public City(string fullName, long inhabitants)
- {
- FullName = fullName;
- Inhabitants = inhabitants;
- }
- }
+public class City
+{
+ public string FullName { get; }
+ public long Inhabitants { get; }
- ///
- /// Target
- ///
- public interface ICityAdapter
+ public City(string fullName, long inhabitants)
{
- City GetCity();
+ FullName = fullName;
+ Inhabitants = inhabitants;
}
+}
- ///
- /// Adapter
- ///
- public class CityAdapter : ExternalSystem, ICityAdapter
- {
- public City GetCity()
- {
- // call into the external system
- var cityFromExternalSystem = base.GetCity();
+///
+/// Target
+///
+public interface ICityAdapter
+{
+ City GetCity();
+}
+
+///
+/// Adapter
+///
+public class CityAdapter : ExternalSystem, ICityAdapter
+{
+ public new City GetCity()
+ {
+ // call into the external system
+ CityFromExternalSystem cityFromExternalSystem = base.GetCity();
- // adapt the CityFromExternalCity to a City
- return new City(
- $"{cityFromExternalSystem.Name} - {cityFromExternalSystem.NickName}"
- , cityFromExternalSystem.Inhabitants);
- }
+ // adapt the CityFromExternalCity to a City
+ return new City(
+ $"{cityFromExternalSystem.Name} - {cityFromExternalSystem.NickName}"
+ , cityFromExternalSystem.Inhabitants);
}
}
diff --git a/Finished sample/Adapter/ObjectAdapterImplementation.cs b/Finished sample/Adapter/ObjectAdapterImplementation.cs
index 9b12393..7d6877c 100644
--- a/Finished sample/Adapter/ObjectAdapterImplementation.cs
+++ b/Finished sample/Adapter/ObjectAdapterImplementation.cs
@@ -1,75 +1,66 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Adapter;
-namespace Adapter.ObjectAdapter
+public class CityFromExternalSystem
{
- public class CityFromExternalSystem
- {
- public string Name { get; private set; }
- public string NickName { get; private set; }
- public int Inhabitants { get; private set; }
-
- public CityFromExternalSystem(
- string name,
- string nickName,
- int inhabitants)
- {
- Name = name;
- NickName = nickName;
- Inhabitants = inhabitants;
- }
- }
+ public string Name { get; }
+ public string NickName { get; }
+ public int Inhabitants { get; }
- ///
- /// Adaptee
- ///
- public class ExternalSystem
+ public CityFromExternalSystem(
+ string name,
+ string nickName,
+ int inhabitants)
{
- public CityFromExternalSystem GetCity()
- {
- return new CityFromExternalSystem("Antwerp", "'t Stad", 500000);
- }
+ Name = name;
+ NickName = nickName;
+ Inhabitants = inhabitants;
}
+}
- public class City
- {
- public string FullName { get; private set; }
- public long Inhabitants { get; private set; }
+///
+/// Adaptee
+///
+public class ExternalSystem
+{
+ public CityFromExternalSystem GetCity() =>
+ new("Antwerp", "'t Stad", 500000);
+}
- public City(string fullName, long inhabitants)
- {
- FullName = fullName;
- Inhabitants = inhabitants;
- }
- }
+public class City
+{
+ public string FullName { get; }
+ public long Inhabitants { get; }
- ///
- /// Target
- ///
- public interface ICityAdapter
+ public City(string fullName, long inhabitants)
{
- City GetCity();
+ FullName = fullName;
+ Inhabitants = inhabitants;
}
+}
- ///
- /// Adapter
- ///
- public class CityAdapter : ICityAdapter
- {
- public ExternalSystem ExternalSystem { get; private set; } = new();
+///
+/// Target
+///
+public interface ICityAdapter
+{
+ City GetCity();
+}
- public City GetCity()
- {
- // call into the external system
- var cityFromExternalSystem = ExternalSystem.GetCity();
+///
+/// Adapter
+///
+public class CityAdapter : ICityAdapter
+{
+ public ExternalSystem ExternalSystem { get; } = new();
+
+ public City GetCity()
+ {
+ // call into the external system
+ CityFromExternalSystem cityFromExternalSystem = ExternalSystem.GetCity();
- // adapt the CityFromExternalCity to a City
- return new City(
- $"{cityFromExternalSystem.Name} - {cityFromExternalSystem.NickName}"
- , cityFromExternalSystem.Inhabitants);
- }
- }
+ // adapt the CityFromExternalCity to a City
+ return new City(
+ $"{cityFromExternalSystem.Name} - {cityFromExternalSystem.NickName}"
+ , cityFromExternalSystem.Inhabitants);
+ }
}
diff --git a/Finished sample/Adapter/Program.cs b/Finished sample/Adapter/Program.cs
index 367335c..0142bda 100644
--- a/Finished sample/Adapter/Program.cs
+++ b/Finished sample/Adapter/Program.cs
@@ -1,9 +1,10 @@
-using Adapter;
-using Adapter.ClassAdapter;
+using ClassAdapter;
+
+Console.Title = "Adapter";
// adapter example (same code for object & class adapter)
ICityAdapter adapter = new CityAdapter();
-var city = adapter.GetCity();
+City city = adapter.GetCity();
Console.WriteLine($"{city.FullName}, {city.Inhabitants}");
-Console.ReadKey();
\ No newline at end of file
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Bridge/Implementation.cs b/Finished sample/Bridge/Implementation.cs
index 1803397..1674585 100644
--- a/Finished sample/Bridge/Implementation.cs
+++ b/Finished sample/Bridge/Implementation.cs
@@ -1,85 +1,65 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Bridge;
-namespace Bridge
+///
+/// Abstraction
+///
+public abstract class Menu
{
- ///
- /// Abstraction
- ///
- public abstract class Menu
- {
- public readonly ICoupon _coupon;
- public abstract int CalculatePrice();
-
- public Menu(ICoupon coupon)
- {
- _coupon = coupon;
- }
- }
-
-
- ///
- /// RefinedAbstraction
- ///
- public class VegetarianMenu : Menu
- {
- public VegetarianMenu(ICoupon coupon): base(coupon)
- {
- }
- public override int CalculatePrice()
- {
- return 20 - _coupon.CouponValue;
- }
- }
+ public readonly ICoupon _coupon = null!;
+ public abstract int CalculatePrice();
+ protected Menu(ICoupon coupon) => _coupon = coupon;
+}
- ///
- /// RefinedAbstraction
- ///
- public class MeatBasedMenu : Menu
+///
+/// RefinedAbstraction
+///
+public class VegetarianMenu : Menu
+{
+ public VegetarianMenu(ICoupon coupon) : base(coupon)
{
- public MeatBasedMenu(ICoupon coupon) : base(coupon)
- {
- }
- public override int CalculatePrice()
- {
- return 30 - _coupon.CouponValue;
- }
}
+ public override int CalculatePrice() => 20 - _coupon.CouponValue;
+}
-
- ///
- /// Implementor
- ///
- public interface ICoupon
+///
+/// RefinedAbstraction
+///
+public class MeatBasedMenu : Menu
+{
+ public MeatBasedMenu(ICoupon coupon) : base(coupon)
{
- int CouponValue { get; }
}
+ public override int CalculatePrice() => 30 - _coupon.CouponValue;
+}
+///
+/// Implementor
+///
+public interface ICoupon
+{
+ int CouponValue { get; }
+}
- ///
- /// ConcreteImplementor
- ///
- public class NoCoupon : ICoupon
- {
- public int CouponValue { get => 0; }
- }
+///
+/// ConcreteImplementor
+///
+public class NoCoupon : ICoupon
+{
+ public int CouponValue => 0;
+}
- ///
- /// ConcreteImplementor
- ///
- public class OneEuroCoupon : ICoupon
- {
- public int CouponValue { get => 1; }
- }
+///
+/// ConcreteImplementor
+///
+public class OneEuroCoupon : ICoupon
+{
+ public int CouponValue => 1;
+}
- ///
- /// ConcreteImplementor
- ///
- public class TwoEuroCoupon : ICoupon
- {
- public int CouponValue { get => 2; }
- }
+///
+/// ConcreteImplementor
+///
+public class TwoEuroCoupon : ICoupon
+{
+ public int CouponValue => 2;
}
\ No newline at end of file
diff --git a/Finished sample/Bridge/Program.cs b/Finished sample/Bridge/Program.cs
index beb8ebd..ac2a862 100644
--- a/Finished sample/Bridge/Program.cs
+++ b/Finished sample/Bridge/Program.cs
@@ -1,6 +1,6 @@
-// create a menu implementation
+using Bridge;
-using Bridge;
+Console.Title = "Bridge";
var noCoupon = new NoCoupon();
var oneEuroCoupon = new OneEuroCoupon();
@@ -16,5 +16,5 @@
vegetarianMenu = new VegetarianMenu(oneEuroCoupon);
Console.WriteLine($"Vegetarian menu, one euro coupon: {vegetarianMenu.CalculatePrice()} euro.");
-
+
Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Builder/Implementation.cs b/Finished sample/Builder/Implementation.cs
index 1aae5a5..18a4dd0 100644
--- a/Finished sample/Builder/Implementation.cs
+++ b/Finished sample/Builder/Implementation.cs
@@ -1,216 +1,97 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Text;
-namespace BuilderPattern
-{
+namespace BuilderPattern;
+///
+/// Product
+///
+public class Car
+{
+ readonly List _parts = new();
+ readonly string _carType;
- ///
- /// Director
- ///
- public class Garage
- {
- private CarBuilder? _builder;
-
- public Garage()
- {
- }
+ public Car(string carType) => _carType = carType;
- public void Construct(CarBuilder builder)
- {
- _builder = builder;
-
- _builder.BuildEngine();
- _builder.BuildFrame();
- }
+ public void AddPart(string part) => _parts.Add(part);
- // variation: the show method on the director instead of on the product.
- public void Show()
- {
- Console.WriteLine(_builder?.Car.ToString());
- }
- }
-
- ///
- /// Builder abstract class
- ///
- public abstract class CarBuilder
+ public override string ToString()
{
- public Car Car { get; private set; }
-
- public CarBuilder(string carType)
- {
- Car = new Car(carType);
- }
- public abstract void BuildEngine();
- public abstract void BuildFrame();
- }
-
- ///
- /// ConcreteBuilder1 class
- ///
- public class MiniBuilder : CarBuilder
- {
- public MiniBuilder()
- : base("Mini")
+ var sb = new StringBuilder();
+ foreach (var part in _parts)
{
+ sb.Append("Car of type ")
+ .Append(_carType)
+ .Append(" has part ")
+ .Append(part)
+ .Append(". ");
}
- public override void BuildEngine()
- {
- Car.AddPart("'not a V8'");
- }
-
- public override void BuildFrame()
- {
- Car.AddPart("'3-door with stripes'");
- }
+ return sb.ToString();
}
+}
- ///
- /// ConcreteBuilder2 class
- ///
- public class BMWBuilder : CarBuilder
- {
- // Invoke base class constructor
- public BMWBuilder()
- : base("BMW")
- {
- }
+///
+/// Builder
+///
+public abstract class CarBuilder
+{
+ public Car Car { get; }
- public override void BuildEngine()
- {
- Car.AddPart("'a fancy V8 engine'");
- }
+ protected CarBuilder(string carType) => Car = new Car(carType);
- public override void BuildFrame()
- {
- Car.AddPart("'5-door with metallic finish'");
- }
- }
-
+ public abstract void BuildEngine();
+ public abstract void BuildFrame();
+}
- ///
- /// Product class
- ///
- public class Car
+///
+/// ConcreteBuilder1 class
+///
+public class MiniBuilder : CarBuilder
+{
+ public MiniBuilder()
+ : base("Mini")
{
- private readonly List _parts = new();
- private readonly string _carType;
-
- public Car(string carType)
- {
- _carType = carType;
- }
-
- public void AddPart(string part)
- {
- _parts.Add(part);
- }
-
- public override string ToString()
- {
- var sb = new StringBuilder();
- foreach (string part in _parts)
- {
- sb.Append($"Car of type {_carType} has part {part}. ");
- }
-
- return sb.ToString();
- }
- }
-
+ }
+ public override void BuildEngine() => Car.AddPart("'not a V8'");
- ///
- /// The 'Director' class
- ///
- public class Director
- {
- // Builder uses a complex series of steps
- public void Construct(Builder builder)
- {
- builder.BuildPartA();
- builder.BuildPartB();
- }
- }
+ public override void BuildFrame() => Car.AddPart("'3-door with stripes'");
+}
- ///
- /// The 'Builder' abstract class
- ///
- public abstract class Builder
+///
+/// ConcreteBuilder2 class
+///
+public class BMWBuilder : CarBuilder
+{
+ // Invoke base class constructor
+ public BMWBuilder()
+ : base("BMW")
{
- public abstract void BuildPartA();
- public abstract void BuildPartB();
- public abstract Product GetResult();
}
- ///
- /// The 'ConcreteBuilder1' class
- ///
- public class ConcreteBuilder1 : Builder
- {
- private Product product = new Product();
-
- public override void BuildPartA()
- {
- product.Add("PartA");
- }
+ public override void BuildEngine() => Car.AddPart("'a fancy V8 engine'");
- public override void BuildPartB()
- {
- product.Add("PartB");
- }
+ public override void BuildFrame() => Car.AddPart("'5-door with metallic finish'");
+}
- public override Product GetResult()
- {
- return product;
- }
- }
+///
+/// Director
+///
+public class Garage
+{
+ CarBuilder? _builder;
- ///
- /// The 'ConcreteBuilder2' class
- ///
- public class ConcreteBuilder2 : Builder
+ public Garage()
{
- private Product product = new Product();
-
- public override void BuildPartA()
- {
- product.Add("PartX");
- }
-
- public override void BuildPartB()
- {
- product.Add("PartY");
- }
-
- public override Product GetResult()
- {
- return product;
- }
}
- ///
- /// The 'Product' class
- ///
- public class Product
+ public void Construct(CarBuilder builder)
{
- private List parts = new List();
+ _builder = builder;
- public void Add(string part)
- {
- parts.Add(part);
- }
-
- public void Show()
- {
- Console.WriteLine("\nProduct Parts -------");
- foreach (string part in parts)
- Console.WriteLine(part);
- }
+ _builder.BuildEngine();
+ _builder.BuildFrame();
}
+
+ public void Show() => Console.WriteLine(_builder?.Car.ToString());
}
diff --git a/Finished sample/Builder/Program.cs b/Finished sample/Builder/Program.cs
index 47802f5..2a5ce85 100644
--- a/Finished sample/Builder/Program.cs
+++ b/Finished sample/Builder/Program.cs
@@ -1,22 +1,6 @@
using BuilderPattern;
-
-//Director director = new Director();
-
-//Builder b1 = new ConcreteBuilder1();
-//Builder b2 = new ConcreteBuilder2();
-
-//// Construct two products
-//director.Construct(b1);
-//Product p1 = b1.GetResult();
-//p1.Show();
-
-//director.Construct(b2);
-//Product p2 = b2.GetResult();
-//p2.Show();
-
-
-
+Console.Title = "Builder";
var garage = new Garage();
@@ -32,5 +16,5 @@
Console.WriteLine(bmwBuilder.Car.ToString());
// or:
garage.Show();
-
+
Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/ChainOfResponsibility/Implementation.cs b/Finished sample/ChainOfResponsibility/Implementation.cs
index 9f76837..35e38bf 100644
--- a/Finished sample/ChainOfResponsibility/Implementation.cs
+++ b/Finished sample/ChainOfResponsibility/Implementation.cs
@@ -1,149 +1,148 @@
using System.ComponentModel.DataAnnotations;
-namespace ChainOfResponsibility
+namespace ChainOfResponsibility;
+
+public class Document
{
- public class Document
+ public string Title { get; set; }
+ public DateTimeOffset LastModified { get; set; }
+ public bool ApprovedByLitigation { get; set; }
+ public bool ApprovedByManagement { get; set; }
+
+ public Document(
+ string title,
+ DateTimeOffset lastModified,
+ bool approvedByLitigation,
+ bool approvedByManagement)
{
- public string Title { get; set; }
- public DateTimeOffset LastModified { get; set; }
- public bool ApprovedByLitigation { get; set; }
- public bool ApprovedByManagement { get; set; }
-
- public Document(
- string title,
- DateTimeOffset lastModified,
- bool approvedByLitigation,
- bool approvedByManagement)
- {
- Title = title;
- LastModified = lastModified;
- ApprovedByLitigation = approvedByLitigation;
- ApprovedByManagement = approvedByManagement;
- }
+ Title = title;
+ LastModified = lastModified;
+ ApprovedByLitigation = approvedByLitigation;
+ ApprovedByManagement = approvedByManagement;
}
+}
- ///
- /// Handler
- ///
- public interface IHandler where T : class
- {
- IHandler SetSuccessor(IHandler successor);
- void Handle(T request);
- }
+///
+/// Handler
+///
+public interface IHandler where T : class
+{
+ IHandler SetSuccessor(IHandler successor);
+ void Handle(T request);
+}
+
+///
+/// ConcreteHandler
+///
+public class DocumentTitleHandler : IHandler
+{
+ IHandler? _successor;
- ///
- /// ConcreteHandler
- ///
- public class DocumentTitleHandler : IHandler
+ public void Handle(Document document)
{
- private IHandler? _successor;
-
- public void Handle(Document document)
+ if (document.Title.Length == 0)
{
- if (document.Title == string.Empty)
- {
- // validation doesn't check out
- throw new ValidationException(
- new ValidationResult(
- "Title must be filled out",
- new List() { "Title" }), null, null);
- }
-
- // go to the next handler
- _successor?.Handle(document);
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Title must be filled out",
+ new List() { "Title" }), null, null);
}
- public IHandler SetSuccessor(IHandler successor)
- {
- _successor = successor;
- return successor;
- }
+ // go to the next handler
+ _successor?.Handle(document);
}
- ///
- /// ConcreteHandler
- ///
- public class DocumentLastModifiedHandler : IHandler
+ public IHandler SetSuccessor(IHandler successor)
{
- private IHandler? _successor;
+ _successor = successor;
+ return successor;
+ }
+}
- public void Handle(Document document)
- {
- if (document.LastModified < DateTime.UtcNow.AddDays(-30))
- {
- // validation doesn't check out
- throw new ValidationException(
- new ValidationResult(
- "Document must be modified in the last 30 days",
- new List() { "LastModified" }), null, null);
- }
-
- // go to the next handler
- _successor?.Handle(document);
- }
+///
+/// ConcreteHandler
+///
+public class DocumentLastModifiedHandler : IHandler
+{
+ IHandler? _successor;
- public IHandler SetSuccessor(IHandler successor)
+ public void Handle(Document document)
+ {
+ if (document.LastModified < DateTime.UtcNow.AddDays(-30))
{
- _successor = successor;
- return successor;
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Document must be modified in the last 30 days",
+ new List() { "LastModified" }), null, null);
}
+
+ // go to the next handler
+ _successor?.Handle(document);
}
- ///
- /// ConcreteHandler
- ///
- public class DocumentApprovedByLitigationHandler : IHandler
+ public IHandler SetSuccessor(IHandler successor)
{
- private IHandler? _successor;
+ _successor = successor;
+ return successor;
+ }
+}
- public void Handle(Document document)
- {
- if (!document.ApprovedByLitigation)
- {
- // validation doesn't check out
- throw new ValidationException(
- new ValidationResult(
- "Document must be approved by litigation",
- new List() { "ApprovedByLitigation" }), null, null);
- }
-
- // go to the next handler
- _successor?.Handle(document);
- }
+///
+/// ConcreteHandler
+///
+public class DocumentApprovedByLitigationHandler : IHandler
+{
+ IHandler? _successor;
- public IHandler SetSuccessor(IHandler successor)
+ public void Handle(Document document)
+ {
+ if (!document.ApprovedByLitigation)
{
- _successor = successor;
- return successor;
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Document must be approved by litigation",
+ new List() { "ApprovedByLitigation" }), null, null);
}
+
+ // go to the next handler
+ _successor?.Handle(document);
}
- ///
- /// ConcreteHandler
- ///
- public class DocumentApprovedByManagementHandler : IHandler
+ public IHandler SetSuccessor(IHandler successor)
{
- private IHandler? _successor;
+ _successor = successor;
+ return successor;
+ }
+}
- public void Handle(Document document)
- {
- if (!document.ApprovedByManagement)
- {
- // validation doesn't check out
- throw new ValidationException(
- new ValidationResult(
- "Document must be approved by management",
- new List() { "ApprovedByManagement" }), null, null);
- }
-
- // go to the next handler
- _successor?.Handle(document);
- }
+///
+/// ConcreteHandler
+///
+public class DocumentApprovedByManagementHandler : IHandler
+{
+ IHandler? _successor;
- public IHandler SetSuccessor(IHandler successor)
+ public void Handle(Document document)
+ {
+ if (!document.ApprovedByManagement)
{
- _successor = successor;
- return successor;
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Document must be approved by management",
+ new List() { "ApprovedByManagement" }), null, null);
}
+
+ // go to the next handler
+ _successor?.Handle(document);
+ }
+
+ public IHandler SetSuccessor(IHandler successor)
+ {
+ _successor = successor;
+ return successor;
}
}
\ No newline at end of file
diff --git a/Finished sample/ChainOfResponsibility/Implementation.cs.bak b/Finished sample/ChainOfResponsibility/Implementation.cs.bak
new file mode 100644
index 0000000..200818b
--- /dev/null
+++ b/Finished sample/ChainOfResponsibility/Implementation.cs.bak
@@ -0,0 +1,148 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace ChainOfResponsibility;
+
+public class Document
+{
+ public string Title { get; set; }
+ public DateTimeOffset LastModified { get; set; }
+ public bool ApprovedByLitigation { get; set; }
+ public bool ApprovedByManagement { get; set; }
+
+ public Document(
+ string title,
+ DateTimeOffset lastModified,
+ bool approvedByLitigation,
+ bool approvedByManagement)
+ {
+ Title = title;
+ LastModified = lastModified;
+ ApprovedByLitigation = approvedByLitigation;
+ ApprovedByManagement = approvedByManagement;
+ }
+}
+
+///
+/// Handler
+///
+public interface IHandler where T : class
+{
+ IHandler SetSuccessor(IHandler successor);
+ void Handle(T request);
+}
+
+///
+/// ConcreteHandler
+///
+public class DocumentTitleHandler : IHandler
+{
+ IHandler? _successor;
+
+ public void Handle(Document document)
+ {
+ if (document.Title?.Length == 0)
+ {
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Title must be filled out",
+ new List() { "Title" }), null, null);
+ }
+
+ // go to the next handler
+ _successor?.Handle(document);
+ }
+
+ public IHandler SetSuccessor(IHandler successor)
+ {
+ _successor = successor;
+ return successor;
+ }
+}
+
+///
+/// ConcreteHandler
+///
+public class DocumentLastModifiedHandler : IHandler
+{
+ IHandler? _successor;
+
+ public void Handle(Document document)
+ {
+ if (document.LastModified < DateTime.UtcNow.AddDays(-30))
+ {
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Document must be modified in the last 30 days",
+ new List() { "LastModified" }), null, null);
+ }
+
+ // go to the next handler
+ _successor?.Handle(document);
+ }
+
+ public IHandler SetSuccessor(IHandler successor)
+ {
+ _successor = successor;
+ return successor;
+ }
+}
+
+///
+/// ConcreteHandler
+///
+public class DocumentApprovedByLitigationHandler : IHandler
+{
+ IHandler? _successor;
+
+ public void Handle(Document document)
+ {
+ if (!document.ApprovedByLitigation)
+ {
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Document must be approved by litigation",
+ new List() { "ApprovedByLitigation" }), null, null);
+ }
+
+ // go to the next handler
+ _successor?.Handle(document);
+ }
+
+ public IHandler SetSuccessor(IHandler successor)
+ {
+ _successor = successor;
+ return successor;
+ }
+}
+
+///
+/// ConcreteHandler
+///
+public class DocumentApprovedByManagementHandler : IHandler
+{
+ IHandler? _successor;
+
+ public void Handle(Document document)
+ {
+ if (!document.ApprovedByManagement)
+ {
+ // validation doesn't check out
+ throw new ValidationException(
+ new ValidationResult(
+ "Document must be approved by management",
+ new List() { "ApprovedByManagement" }), null, null);
+ }
+
+ // go to the next handler
+ _successor?.Handle(document);
+ }
+
+ public IHandler SetSuccessor(IHandler successor)
+ {
+ _successor = successor;
+ return successor;
+ }
+}
\ No newline at end of file
diff --git a/Finished sample/ChainOfResponsibility/Program.cs b/Finished sample/ChainOfResponsibility/Program.cs
index 63a62fb..4964c64 100644
--- a/Finished sample/ChainOfResponsibility/Program.cs
+++ b/Finished sample/ChainOfResponsibility/Program.cs
@@ -1,12 +1,13 @@
-using ChainOfResponsibility;
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
+using ChainOfResponsibility;
-var validDocument = new Document("How to Avoid Java Development",
+Console.Title = "Chain of Responsibility";
+
+var validDocument = new Document("How to Avoid Java Development",
DateTimeOffset.UtcNow, true, true);
-var invalidDocument = new Document("How to Avoid Java Development",
+var invalidDocument = new Document("How to Avoid Java Development",
DateTimeOffset.UtcNow, false, true);
-// chain a set of handlers
var documentHandlerChain = new DocumentTitleHandler();
documentHandlerChain
.SetSuccessor(new DocumentLastModifiedHandler())
@@ -23,4 +24,6 @@
catch (ValidationException validationException)
{
Console.WriteLine(validationException.Message);
-}
\ No newline at end of file
+}
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Command/Implementation.cs b/Finished sample/Command/Implementation.cs
index f4d303e..e5b42bd 100644
--- a/Finished sample/Command/Implementation.cs
+++ b/Finished sample/Command/Implementation.cs
@@ -1,198 +1,178 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Command;
-namespace Command
+public class Employee
{
- ///
- /// ICommand
- ///
- public interface ICommand
+ public int Id { get; set; }
+ public string Name { get; set; }
+
+ public Employee(int id, string name)
{
- void Execute();
- bool CanExecute();
- void Undo();
+ Id = id;
+ Name = name;
}
-
- ///
- /// ConcreteCommand
- ///
- public class AddEmployeeToManagerList : ICommand
+}
+public class Manager : Employee
+{
+ public List Employees = new();
+ public Manager(int id, string name)
+ : base(id, name)
{
- private readonly IEmployeeManagerRepository _employeeManagerRepository;
- private readonly int _managerId;
- private readonly Employee? _employee;
-
- public AddEmployeeToManagerList(
- IEmployeeManagerRepository employeeManagerRepository,
- int managerId,
- Employee? employee)
- {
- _employeeManagerRepository = employeeManagerRepository;
- _managerId = managerId;
- _employee = employee;
- }
+ }
+}
- public bool CanExecute()
- {
- // potentially check against business/technical rules that might block execution
+///
+/// Receiver (interface)
+///
+public interface IEmployeeManagerRepository
+{
+ void AddEmployee(int managerId, Employee employee);
+ void RemoveEmployee(int managerId, Employee employee);
+ bool HasEmployee(int managerId, int employeeId);
+ void WriteDataStore();
+}
+
+///
+/// Receiver (implementation)
+///
+public class EmployeeManagerRepository : IEmployeeManagerRepository
+{
+ // for demo purposes, use an in-memory datastore as a fake "manager list"
+ readonly List _managers = new()
+ { new Manager(1, "Katie"), new Manager(2, "Geoff") };
- // employee shouldn't be null
- if (_employee == null)
- {
- return false;
- }
+ public void AddEmployee(int managerId, Employee employee) =>
+ // in real-life, add additional input & error checks
+ _managers.First(m => m.Id == managerId).Employees.Add(employee);
- // employee shouldn't be on the manager's list already
- if (_employeeManagerRepository.HasEmployee(_managerId, _employee.Id))
- {
- return false;
- }
+ public void RemoveEmployee(int managerId, Employee employee) =>
+ // in real-life, add additional input & error checks
+ _managers.First(m => m.Id == managerId).Employees.Remove(employee);
- // other potential rule(s): ensure that an employee can only be added to
- // one manager's list at the same time, etc.
- return true;
- }
+ public bool HasEmployee(int managerId, int employeeId) =>
+ // in real-life, add additional input & error checks
+ _managers.First(m => m.Id == managerId)
+ .Employees.Any(e => e.Id == employeeId);
- public void Execute()
+ ///
+ /// For demo purposes, write out the data store to the console window
+ ///
+ public void WriteDataStore()
+ {
+ foreach (Manager manager in _managers)
{
- if (_employee == null)
+ Console.WriteLine($"Manager {manager.Id}, {manager.Name}");
+ if (manager.Employees.Any())
{
- return;
+ foreach (Employee employee in manager.Employees)
+ {
+ Console.WriteLine($"\t Employee {employee.Id}, {employee.Name}");
+ }
}
-
- _employeeManagerRepository.AddEmployee(_managerId, _employee);
- }
-
- public void Undo()
- {
- if (_employee == null)
+ else
{
- return;
+ Console.WriteLine("\t No employees.");
}
-
- _employeeManagerRepository.RemoveEmployee(_managerId, _employee);
}
}
+}
- ///
- /// Invoker
- ///
- public class CommandManager
+///
+/// Command
+///
+public interface ICommand
+{
+ void Execute();
+ bool CanExecute();
+ void Undo();
+}
+
+///
+/// ConcreteCommand
+///
+public class AddEmployeeToManagerList : ICommand
+{
+ readonly IEmployeeManagerRepository _employeeManagerRepository;
+ readonly int _managerId;
+ readonly Employee? _employee;
+
+ public AddEmployeeToManagerList(
+ IEmployeeManagerRepository employeeManagerRepository,
+ int managerId,
+ Employee? employee)
{
- private readonly Stack _commands = new Stack();
+ _employeeManagerRepository = employeeManagerRepository;
+ _managerId = managerId;
+ _employee = employee;
+ }
- public void Invoke(ICommand command)
+ public bool CanExecute()
+ {
+ // employee shouldn't be null
+ if (_employee == null)
{
- if (command.CanExecute())
- {
- command.Execute();
- _commands.Push(command);
- }
+ return false;
}
- public void Undo()
+ // employee shouldn't be on the manager's list already
+ if (_employeeManagerRepository.HasEmployee(_managerId, _employee.Id))
{
- if (_commands.Any())
- {
- _commands.Pop()?.Undo();
- }
+ return false;
}
- public void UndoAll()
- {
- while (_commands.Any())
- {
- _commands.Pop()?.Undo();
- }
- }
+ // other potential rule(s): ensure that an employee can only be added to
+ // one manager's list at the same time, etc.
+ return true;
}
-
-
- public class Employee
+ public void Execute()
{
- public int Id { get; set; }
- public string Name { get; set; }
-
- public Employee(int id, string name)
+ if (_employee == null)
{
- Id = id;
- Name = name;
+ return;
}
+ _employeeManagerRepository.AddEmployee(_managerId, _employee);
}
- public class Manager : Employee
+ public void Undo()
{
- public List Employees = new();
- public Manager(int id, string name)
- : base(id, name)
+ if (_employee == null)
{
+ return;
}
- }
- ///
- /// Receiver (interface)
- ///
- public interface IEmployeeManagerRepository
- {
- void AddEmployee(int managerId, Employee employee);
- void RemoveEmployee(int managerId, Employee employee);
- bool HasEmployee(int managerId, int employeeId);
- void WriteDataStore();
+ _employeeManagerRepository.RemoveEmployee(_managerId, _employee);
}
+}
- ///
- /// Receiver (implementation)
- ///
- public class EmployeeManagerRepository : IEmployeeManagerRepository
- {
- // for demo purposes, use an in-memory datastore as a fake "manager list"
- private List _managers = new List()
- { new Manager(1, "Katie"), new Manager(2, "Geoff") };
-
- public void AddEmployee(int managerId, Employee employee)
- {
- // in real-life, add additional input & error checks
- _managers.First(m => m.Id == managerId).Employees.Add(employee);
- }
+///
+/// Invoker
+///
+public class CommandManager
+{
+ readonly Stack _commands = new();
- public void RemoveEmployee(int managerId, Employee employee)
+ public void Invoke(ICommand command)
+ {
+ if (command.CanExecute())
{
- // in real-life, add additional input & error checks
- _managers.First(m => m.Id == managerId).Employees.Remove(employee);
+ command.Execute();
+ _commands.Push(command);
}
+ }
- public bool HasEmployee(int managerId, int employeeId)
+ public void Undo()
+ {
+ if (_commands.TryPop(out ICommand? cmd))
{
- // in real-life, add additional input & error checks
- return _managers.First(m => m.Id == managerId).Employees.Any(e => e.Id == employeeId);
+ cmd.Undo();
}
+ }
-
- ///
- /// For demo purposes, write out the data store to the console window
- ///
- public void WriteDataStore()
+ public void UndoAll()
+ {
+ while (_commands.TryPop(out ICommand? cmd))
{
- foreach (var manager in _managers)
- {
- Console.WriteLine($"Manager {manager.Id}, {manager.Name}");
- if (manager.Employees.Any())
- {
- foreach (var employee in manager.Employees)
- {
- Console.WriteLine($"\t Employee {employee.Id}, {employee.Name}");
- }
- }
- else
- {
- Console.WriteLine($"\t No employees.");
- }
- }
- Console.WriteLine();
+ cmd.Undo();
}
}
-}
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/Finished sample/Command/Program.cs b/Finished sample/Command/Program.cs
index e0cbdd9..6b18a31 100644
--- a/Finished sample/Command/Program.cs
+++ b/Finished sample/Command/Program.cs
@@ -1,24 +1,31 @@
using Command;
-CommandManager commandManager = new ();
-IEmployeeManagerRepository repository = new EmployeeManagerRepository();
+Console.Title = "Command";
+CommandManager commandManager = new();
+IEmployeeManagerRepository repository = new EmployeeManagerRepository();
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 1, new Employee(111, "Kevin")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 1, new Employee(111, "Kevin")));
repository.WriteDataStore();
commandManager.Undo();
repository.WriteDataStore();
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 1, new Employee(222, "Clara")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 1, new Employee(222, "Clara")));
repository.WriteDataStore();
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
repository.WriteDataStore();
// try adding the same employee again
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
repository.WriteDataStore();
commandManager.UndoAll();
-repository.WriteDataStore();
\ No newline at end of file
+repository.WriteDataStore();
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Composite/Implementation.cs b/Finished sample/Composite/Implementation.cs
index 67885b3..ec60052 100644
--- a/Finished sample/Composite/Implementation.cs
+++ b/Finished sample/Composite/Implementation.cs
@@ -1,77 +1,49 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Composite;
-namespace Composite
+///
+/// Component
+///
+public abstract class FileSystemItem
{
- ///
- /// Component
- ///
- public abstract class FileSystemItem
- {
- public string Name { get; set; }
-
- public abstract long GetSize();
+ public string Name { get; set; }
- public FileSystemItem(string name)
- {
- Name = name;
- }
- }
+ public abstract long GetSize();
+ protected FileSystemItem(string name) => Name = name;
+}
- ///
- /// Leaf
- ///
- public class File : FileSystemItem
- {
- private long _size;
- public File(string name, long size) : base(name)
- {
- _size = size;
- }
+///
+/// Leaf
+///
+public class File : FileSystemItem
+{
+ readonly long _size;
+ public File(string name, long size) : base(name) => _size = size;
- public override long GetSize()
- {
- return _size;
- }
- }
+ public override long GetSize() => _size;
+}
- ///
- /// Composite
- ///
- public class Directory : FileSystemItem
- {
- private long _size;
- private List _fileSystemItems { get; set; } = new List();
-
- public Directory(string name, long size) : base(name)
- {
- _size = size;
- }
+///
+/// Composite
+///
+public class Directory : FileSystemItem
+{
+ readonly List _fileSystemItems = new();
- public void Add(FileSystemItem itemToAdd)
- {
- _fileSystemItems.Add(itemToAdd);
- }
+ readonly long _size;
+ public Directory(string name, long size) : base(name) => _size = size;
- public void Remove(FileSystemItem itemToRemove)
- {
- _fileSystemItems.Remove(itemToRemove);
- }
+ public void Add(FileSystemItem itemToAdd) => _fileSystemItems.Add(itemToAdd);
+
+ public void Remove(FileSystemItem itemToRemove) => _fileSystemItems.Remove(itemToRemove);
- public override long GetSize()
+ public override long GetSize()
+ {
+ var treeSize = _size;
+ foreach (FileSystemItem fileSystemItem in _fileSystemItems)
{
- var treeSize = _size;
- foreach (var fileSystemItem in _fileSystemItems)
- {
- treeSize += fileSystemItem.GetSize();
- }
- return treeSize;
+ treeSize += fileSystemItem.GetSize();
}
+ return treeSize;
}
-
-
}
diff --git a/Finished sample/Composite/Program.cs b/Finished sample/Composite/Program.cs
index 810f95f..722327f 100644
--- a/Finished sample/Composite/Program.cs
+++ b/Finished sample/Composite/Program.cs
@@ -1,4 +1,6 @@
-var root = new Composite.Directory("root", 0);
+Console.Title = "Composite";
+
+var root = new Composite.Directory("root", 0);
var topLevelFile = new Composite.File("toplevel.txt", 100);
var topLevelDirectory1 = new Composite.Directory("topleveldirectory1", 4);
var topLevelDirectory2 = new Composite.Directory("topleveldirectory2", 4);
@@ -17,4 +19,4 @@
Console.WriteLine($"Size of topLevelDirectory2: {topLevelDirectory2.GetSize()}");
Console.WriteLine($"Size of root: {root.GetSize()}");
-Console.ReadKey();
\ No newline at end of file
+Console.ReadKey();
diff --git a/Finished sample/Decorator/Implementation.cs b/Finished sample/Decorator/Implementation.cs
index 82a2640..c28c6d3 100644
--- a/Finished sample/Decorator/Implementation.cs
+++ b/Finished sample/Decorator/Implementation.cs
@@ -1,104 +1,91 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Decorator;
-namespace Decorator
+///
+/// Component (as interface)
+///
+public interface IMailService
{
- ///
- /// ConcreteComponent1
- ///
- public class CloudMailService : IMailService
- {
- public bool SendMail(string message)
- {
- Console.WriteLine($"Message \"{message}\" sent via {nameof(CloudMailService)}.");
- return true;
- }
- }
+ bool SendMail(string message);
+}
- ///
- /// ConcreteComponent2
- ///
- public class OnPremiseMailService : IMailService
+///
+/// ConcreteComponent1
+///
+public class CloudMailService : IMailService
+{
+ public bool SendMail(string message)
{
- public bool SendMail(string message)
- {
- Console.WriteLine($"Message \"{message}\" sent via {nameof(OnPremiseMailService)}.");
- return true;
- }
+ Console.WriteLine($"Message \"{message}\" " +
+ $"sent via {nameof(CloudMailService)}.");
+ return true;
}
+}
- ///
- /// Component (as interface)
- ///
- public interface IMailService
+///
+/// ConcreteComponent2
+///
+public class OnPremiseMailService : IMailService
+{
+ public bool SendMail(string message)
{
- bool SendMail(string message);
+ Console.WriteLine($"Message \"{message}\" " +
+ $"sent via {nameof(OnPremiseMailService)}.");
+ return true;
}
+}
+///
+/// Decorator
+///
+public abstract class MailServiceDecoratorBase : IMailService
+{
+ readonly IMailService _mailService;
+ protected MailServiceDecoratorBase(IMailService mailService) => _mailService = mailService;
- ///
- /// Decorator (as abstract base class)
- ///
- public abstract class MailServiceDecoratorBase : IMailService
- {
- private readonly IMailService _mailService;
- public MailServiceDecoratorBase(IMailService mailService)
- {
- _mailService = mailService;
- }
+ public virtual bool SendMail(string message) => _mailService.SendMail(message);
+}
- public virtual bool SendMail(string message)
- {
- return _mailService.SendMail(message);
- }
+///
+/// ConcreteDecorator1
+///
+public class StatisticsDecorator : MailServiceDecoratorBase
+{
+ public StatisticsDecorator(IMailService mailService)
+ : base(mailService)
+ {
}
- ///
- /// ConcreteDecorator1
- ///
- public class StatisticsDecorator : MailServiceDecoratorBase
+ public override bool SendMail(string message)
{
- public StatisticsDecorator(IMailService mailService)
- : base(mailService)
- {
- }
-
- public override bool SendMail(string message)
- {
- // Fake collecting statistics
- Console.WriteLine($"Collecting statistics in {nameof(StatisticsDecorator)}.");
- return base.SendMail(message);
- }
+ // Fake collecting statistics
+ Console.WriteLine($"Collecting statistics in {nameof(StatisticsDecorator)}.");
+ return base.SendMail(message);
}
+}
+///
+/// ConcreteDecorator2
+///
+public class MessageDatabaseDecorator : MailServiceDecoratorBase
+{
///
- /// ConcreteDecorator2
+ /// A list of sent messages - a "fake" database
///
- public class MessageDatabaseDecorator : MailServiceDecoratorBase
- {
- ///
- /// A list of sent messages - a "fake" database
- ///
- public List SentMessages { get; private set; } = new List();
+ public List SentMessages { get; } = new List();
- public MessageDatabaseDecorator(IMailService mailService)
- : base(mailService)
- {
- }
+ public MessageDatabaseDecorator(IMailService mailService)
+ : base(mailService)
+ { }
- public override bool SendMail(string message)
+ public override bool SendMail(string message)
+ {
+ if (base.SendMail(message))
{
- if (base.SendMail(message))
- {
- // store sent message
- SentMessages.Add(message);
- return true;
- };
-
- return false;
+ // store sent message
+ SentMessages.Add(message);
+ return true;
}
+
+ return false;
}
}
diff --git a/Finished sample/Decorator/Program.cs b/Finished sample/Decorator/Program.cs
index 230cbb1..a76a3b5 100644
--- a/Finished sample/Decorator/Program.cs
+++ b/Finished sample/Decorator/Program.cs
@@ -1,6 +1,8 @@
-// instantiate mail services
-using Decorator;
+using Decorator;
+Console.Title = "Decorator";
+
+// instantiate mail services
var cloudMailService = new CloudMailService();
cloudMailService.SendMail("Hi there.");
diff --git a/Finished sample/DesignPatterns.sln b/Finished sample/DesignPatterns.sln
index d3ca260..fa609cf 100644
--- a/Finished sample/DesignPatterns.sln
+++ b/Finished sample/DesignPatterns.sln
@@ -101,6 +101,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "23 - Interpreter", "23 - In
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interpreter", "Interpreter\Interpreter.csproj", "{39C0A16A-B9F1-444B-9D5D-F46BBB84F746}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{61D1DF2B-393E-4AC1-AE68-0842FD3B1859}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ ReadMe.txt = ReadMe.txt
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/Finished sample/Facade/Implementation.cs b/Finished sample/Facade/Implementation.cs
index f5a0bcd..9d94170 100644
--- a/Finished sample/Facade/Implementation.cs
+++ b/Finished sample/Facade/Implementation.cs
@@ -1,75 +1,51 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Facade;
-namespace Facade
+///
+/// Subsystem class
+///
+public class OrderService
{
- ///
- /// Facade
- ///
- public class DiscountFacade
- {
- private readonly OrderService _orderService = new ();
- private readonly CustomerDiscountBaseService _customerDiscountBaseService = new ();
- private readonly DayOfTheWeekFactorService _dayOfTheWeekFactorService = new ();
-
- public double CalculateDiscountPercentage(int customerId)
- {
- if (!_orderService.HasEnoughOrders(customerId))
- {
- return 0;
- }
+ public static bool HasEnoughOrders(int customerId) =>
+ // does the customer have enough orders?
+ // fake calculation for demo purposes
+ customerId > 5;
+}
- return _customerDiscountBaseService.CalculateDiscountBase(customerId)
- * _dayOfTheWeekFactorService.CalculateDayOfTheWeekFactor();
- }
- }
-
- ///
- /// Subsystem class
- ///
- public class OrderService
- {
- public bool HasEnoughOrders(int customerId)
- {
- // does the customer have enough orders?
- // fake calculation for demo purposes
- return (customerId > 5);
- }
- }
+///
+/// Subsystem class
+///
+public class CustomerDiscountBaseService
+{
+ public double CalculateDiscountBase(int customerId) =>
+ // fake calculation for demo purposes
+ (customerId > 8) ? 10 : 20;
+}
- ///
- /// Subsystem class
- ///
- public class CustomerDiscountBaseService
- {
- public double CalculateDiscountBase(int customerId)
+///
+/// Subsystem class
+///
+public static class DayOfTheWeekFactorService
+{
+ public static double CalculateDayOfTheWeekFactor() =>
+ // fake calculation for demo purposes
+ DateTime.UtcNow.DayOfWeek switch
{
- // fake calculation for demo purposes
- return (customerId > 8) ? 10 : 20;
- }
- }
-
+ DayOfWeek.Saturday or DayOfWeek.Sunday => 0.8,
+ _ => 1.2,
+ };
+}
- ///
- /// Subsystem class
- ///
- public class DayOfTheWeekFactorService
- {
- public double CalculateDayOfTheWeekFactor()
- {
- // fake calculation for demo purposes
- switch (DateTime.UtcNow.DayOfWeek)
- {
- case DayOfWeek.Saturday:
- case DayOfWeek.Sunday:
- return 0.8;
- default:
- return 1.2;
- }
- }
- }
+///
+/// Facade
+///
+public class DiscountFacade
+{
+ //readonly OrderService _orderService = new();
+ readonly CustomerDiscountBaseService _customerDiscountBaseService = new();
+ //readonly DayOfTheWeekFactorService _dayOfTheWeekFactorService = new();
+ public double CalculateDiscountPercentage(int customerId) => OrderService.HasEnoughOrders(customerId)
+ ? _customerDiscountBaseService.CalculateDiscountBase(customerId)
+ * DayOfTheWeekFactorService.CalculateDayOfTheWeekFactor()
+ : 0;
}
diff --git a/Finished sample/Facade/Program.cs b/Finished sample/Facade/Program.cs
index fac6d6f..63d1eca 100644
--- a/Finished sample/Facade/Program.cs
+++ b/Finished sample/Facade/Program.cs
@@ -1,7 +1,11 @@
using Facade;
-
+
+Console.Title = "Facade";
+
var facade = new DiscountFacade();
-Console.WriteLine($"Discount percentage for customer with id 1: {facade.CalculateDiscountPercentage(1)}");
-Console.WriteLine($"Discount percentage for customer with id 10: {facade.CalculateDiscountPercentage(10)}");
+Console.WriteLine("Discount percentage for customer with id 1: " +
+ $"{facade.CalculateDiscountPercentage(1)}");
+Console.WriteLine("Discount percentage for customer with id 10: " +
+ $"{facade.CalculateDiscountPercentage(10)}");
Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/FactoryMethod/Implementation.cs b/Finished sample/FactoryMethod/Implementation.cs
index 9c28244..5bbec8b 100644
--- a/Finished sample/FactoryMethod/Implementation.cs
+++ b/Finished sample/FactoryMethod/Implementation.cs
@@ -1,109 +1,69 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace FactoryMethod;
-namespace FactoryMethod
+///
+/// Product
+///
+public abstract class DiscountService
{
- ///
- /// Product
- ///
- public abstract class DiscountService
- {
- public abstract int DiscountPercentage { get; }
-
- public override string ToString() => GetType().Name;
- }
-
- ///
- /// ConcreteProduct
- ///
- public class CountryDiscountService : DiscountService
- {
- private readonly string _countryIdentifier;
+ public abstract int DiscountPercentage { get; }
+ public override string ToString() => GetType().Name;
+}
- public CountryDiscountService(string countryIdentifier)
- {
- _countryIdentifier = countryIdentifier;
- }
+///
+/// ConcreteProduct
+///
+public class CountryDiscountService : DiscountService
+{
+ readonly string _countryIdentifier;
- public override int DiscountPercentage
- {
- get
- {
- switch (_countryIdentifier)
- {
- // if you're from Belgium, you get a better discount :)
- case "BE":
- return 20;
- default:
- return 10;
- }
- }
- }
- }
+ public CountryDiscountService(string countryIdentifier) => _countryIdentifier = countryIdentifier;
- ///
- /// ConcreteProduct
- ///
- public class CodeDiscountService : DiscountService
+ public override int DiscountPercentage => _countryIdentifier switch
{
- private readonly Guid _code;
+ // if you're from Belgium, you get a better discount :)
+ "BE" => 20,
+ _ => 10,
+ };
+}
- public CodeDiscountService(Guid code)
- {
- _code = code;
- }
+///
+/// ConcreteProduct
+///
+public class CodeDiscountService : DiscountService
+{
+ readonly Guid _code;
- public override int DiscountPercentage
- {
- // each code returns the same fixed percentage, but a code is only
- // valid once - include a check to so whether the code's been used before
- // ...
- get => 15;
- }
- }
+ public CodeDiscountService(Guid code) => _code = code;
- ///
- /// Creator
- ///
- public abstract class DiscountFactory
- {
- public abstract DiscountService CreateDiscountService();
- }
+ public override int DiscountPercentage => 15;
+}
- ///
- /// ConcretCreator
- ///
- public class CountryDiscountFactory : DiscountFactory
- {
- private readonly string _countryIdentifier;
- public CountryDiscountFactory(string countryIdentifier)
- {
- _countryIdentifier = countryIdentifier;
- }
+///
+/// Creator
+///
+public abstract class DiscountFactory
+{
+ public abstract DiscountService CreateDiscountService();
+}
- public override DiscountService CreateDiscountService()
- {
- return new CountryDiscountService(_countryIdentifier);
- }
- }
+///
+/// ConcreteCreator
+///
+public class CountryDiscountFactory : DiscountFactory
+{
+ readonly string _countryIdentifier;
+ public CountryDiscountFactory(string countryIdentifier) => _countryIdentifier = countryIdentifier;
- ///
- /// ConcreteCreator
- ///
- public class CodeDiscountFactory : DiscountFactory
- {
- private readonly Guid _code;
+ public override DiscountService CreateDiscountService() => new CountryDiscountService(_countryIdentifier);
+}
+
+///
+/// ConcreteCreator
+///
+public class CodeDiscountFactory : DiscountFactory
+{
+ readonly Guid _code;
- public CodeDiscountFactory(Guid code)
- {
- _code = code;
- }
- public override DiscountService CreateDiscountService()
- {
- return new CodeDiscountService(_code);
- }
- }
+ public CodeDiscountFactory(Guid code) => _code = code;
+ public override DiscountService CreateDiscountService() => new CodeDiscountService(_code);
}
diff --git a/Finished sample/FactoryMethod/Program.cs b/Finished sample/FactoryMethod/Program.cs
index c3c42e1..73a7ce6 100644
--- a/Finished sample/FactoryMethod/Program.cs
+++ b/Finished sample/FactoryMethod/Program.cs
@@ -1,13 +1,16 @@
using FactoryMethod;
-
+
+Console.Title = "Factory Method";
+
var factories = new List {
- new CodeDiscountFactory(Guid.NewGuid()),
+ new CodeDiscountFactory(Guid.NewGuid()),
new CountryDiscountFactory("BE") };
-foreach (var factory in factories)
+foreach (DiscountFactory factory in factories)
{
- var discountService = factory.CreateDiscountService();
- Console.WriteLine($"Percentage {discountService.DiscountPercentage} coming from {discountService}");
-}
+ DiscountService discountService = factory.CreateDiscountService();
+ Console.WriteLine($"Percentage {discountService.DiscountPercentage} " +
+ $"coming from {discountService}");
+}
Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Flyweight/Implementation.cs b/Finished sample/Flyweight/Implementation.cs
index 84c64ed..dddbfb1 100644
--- a/Finished sample/Flyweight/Implementation.cs
+++ b/Finished sample/Flyweight/Implementation.cs
@@ -1,113 +1,103 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Flyweight;
-namespace Flyweight
+///
+/// Flyweight
+///
+public interface ICharacter
{
- ///
- /// Flyweight
- ///
- public interface ICharacter
+ void Draw(string fontFamily, int fontSize);
+}
+
+///
+/// Concrete Flyweight
+///
+public class CharacterA : ICharacter
+{
+ readonly char _actualCharacter = 'a';
+ string _fontFamily = string.Empty;
+ int _fontSize;
+
+ public void Draw(string fontFamily, int fontSize)
{
- void Draw(string fontFamily, int fontSize);
+ _fontFamily = fontFamily;
+ _fontSize = fontSize;
+ Console.WriteLine($"Drawing {_actualCharacter}, {_fontFamily} {_fontSize}");
}
+}
- ///
- /// Concrete Flyweight
- ///
- public class CharacterA : ICharacter
- {
- private char _actualCharacter = 'a';
- private string _fontFamily = string.Empty;
- private int _fontSize;
+///
+/// Concrete Flyweight
+///
+public class CharacterB : ICharacter
+{
+ readonly char _actualCharacter = 'b';
+ string _fontFamily = string.Empty;
+ int _fontSize;
- public void Draw(string fontFamily, int fontSize)
- {
- _fontFamily = fontFamily;
- _fontSize = fontSize;
- Console.WriteLine($"Drawing {_actualCharacter}, {_fontFamily} {_fontSize}");
- }
+ public void Draw(string fontFamily, int fontSize)
+ {
+ _fontFamily = fontFamily;
+ _fontSize = fontSize;
+ Console.WriteLine($"Drawing {_actualCharacter}, {_fontFamily} {_fontSize}");
}
+}
- ///
- /// Concrete Flyweight
- ///
- public class CharacterB : ICharacter
- {
- private char _actualCharacter = 'b';
- private string _fontFamily = string.Empty;
- private int _fontSize;
+///
+/// FlyweightFactory
+///
+public class CharacterFactory
+{
+ readonly Dictionary _characters = new();
- public void Draw(string fontFamily, int fontSize)
+ public ICharacter? GetCharacter(char characterIdentifier)
+ {
+ // Does the character dictionary contain the one we need?
+ if (_characters.ContainsKey(characterIdentifier))
{
- _fontFamily = fontFamily;
- _fontSize = fontSize;
- Console.WriteLine($"Drawing {_actualCharacter}, {_fontFamily} {_fontSize}");
+ Console.WriteLine("Character reuse");
+ return _characters[characterIdentifier];
}
- }
-
- ///
- /// FlyweightFactory
- ///
- public class CharacterFactory
- {
- private readonly Dictionary _characters = new ();
- public ICharacter? GetCharacter(char characterIdentifier)
- {
- // Coes the character dictionary contain the one we need?
- if (_characters.ContainsKey(characterIdentifier))
- {
- Console.WriteLine("Character reuse");
+ // The character isn't in the dictionary.
+ // Create it, store it, return it.
+ Console.WriteLine("Character construction");
+ switch (characterIdentifier)
+ {
+ case 'a':
+ _characters[characterIdentifier] = new CharacterA();
+ return _characters[characterIdentifier];
+ case 'b':
+ _characters[characterIdentifier] = new CharacterB();
return _characters[characterIdentifier];
- }
-
- // The character isn't in the dictionary.
- // Create it, store it, return it.
- Console.WriteLine("Character construction");
- switch (characterIdentifier)
- {
- case 'a':
- _characters[characterIdentifier] = new CharacterA();
- return _characters[characterIdentifier];
- case 'b':
- _characters[characterIdentifier] = new CharacterB();
- return _characters[characterIdentifier];
// and so on...
- }
-
- return null;
}
- public ICharacter CreateParagraph(List characters, int location)
- {
- return new Paragraph(characters, location);
- }
+ return null;
}
- ///
- /// Unshared Concrete Flyweight
- ///
- public class Paragraph : ICharacter
- {
- private int _location;
- private List _characters = new();
+ public static ICharacter CreateParagraph(List characters, int location) => new Paragraph(characters, location);
+}
- public Paragraph(List characters, int location)
- {
- _characters = characters;
- _location = location;
- }
+///
+/// Unshared Concrete Flyweight
+///
+public class Paragraph : ICharacter
+{
+ readonly int _location;
+ readonly List _characters = new();
- public void Draw(string fontFamily, int fontSize)
+ public Paragraph(List characters, int location)
+ {
+ _characters = characters;
+ _location = location;
+ }
+
+ public void Draw(string fontFamily, int fontSize)
+ {
+ Console.WriteLine($"Drawing in paragraph at location {_location}");
+ foreach (ICharacter character in _characters)
{
- Console.WriteLine($"Drawing in paragraph at location {_location}");
- foreach (var character in _characters)
- {
- character.Draw(fontFamily, fontSize);
- }
+ character.Draw(fontFamily, fontSize);
}
}
}
diff --git a/Finished sample/Flyweight/Program.cs b/Finished sample/Flyweight/Program.cs
index bacf227..4a3a04d 100644
--- a/Finished sample/Flyweight/Program.cs
+++ b/Finished sample/Flyweight/Program.cs
@@ -1,11 +1,13 @@
using Flyweight;
-var aBunchOfCharacters = "abba";
+Console.Title = "Flyweight";
+
+var aBunchOfCharacters = "abba";
var characterFactory = new CharacterFactory();
// Get the flyweight(s)
-var characterObject = characterFactory.GetCharacter(aBunchOfCharacters[0]);
+ICharacter? characterObject = characterFactory.GetCharacter(aBunchOfCharacters[0]);
// Pass through extrinsic state
characterObject?.Draw("Arial", 12);
@@ -19,8 +21,11 @@
characterObject?.Draw("Comic Sans", 18);
// create unshared concrete flyweight (paragraph)
-var paragraph = characterFactory.CreateParagraph(
- new List() { characterObject }, 1);
+ICharacter paragraph = CharacterFactory.CreateParagraph(
+ characterObject is null
+ ? new List(0)
+ : new List() { characterObject }
+ , 1);
// draw the paragraph
paragraph.Draw("Lucinda", 12);
diff --git a/Finished sample/Interpreter/Implementation.cs b/Finished sample/Interpreter/Implementation.cs
index acf64d6..701a328 100644
--- a/Finished sample/Interpreter/Implementation.cs
+++ b/Finished sample/Interpreter/Implementation.cs
@@ -1,176 +1,166 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Interpreter;
-namespace Interpreter
+///
+/// Context
+///
+public class RomanContext
{
- ///
- /// Context
- ///
- public class RomanContext
+ public int Input { get; set; }
+ public string Output { get; set; } = string.Empty;
+ public RomanContext(int input) => Input = input;
+}
+
+///
+/// AbstractExpression
+///
+public abstract class RomanExpression
+{
+ public abstract void Interpret(RomanContext value);
+}
+
+// 9 = IX
+// 8 = VIII
+// 7 = VII
+// 6 = VI
+// 5 = V
+// 4 = IV
+// 3 = III
+// 2 = II
+// 1 = I
+
+// simplified - each combination is reachable with subtraction and these 4:
+// 9 = IX
+// 5 = V
+// 4 = IV
+// 1 = I
+
+///
+/// TerminalExpression
+///
+public class RomanOneExpression : RomanExpression
+{
+ public override void Interpret(RomanContext value)
{
- public int Input { get; set; }
- public string Output { get; set; } = string.Empty;
- public RomanContext(int input)
+ while (value.Input - 9 >= 0)
{
- Input = input;
+ value.Output += "IX";
+ value.Input -= 9;
}
- }
- ///
- /// AbstractExpression
- ///
- public abstract class RomanExpression
- {
- public abstract void Interpret(RomanContext value);
- }
+ while (value.Input - 5 >= 0)
+ {
+ value.Output += "V";
+ value.Input -= 5;
+ }
- // 9 = IX
- // 8 = VIII
- // 7 = VII
- // 6 = VI
- // 5 = V
- // 4 = IV
- // 3 = III
- // 2 = II
- // 1 = I
-
- // simplified - each combination is reachable with substraction and these 4:
- // 9 = IX
- // 5 = V
- // 4 = IV
- // 1 = I
-
- ///
- /// TerminalExpression
- ///
- public class RomanOneExpression : RomanExpression
- {
- public override void Interpret(RomanContext value)
+ while (value.Input - 4 >= 0)
+ {
+ value.Output += "IV";
+ value.Input -= 4;
+ }
+
+ while (value.Input - 1 >= 0)
{
- while ((value.Input - 9) >= 0)
- {
- value.Output += "IX";
- value.Input -= 9;
- }
-
- while ((value.Input - 5) >= 0)
- {
- value.Output += "V";
- value.Input -= 5;
- }
-
- while ((value.Input - 4) >= 0)
- {
- value.Output += "IV";
- value.Input -= 4;
- }
-
- while ((value.Input - 1) >= 0)
- {
- value.Output += "I";
- value.Input -= 1;
- }
+ value.Output += "I";
+ value.Input--;
}
}
+}
- // 90 = XC
- // 80 = LIII
- // 70 = LII
- // 60 = LX
- // 50 = L
- // 40 = XL
- // 30 = XXX
- // 20 = XX
- // 10 = X
-
- // simplified - each combination is reachable with substraction and these 4:
- // 90 = XC
- // 50 = L
- // 40 = XL
- // 10 = X
-
- ///
- /// TerminalExpression
- ///
- public class RomanTenExpression : RomanExpression
+// 90 = XC
+// 80 = LIII
+// 70 = LII
+// 60 = LX
+// 50 = L
+// 40 = XL
+// 30 = XXX
+// 20 = XX
+// 10 = X
+
+// simplified - each combination is reachable with substraction and these 4:
+// 90 = XC
+// 50 = L
+// 40 = XL
+// 10 = X
+
+///
+/// TerminalExpression
+///
+public class RomanTenExpression : RomanExpression
+{
+ public override void Interpret(RomanContext value)
{
- public override void Interpret(RomanContext value)
+ while (value.Input - 90 >= 0)
{
- while ((value.Input - 90) >= 0)
- {
- value.Output += "XC";
- value.Input -= 90;
- }
-
- while ((value.Input - 50) >= 0)
- {
- value.Output += "L";
- value.Input -= 50;
- }
-
- while ((value.Input - 40) >= 0)
- {
- value.Output += "XL";
- value.Input -= 40;
- }
-
- while ((value.Input - 10) >= 0)
- {
- value.Output += "X";
- value.Input -= 10;
- }
+ value.Output += "XC";
+ value.Input -= 90;
+ }
+
+ while (value.Input - 50 >= 0)
+ {
+ value.Output += "L";
+ value.Input -= 50;
+ }
+
+ while (value.Input - 40 >= 0)
+ {
+ value.Output += "XL";
+ value.Input -= 40;
+ }
+
+ while (value.Input - 10 >= 0)
+ {
+ value.Output += "X";
+ value.Input -= 10;
}
}
+}
- // 900 = CM
- // 800 = DCCC
- // 700 = DCC
- // 600 = DC
- // 500 = D
- // 400 = CD
- // 300 = CCC
- // 200 = CC
- // 100 = C
-
- // simplified - each combination is reachable with substraction and these 4:
- // 900 = CM
- // 500 = D
- // 400 = CD
- // 100 = C
-
- ///
- /// TerminalExpression
- ///
- public class RomanHunderdExpression : RomanExpression
+// 900 = CM
+// 800 = DCCC
+// 700 = DCC
+// 600 = DC
+// 500 = D
+// 400 = CD
+// 300 = CCC
+// 200 = CC
+// 100 = C
+
+// simplified - each combination is reachable with substraction and these 4:
+// 900 = CM
+// 500 = D
+// 400 = CD
+// 100 = C
+
+///
+/// TerminalExpression
+///
+public class RomanHunderdExpression : RomanExpression
+{
+ public override void Interpret(RomanContext value)
{
- public override void Interpret(RomanContext value)
+ while (value.Input - 900 >= 0)
+ {
+ value.Output += "CM";
+ value.Input -= 900;
+ }
+
+ while (value.Input - 500 >= 0)
+ {
+ value.Output += "D";
+ value.Input -= 500;
+ }
+
+ while (value.Input - 400 >= 0)
+ {
+ value.Output += "CD";
+ value.Input -= 400;
+ }
+
+ while (value.Input - 100 >= 0)
{
- while ((value.Input - 900) >= 0)
- {
- value.Output += "CM";
- value.Input -= 900;
- }
-
- while ((value.Input - 500) >= 0)
- {
- value.Output += "D";
- value.Input -= 500;
- }
-
- while ((value.Input - 400) >= 0)
- {
- value.Output += "CD";
- value.Input -= 400;
- }
-
- while ((value.Input - 100) >= 0)
- {
- value.Output += "C";
- value.Input -= 100;
- }
+ value.Output += "C";
+ value.Input -= 100;
}
}
}
diff --git a/Finished sample/Interpreter/Program.cs b/Finished sample/Interpreter/Program.cs
index db45324..57dfbc1 100644
--- a/Finished sample/Interpreter/Program.cs
+++ b/Finished sample/Interpreter/Program.cs
@@ -1,5 +1,7 @@
using Interpreter;
+Console.Title = "Interpreter";
+
var expressions = new List
{
new RomanHunderdExpression(),
@@ -8,22 +10,24 @@
};
var context = new RomanContext(5);
-foreach (var expression in expressions)
+foreach (RomanExpression expression in expressions)
{
expression.Interpret(context);
}
Console.WriteLine($"Translating Arabic numerals to Roman numerals: 5 = {context.Output}");
context = new RomanContext(81);
-foreach (var expression in expressions)
+foreach (RomanExpression expression in expressions)
{
expression.Interpret(context);
}
Console.WriteLine($"Translating Arabic numerals to Roman numerals: 81 = {context.Output}");
context = new RomanContext(733);
-foreach (var expression in expressions)
+foreach (RomanExpression expression in expressions)
{
expression.Interpret(context);
}
Console.WriteLine($"Translating Arabic numerals to Roman numerals: 733 = {context.Output}");
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Iterator/Implementation.cs b/Finished sample/Iterator/Implementation.cs
index 4146ec0..ec78222 100644
--- a/Finished sample/Iterator/Implementation.cs
+++ b/Finished sample/Iterator/Implementation.cs
@@ -1,90 +1,74 @@
-namespace Iterator
+namespace Iterator;
+
+public class Person
{
- public class Person
- {
- public string Name { get; set; }
- public string Country { get; set; }
+ public string Name { get; set; }
+ public string Country { get; set; }
- public Person(string name, string country)
- {
- Name = name;
- Country = country;
- }
- }
-
- ///
- /// Iterator
- ///
- public interface IPeopleIterator
+ public Person(string name, string country)
{
- Person First();
- Person Next();
- bool IsDone { get; }
- Person CurrentItem { get; }
+ Name = name;
+ Country = country;
}
+}
- ///
- /// ConcreteIterator
- ///
- public class PeopleIterator : IPeopleIterator
- {
- private PeopleCollection _peopleCollection;
- private int _current = 0;
-
- public PeopleIterator(PeopleCollection collection)
- {
- _peopleCollection = collection;
- }
+///
+/// Iterator
+///
+public interface IPeopleIterator
+{
+ Person? First();
+ Person? Next();
+ bool IsDone { get; }
+ Person? CurrentItem { get; }
+}
- public Person First()
- {
- _current = 0;
- return _peopleCollection
- .OrderBy(p => p.Name).ToList()[_current];
- }
+///
+/// Aggregate
+///
+public interface IPeopleCollection
+{
+ IPeopleIterator CreateIterator();
+}
- public Person Next()
- {
- _current++;
- if (!IsDone)
- {
- return _peopleCollection
- .OrderBy(p => p.Name).ToList()[_current];
- }
- else
- {
- return null;
- }
- }
+///
+/// ConcreteAggregate
+///
+public class PeopleCollection : List, IPeopleCollection
+{
+ public IPeopleIterator CreateIterator() => new PeopleIterator(this);
+}
- public bool IsDone
- {
- get { return _current >= _peopleCollection.Count; }
- }
+///
+/// ConcreteIterator
+///
+public class PeopleIterator : IPeopleIterator
+{
+ readonly PeopleCollection _peopleCollection;
+ int _current = 0;
- public Person CurrentItem
- {
- get { return _peopleCollection
- .OrderBy(p => p.Name).ToList()[_current]; }
- }
- }
+ public PeopleIterator(PeopleCollection collection) => _peopleCollection = collection;
- ///
- /// Aggregate
- ///
- public interface IPeopleCollection
+ public bool IsDone => _current >= _peopleCollection.Count;
+
+ public Person CurrentItem => _peopleCollection
+ .OrderBy(p => p.Name).ToList()[_current];
+
+ public Person? First()
{
- IPeopleIterator CreateIterator();
+ _current = 0;
+ return IsDone
+ ? null
+ : _peopleCollection
+ .OrderBy(p => p.Name).ToList()[_current];
}
- ///
- /// ConcreteAggregate
- ///
- public class PeopleCollection : List, IPeopleCollection
+ public Person? Next()
{
- public IPeopleIterator CreateIterator()
- {
- return new PeopleIterator(this);
- }
+ _current++;
+ return IsDone
+ ? null
+ : _peopleCollection
+ .OrderBy(p => p.Name).ToList()[_current];
}
}
diff --git a/Finished sample/Iterator/Program.cs b/Finished sample/Iterator/Program.cs
index f59562f..b65b6ba 100644
--- a/Finished sample/Iterator/Program.cs
+++ b/Finished sample/Iterator/Program.cs
@@ -1,21 +1,26 @@
using Iterator;
+Console.Title = "Iterator";
+
// create the collection
-PeopleCollection people = new PeopleCollection();
-people.Add(new Person("Kevin Dockx", "Belgium"));
-people.Add(new Person("Gill Cleeren", "Belgium"));
-people.Add(new Person("Roland Guijt", "The Netherlands"));
-people.Add(new Person("Thomas Claudius Huber", "Germany"));
+PeopleCollection people = new()
+{
+ new Person("Kevin Dockx", "Belgium"),
+ new Person("Gill Cleeren", "Belgium"),
+ new Person("Roland Guijt", "The Netherlands"),
+ new Person("Thomas Claudius Huber", "Germany")
+};
-// create the interator
-var peopleIterator = people.CreateIterator();
+// create the iterator
+IPeopleIterator peopleIterator = people.CreateIterator();
// use the iterator to run through the people
// in the collection; they should come out
// in alphabetical order
-for (Person person = peopleIterator.First();
- !peopleIterator.IsDone;
- person = peopleIterator.Next())
+Person person = peopleIterator.First()!;
+while (!peopleIterator.IsDone)
{
- Console.WriteLine(person?.Name);
+ Console.WriteLine(person.Name);
+ person = peopleIterator.Next()!;
}
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Mediator/Implementation.cs b/Finished sample/Mediator/Implementation.cs
index 05fbc91..175b62a 100644
--- a/Finished sample/Mediator/Implementation.cs
+++ b/Finished sample/Mediator/Implementation.cs
@@ -1,135 +1,108 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Mediator;
+
+//public abstract class ChatRoom
+//{
+// public abstract void Register(TeamMember teamMember);
+// public abstract void Send(string from, string message);
+//}
+
+///
+/// Mediator
+///
+public interface IChatRoom
+{
+ void Register(TeamMember teamMember);
+ void Send(string from, string message);
+ void Send(string from, string to, string message);
+ void SendTo(string from, string message) where T : TeamMember;
+}
-namespace Mediator
+///
+/// Colleague
+///
+public abstract class TeamMember
{
- ///
- /// Mediator
- ///
- public interface IChatRoom
- {
- void Register(TeamMember teamMember);
- void Send(string from, string message);
- void Send(string from, string to, string message);
- void SendTo(string from, string message) where T : TeamMember;
- }
+ IChatRoom? _chatroom;
+ public string Name { get; set; }
+ protected TeamMember(string name) => Name = name;
- ///
- /// Colleague
- ///
- public abstract class TeamMember
- {
- public string Name { get; set; }
+ internal void SetChatroom(IChatRoom chatRoom) => _chatroom = chatRoom;
+ public void Send(string to, string message) => _chatroom?.Send(Name, to, message);
- private IChatRoom? _chatroom;
+ public void SendTo(string message) where T : TeamMember => _chatroom?.SendTo(Name, message);
- public TeamMember(string name)
- {
- Name = name;
- }
-
- internal void SetChatroom(IChatRoom chatRoom)
- {
- _chatroom = chatRoom;
- }
-
- public void Send(string message)
- {
- _chatroom?.Send(Name, message);
- }
+ public void Send(string message) => _chatroom?.Send(Name, message);
- public void Send(string to, string message)
- {
- _chatroom?.Send(Name, to, message);
- }
-
- public void SendTo(string message) where T : TeamMember
- {
- _chatroom?.SendTo(Name, message);
- }
+ public virtual void Receive(string from, string message) => Console.WriteLine($"Message {from} to {Name}: {message}");
+}
- public virtual void Receive(string from, string message)
- {
- Console.WriteLine($"message from {from} to {Name}: {message}");
- }
+///
+/// ConcreteColleague
+///
+public class Lawyer : TeamMember
+{
+ public Lawyer(string name) : base(name)
+ {
}
- ///
- /// ConcreteColleague
- ///
- public class Lawyer : TeamMember
+ public override void Receive(string from, string message)
{
- private List _teamMembersInChat = new();
-
- public Lawyer(string name) : base(name)
- {
- }
-
- public override void Receive(string from, string message)
- {
- Console.Write($"{nameof(Lawyer)} {Name} received: ");
- base.Receive(from, message);
- }
+ Console.WriteLine($"{nameof(Lawyer)} {Name} received: ");
+ base.Receive(from, message);
}
+}
-
- ///
- /// ConcreteColleague
- ///
- public class AccountManager : TeamMember
+///
+/// ConcreteColleague
+///
+public class AccountManager : TeamMember
+{
+ public AccountManager(string name) : base(name)
{
- public AccountManager(string name) : base(name)
- {
- }
+ }
- public override void Receive(string from, string message)
- {
- Console.Write($"{nameof(AccountManager)} {Name} received: ");
- base.Receive(from, message);
- }
+ public override void Receive(string from, string message)
+ {
+ Console.WriteLine($"{nameof(AccountManager)} {Name} received: ");
+ base.Receive(from, message);
}
+}
+///
+/// ConcreteMediator
+///
+public class TeamChatRoom : IChatRoom
+{
+ readonly Dictionary teamMembers = new();
- ///
- /// ConcreteMediator
- ///
- public class TeamChatRoom : IChatRoom
+ public void Register(TeamMember teamMember)
{
- private readonly Dictionary teamMembers = new();
-
- public void Register(TeamMember teamMember)
+ teamMember.SetChatroom(this);
+ if (!teamMembers.ContainsKey(teamMember.Name))
{
- teamMember.SetChatroom(this);
- if (!teamMembers.ContainsKey(teamMember.Name))
- {
- teamMembers.Add(teamMember.Name, teamMember);
- }
+ teamMembers.Add(teamMember.Name, teamMember);
}
+ }
- public void Send(string from, string message)
+ public void Send(string from, string message)
+ {
+ foreach (TeamMember teamMember in teamMembers.Values)
{
- foreach (var teamMember in teamMembers.Values)
- {
- teamMember.Receive(from, message);
- }
+ teamMember.Receive(from, message);
}
+ }
- public void Send(string from, string to, string message)
- {
- var teamMember = teamMembers[to];
- teamMember?.Receive(from, message);
- }
+ public void Send(string from, string to, string message)
+ {
+ TeamMember teamMember = teamMembers[to];
+ teamMember?.Receive(from, message);
+ }
- public void SendTo(string from, string message) where T : TeamMember
+ public void SendTo(string from, string message) where T : TeamMember
+ {
+ foreach (T teamMember in teamMembers.Values.OfType())
{
- foreach (var teamMember in teamMembers.Values.OfType())
- {
- teamMember.Receive(from, message);
- }
+ teamMember.Receive(from, message);
}
}
}
-
\ No newline at end of file
diff --git a/Finished sample/Mediator/Program.cs b/Finished sample/Mediator/Program.cs
index a528358..a1c3668 100644
--- a/Finished sample/Mediator/Program.cs
+++ b/Finished sample/Mediator/Program.cs
@@ -1,5 +1,7 @@
using Mediator;
+Console.Title = "Mediator";
+
TeamChatRoom teamChatroom = new();
var sven = new Lawyer("Sven");
@@ -18,4 +20,6 @@
sven.Send("On it!");
sven.Send("Ann", "Could you join me in a Teams call?");
sven.Send("Ann", "All good :)");
-ann.SendTo("The file was approved!");
\ No newline at end of file
+ann.SendTo("The file was approved!");
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Memento/Implementation.cs b/Finished sample/Memento/Implementation.cs
index f1a7f2a..34edf57 100644
--- a/Finished sample/Memento/Implementation.cs
+++ b/Finished sample/Memento/Implementation.cs
@@ -1,229 +1,209 @@
-namespace Memento
+namespace Memento;
+
+public class Employee
{
- ///
- /// ICommand
- ///
- public interface ICommand
- {
- void Execute();
- bool CanExecute();
- void Undo();
- }
+ public int Id { get; set; }
+ public string Name { get; set; }
- ///
- /// Memento
- ///
- public class AddEmployeeToManagerListMemento
+ public Employee(int id, string name)
{
- public int ManagerId { get; private set; }
- public Employee? Employee { get; private set; }
-
- public AddEmployeeToManagerListMemento(int managerId, Employee? employee)
- {
- ManagerId = managerId;
- Employee = employee;
- }
+ Id = id;
+ Name = name;
}
-
- ///
- /// ConcreteCommand
- ///
- public class AddEmployeeToManagerList : ICommand
+}
+public class Manager : Employee
+{
+ public List Employees = new();
+ public Manager(int id, string name)
+ : base(id, name)
{
- private readonly IEmployeeManagerRepository _employeeManagerRepository;
- private int _managerId;
- private Employee? _employee;
-
- public AddEmployeeToManagerList(
- IEmployeeManagerRepository employeeManagerRepository,
- int managerId,
- Employee? employee)
- {
- _employeeManagerRepository = employeeManagerRepository;
- _managerId = managerId;
- _employee = employee;
- }
-
- public AddEmployeeToManagerListMemento CreateMemento()
- {
- return new AddEmployeeToManagerListMemento(_managerId, _employee);
- }
-
- public void RestoreMemento(AddEmployeeToManagerListMemento memento)
- {
- _managerId = memento.ManagerId;
- _employee = memento.Employee;
- }
+ }
+}
- public bool CanExecute()
- {
- // potentially check against business/technical rules that might block execution
+///
+/// Receiver (interface)
+///
+public interface IEmployeeManagerRepository
+{
+ void AddEmployee(int managerId, Employee employee);
+ void RemoveEmployee(int managerId, Employee employee);
+ bool HasEmployee(int managerId, int employeeId);
+ void WriteDataStore();
+}
+
+///
+/// Receiver (implementation)
+///
+public class EmployeeManagerRepository : IEmployeeManagerRepository
+{
+ // for demo purposes, use an in-memory datastore as a fake "manager list"
+ readonly List _managers = new()
+ { new Manager(1, "Katie"), new Manager(2, "Geoff") };
- // employee shouldn't be null
- if (_employee == null)
- {
- return false;
- }
+ public void AddEmployee(int managerId, Employee employee) =>
+ // in real-life, add additional input & error checks
+ _managers.First(m => m.Id == managerId).Employees.Add(employee);
- // employee shouldn't be on the manager's list already
- if (_employeeManagerRepository.HasEmployee(_managerId, _employee.Id))
- {
- return false;
- }
+ public void RemoveEmployee(int managerId, Employee employee) =>
+ // in real-life, add additional input & error checks
+ _managers.First(m => m.Id == managerId).Employees.Remove(employee);
- // other potential rule(s): ensure that an employee can only be added to
- // one manager's list at the same time, etc.
- return true;
- }
+ public bool HasEmployee(int managerId, int employeeId) =>
+ // in real-life, add additional input & error checks
+ _managers.First(m => m.Id == managerId)
+ .Employees.Any(e => e.Id == employeeId);
- public void Execute()
+ ///
+ /// For demo purposes, write out the data store to the console window
+ ///
+ public void WriteDataStore()
+ {
+ foreach (Manager manager in _managers)
{
- if (_employee == null)
+ Console.WriteLine($"Manager {manager.Id}, {manager.Name}");
+ if (manager.Employees.Any())
{
- return;
+ foreach (Employee employee in manager.Employees)
+ {
+ Console.WriteLine($"\t Employee {employee.Id}, {employee.Name}");
+ }
}
-
- _employeeManagerRepository.AddEmployee(_managerId, _employee);
- }
-
- public void Undo()
- {
- if (_employee == null)
+ else
{
- return;
+ Console.WriteLine("\t No employees.");
}
-
- _employeeManagerRepository.RemoveEmployee(_managerId, _employee);
}
}
+}
- ///
- /// CareTaker (and Invoker from the Command pattern)
- ///
- public class CommandManager
+///
+/// Command
+///
+public interface ICommand
+{
+ void Execute();
+ bool CanExecute();
+ void Undo();
+}
+
+///
+/// Memento
+///
+public class AddEmployeeToManagerListMemento
+{
+ public int ManagerId { get; }
+ public Employee? Employee { get; }
+
+ public AddEmployeeToManagerListMemento(int managerId, Employee? employee)
{
- private readonly Stack _mementos = new ();
- private AddEmployeeToManagerList? _command;
+ ManagerId = managerId;
+ Employee = employee;
+ }
+}
- public void Invoke(AddEmployeeToManagerList command)
- {
- // if the command has not been stored yet, store it - we will
- // reuse it instead of storing different instances
+///
+/// ConcreteCommand & Originator
+///
+public class AddEmployeeToManagerList : ICommand
+{
+ readonly IEmployeeManagerRepository _employeeManagerRepository;
+ int _managerId;
+ Employee? _employee;
+
+ public AddEmployeeToManagerList(
+ IEmployeeManagerRepository employeeManagerRepository,
+ int managerId,
+ Employee? employee)
+ {
+ _employeeManagerRepository = employeeManagerRepository;
+ _managerId = managerId;
+ _employee = employee;
+ }
- if (_command == null)
- {
- _command = command;
- }
+ public AddEmployeeToManagerListMemento CreateMemento() => new(_managerId, _employee);
- if (command.CanExecute())
- {
- command.Execute();
- _mementos.Push(command.CreateMemento());
- }
- }
+ public void RestoreMemento(AddEmployeeToManagerListMemento memento)
+ {
+ _managerId = memento.ManagerId;
+ _employee = memento.Employee;
+ }
- public void Undo()
+ public bool CanExecute()
+ {
+ // employee shouldn't be null
+ if (_employee == null)
{
- if (_mementos.Any())
- {
- _command?.RestoreMemento(_mementos.Pop());
- _command?.Undo();
- }
+ return false;
}
- public void UndoAll()
+ // employee shouldn't be on the manager's list already
+ if (_employeeManagerRepository.HasEmployee(_managerId, _employee.Id))
{
- while (_mementos.Any())
- {
- _command?.RestoreMemento(_mementos.Pop());
- _command?.Undo();
- }
+ return false;
}
- }
-
+ // other potential rule(s): ensure that an employee can only be added to
+ // one manager's list at the same time, etc.
+ return true;
+ }
- public class Employee
+ public void Execute()
{
- public int Id { get; set; }
- public string Name { get; set; }
-
- public Employee(int id, string name)
+ if (_employee == null)
{
- Id = id;
- Name = name;
+ return;
}
+ _employeeManagerRepository.AddEmployee(_managerId, _employee);
}
- public class Manager : Employee
+ public void Undo()
{
- public List Employees = new();
- public Manager(int id, string name)
- : base(id, name)
+ if (_employee == null)
{
+ return;
}
- }
- ///
- /// Receiver (interface)
- ///
- public interface IEmployeeManagerRepository
- {
- void AddEmployee(int managerId, Employee employee);
- void RemoveEmployee(int managerId, Employee employee);
- bool HasEmployee(int managerId, int employeeId);
- void WriteDataStore();
+ _employeeManagerRepository.RemoveEmployee(_managerId, _employee);
}
+}
- ///
- /// Receiver (implementation)
- ///
- public class EmployeeManagerRepository : IEmployeeManagerRepository
+///
+/// Invoker & Caretaker
+///
+public class CommandManager
+{
+ readonly Stack _mementos = new();
+ AddEmployeeToManagerList? _command;
+
+ public void Invoke(ICommand command)
{
- // for demo purposes, use an in-memory datastore as a fake "manager list"
- private List _managers = new List()
- { new Manager(1, "Katie"), new Manager(2, "Geoff") };
+ // if the command has not been stored yet, store it - we will
+ // reuse it instead of storing different instances
- public void AddEmployee(int managerId, Employee employee)
- {
- // in real-life, add additional input & error checks
- _managers.First(m => m.Id == managerId).Employees.Add(employee);
- }
+ _command ??= (AddEmployeeToManagerList)command;
- public void RemoveEmployee(int managerId, Employee employee)
+ if (command.CanExecute())
{
- // in real-life, add additional input & error checks
- _managers.First(m => m.Id == managerId).Employees.Remove(employee);
+ command.Execute();
+ _mementos.Push(((AddEmployeeToManagerList)command).CreateMemento());
}
+ }
- public bool HasEmployee(int managerId, int employeeId)
+ public void Undo()
+ {
+ if (_mementos.Any())
{
- // in real-life, add additional input & error checks
- return _managers.First(m => m.Id == managerId).Employees.Any(e => e.Id == employeeId);
+ _command?.RestoreMemento(_mementos.Pop());
+ _command?.Undo();
}
+ }
-
- ///
- /// For demo purposes, write out the data store to the console window
- ///
- public void WriteDataStore()
+ public void UndoAll()
+ {
+ while (_mementos.Any())
{
- foreach (var manager in _managers)
- {
- Console.WriteLine($"Manager {manager.Id}, {manager.Name}");
- if (manager.Employees.Any())
- {
- foreach (var employee in manager.Employees)
- {
- Console.WriteLine($"\t Employee {employee.Id}, {employee.Name}");
- }
- }
- else
- {
- Console.WriteLine($"\t No employees.");
- }
- }
- Console.WriteLine();
+ _command?.RestoreMemento(_mementos.Pop());
+ _command?.Undo();
}
}
}
\ No newline at end of file
diff --git a/Finished sample/Memento/Program.cs b/Finished sample/Memento/Program.cs
index 426c06f..50e0b77 100644
--- a/Finished sample/Memento/Program.cs
+++ b/Finished sample/Memento/Program.cs
@@ -1,24 +1,31 @@
using Memento;
+Console.Title = "Memento";
+
CommandManager commandManager = new();
IEmployeeManagerRepository repository = new EmployeeManagerRepository();
-
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 1, new Employee(111, "Kevin")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 1, new Employee(111, "Kevin")));
repository.WriteDataStore();
commandManager.Undo();
repository.WriteDataStore();
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 1, new Employee(222, "Clara")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 1, new Employee(222, "Clara")));
repository.WriteDataStore();
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
repository.WriteDataStore();
// try adding the same employee again
-commandManager.Invoke(new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
+commandManager.Invoke(
+ new AddEmployeeToManagerList(repository, 2, new Employee(333, "Tom")));
repository.WriteDataStore();
commandManager.UndoAll();
-repository.WriteDataStore();
\ No newline at end of file
+repository.WriteDataStore();
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Observer/Implementation.cs b/Finished sample/Observer/Implementation.cs
index 148ea3a..592f4dc 100644
--- a/Finished sample/Observer/Implementation.cs
+++ b/Finished sample/Observer/Implementation.cs
@@ -1,89 +1,79 @@
-namespace Observer
-{
- public class TicketChange
- {
- public int Amount { get; private set; }
- public int ArtistId { get; private set; }
+namespace Observer;
- public TicketChange(int artistId, int amount)
- {
- ArtistId = artistId;
- Amount = amount;
- }
- }
+public class TicketChange
+{
+ public int Amount { get; }
+ public int ArtistId { get; }
- ///
- /// Subject
- ///
- public abstract class TicketChangeNotifier
+ public TicketChange(int artistId, int amount)
{
- private List _observers = new();
+ ArtistId = artistId;
+ Amount = amount;
+ }
+}
- public void AddObserver(ITicketChangeListener observer)
- {
- _observers.Add(observer);
- }
+///
+/// Subject
+///
+public abstract class TicketChangeNotifier
+{
+ readonly List _observers = new();
- public void RemoveObserver(ITicketChangeListener observer)
- {
- _observers.Remove(observer);
- }
+ public void AddObserver(ITicketChangeListener observer) => _observers.Add(observer);
+ public void RemoveObserver(ITicketChangeListener observer) => _observers.Remove(observer);
- public void Notify(TicketChange ticketChange)
+ public void Notify(TicketChange ticketChange)
+ {
+ foreach (ITicketChangeListener observer in _observers)
{
- foreach (var observer in _observers)
- {
- observer.ReceiveTicketChangeNotification(ticketChange);
- }
+ observer.ReceiveTicketChangeNotification(ticketChange);
}
}
+}
- ///
- /// ConcreteSubject
- ///
- public class OrderService : TicketChangeNotifier
- {
- public void CompleteTicketSale(int artistId, int amount)
- {
- // change local datastore. Datastore omitted in demo implementation.
- Console.WriteLine($"{nameof(OrderService)} is changing its state.");
- // notify observers
- Console.WriteLine($"{nameof(OrderService)} is notifying observers...");
- Notify(new TicketChange(artistId, amount));
- }
- }
+///
+/// Observer
+///
+public interface ITicketChangeListener
+{
+ void ReceiveTicketChangeNotification(TicketChange ticketChange);
+}
- ///
- /// Observer
- ///
- public interface ITicketChangeListener
+///
+/// ConcreteSubject
+///
+public class OrderService : TicketChangeNotifier
+{
+ public void CompleteTicketSale(int artistId, int amount)
{
- void ReceiveTicketChangeNotification(TicketChange ticketChange);
+ // change local datastore. Datastore omitted in demo implementation.
+ Console.WriteLine($"{nameof(OrderService)} is changing its state.");
+ // notify observers
+ Console.WriteLine($"{nameof(OrderService)} is notifying observers...");
+ Notify(new TicketChange(artistId, amount));
}
+}
- ///
- /// ConcreteObserver
- ///
- public class TicketResellerService : ITicketChangeListener
- {
- public void ReceiveTicketChangeNotification(TicketChange ticketChange)
- {
- // update local datastore (datastore omitted in demo implementation)
- Console.WriteLine($"{nameof(TicketResellerService)} notified " +
- $"of ticket change: artist {ticketChange.ArtistId}, amount {ticketChange.Amount}");
- }
- }
+///
+/// ConcreteObserver
+///
+public class TicketResellerService : ITicketChangeListener
+{
+ public void ReceiveTicketChangeNotification(TicketChange ticketChange) =>
+ // update local datastore (datastore omitted in demo implementation)
+ Console.WriteLine($"{nameof(TicketResellerService)} notified " +
+ $"of ticket change: artist {ticketChange.ArtistId}, amount " +
+ $"{ticketChange.Amount}");
+}
- ///
- /// ConcreteObserver
- ///
- public class TicketStockService : ITicketChangeListener
- {
- public void ReceiveTicketChangeNotification(TicketChange ticketChange)
- {
- // update local datastore (datastore omitted in demo implementation)
- Console.WriteLine($"{nameof(TicketStockService)} notified " +
- $"of ticket change: artist {ticketChange.ArtistId}, amount {ticketChange.Amount}");
- }
- }
+///
+/// ConcreteObserver
+///
+public class TicketStockService : ITicketChangeListener
+{
+ public void ReceiveTicketChangeNotification(TicketChange ticketChange) =>
+ // update local datastore (datastore omitted in demo implementation)
+ Console.WriteLine($"{nameof(TicketStockService)} notified " +
+ $"of ticket change: artist {ticketChange.ArtistId}, amount " +
+ $"{ticketChange.Amount}");
}
diff --git a/Finished sample/Observer/Program.cs b/Finished sample/Observer/Program.cs
index 4b1bfe0..e363147 100644
--- a/Finished sample/Observer/Program.cs
+++ b/Finished sample/Observer/Program.cs
@@ -1,5 +1,7 @@
using Observer;
+Console.Title = "Observer";
+
TicketStockService ticketStockService = new();
TicketResellerService ticketResellerService = new();
OrderService orderService = new();
@@ -11,8 +13,12 @@
// notify
orderService.CompleteTicketSale(1, 2);
+Console.WriteLine();
+
// remove one observer
orderService.RemoveObserver(ticketResellerService);
// notify
orderService.CompleteTicketSale(2, 4);
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Prototype/Implementation.cs b/Finished sample/Prototype/Implementation.cs
index 7449d0e..94d97df 100644
--- a/Finished sample/Prototype/Implementation.cs
+++ b/Finished sample/Prototype/Implementation.cs
@@ -1,74 +1,53 @@
using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.Serialization;
-using System.Runtime.Serialization.Formatters.Binary;
-using System.Threading.Tasks;
-namespace Prototype
-{
- ///
- /// Prototype abstract class
- ///
- public abstract class Person
- {
- public abstract string Name { get; set; }
-
- public abstract Person Clone(bool deepClone);
-
- }
+namespace Prototype;
- ///
- /// ConcretePrototype1
- ///
- public class Employee : Person
- {
- public Manager Manager { get; set; }
- public override string Name { get; set; }
-
- public Employee(string name, Manager manager)
- {
- Name = name;
- Manager = manager;
- }
+///
+/// Prototype
+///
+public abstract class Person
+{
+ public abstract string Name { get; set; }
- public override Person Clone(bool deepClone = false)
- {
- if (deepClone)
- {
- var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
- var objectAsJson = JsonConvert.SerializeObject(this, typeof(Employee), settings);
- return JsonConvert.DeserializeObject(objectAsJson, settings);
- }
+ public abstract Person Clone(bool deepClone);
+}
+///
+/// ConcretePrototype1
+///
+public class Manager : Person
+{
+ public override string Name { get; set; }
- return (Person)MemberwiseClone();
- }
- }
+ public Manager(string name) => Name = name;
- ///
- /// ConcretePrototype2
- ///
- public class Manager : Person
+ public override Person Clone(bool deepClone = false)
{
- public override string Name { get; set; }
-
- public Manager(string name)
+ if (deepClone)
{
- Name = name;
+ var objectAsJson = JsonConvert.SerializeObject(this);
+ return JsonConvert.DeserializeObject(objectAsJson)!;
}
- public override Person Clone(bool deepClone = false)
- {
- if (deepClone)
- {
- var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
- var objectAsJson = JsonConvert.SerializeObject(this, typeof(Manager), settings);
- return JsonConvert.DeserializeObject(objectAsJson, settings);
- }
-
- return (Person)MemberwiseClone();
- }
+ return (Person)MemberwiseClone();
}
}
+
+///
+/// ConcretePrototype2
+///
+public class Employee : Person
+{
+ public Manager Manager { get; set; }
+ public override string Name { get; set; }
+
+ public Employee(string name, Manager manager)
+ {
+ Name = name;
+ Manager = manager;
+ }
+
+ public override Person Clone(bool deepClone = false) => deepClone
+ ? JsonConvert.DeserializeObject(JsonConvert.SerializeObject(this))!
+ : (Person)MemberwiseClone();
+}
\ No newline at end of file
diff --git a/Finished sample/Prototype/Program.cs b/Finished sample/Prototype/Program.cs
index 429c804..2a873c3 100644
--- a/Finished sample/Prototype/Program.cs
+++ b/Finished sample/Prototype/Program.cs
@@ -1,15 +1,19 @@
using Prototype;
+Console.Title = "Prototype";
+
var manager = new Manager("Cindy");
var managerClone = (Manager)manager.Clone();
Console.WriteLine($"Manager was cloned: {managerClone.Name}");
-var employee = new Employee("Kevin", manager);
+var employee = new Employee("Kevin", managerClone);
var employeeClone = (Employee)employee.Clone(true);
-Console.WriteLine($"Employee was cloned: {employeeClone.Name}, with manager {employeeClone.Manager.Name}");
+Console.WriteLine($"Employee was cloned: {employeeClone.Name}," +
+ $" with manager {employeeClone.Manager.Name}");
// change the manager name
-manager.Name = "Karen";
-Console.WriteLine($"Employee was cloned: {employeeClone.Name}, with manager {employeeClone.Manager.Name}");
+managerClone.Name = "Karen";
+Console.WriteLine($"Employee was cloned: {employeeClone.Name}, " +
+ $"with manager {employeeClone.Manager.Name}");
Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Prototype/Prototype.csproj b/Finished sample/Prototype/Prototype.csproj
index 11b28f3..15a13e3 100644
--- a/Finished sample/Prototype/Prototype.csproj
+++ b/Finished sample/Prototype/Prototype.csproj
@@ -1,4 +1,4 @@
-
+
Exe
diff --git a/Finished sample/Proxy/Implementation.cs b/Finished sample/Proxy/Implementation.cs
index 1097957..982bdaa 100644
--- a/Finished sample/Proxy/Implementation.cs
+++ b/Finished sample/Proxy/Implementation.cs
@@ -1,101 +1,93 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Proxy;
-namespace Proxy
+///
+/// Subject
+///
+public interface IDocument
{
- ///
- /// RealSubject
- ///
- public class Document : IDocument
- {
- public string? Title { get; private set; }
- public string? Content { get; private set; }
- public int AuthorId { get; private set; }
- public DateTimeOffset LastAccessed { get; private set; }
- private string _fileName;
-
- public Document(string fileName)
- {
- _fileName = fileName;
- LoadDocument(fileName);
- }
-
- private void LoadDocument(string fileName)
- {
- Console.WriteLine("Executing expensive action: loading a file from disk");
- // fake loading...
- Thread.Sleep(1000);
+ void DisplayDocument();
+}
- Title = "An expensive document";
- Content = "Lots and lots of content";
- AuthorId = 1;
- LastAccessed = DateTimeOffset.UtcNow;
- }
+///
+/// RealSubject
+///
+public class Document : IDocument
+{
+ public string? Title { get; set; }
+ public string? Content { get; set; }
+ public int AuthorId { get; set; }
+ public DateTimeOffset LastAccessed { get; set; }
+ readonly string _fileName;
- public void DisplayDocument()
- {
- Console.WriteLine($"Title: {Title}, Content: {Content}");
- }
+ public Document(string fileName)
+ {
+ _fileName = fileName;
+ LoadDocument(fileName);
}
- ///
- /// Subject
- ///
- public interface IDocument
+ void LoadDocument(string fileName)
{
- void DisplayDocument();
+ Console.WriteLine("Executing expensive action: loading a file from disk");
+ // fake loading...
+ Thread.Sleep(1000);
+
+ Title = "An expensive document";
+ Content = "Lots and lots of content";
+ AuthorId = 1;
+ LastAccessed = DateTimeOffset.UtcNow;
}
- ///
- /// Proxy
- ///
- public class DocumentProxy : IDocument
+ public void DisplayDocument() => Console.WriteLine($"Title: {Title}, Content: {Content}");
+}
+
+///
+/// Proxy
+///
+public class DocumentProxy : IDocument
+{
+ // avoid creating the document until we need it
+ readonly Lazy _document;
+ readonly string _fileName;
+
+ public DocumentProxy(string fileName)
{
- // avoid creating the document until we need it
- private Lazy _document;
- private string _fileName;
+ _fileName = fileName;
+ _document = new Lazy(() => new Document(_fileName));
+ }
- public DocumentProxy(string fileName)
- {
- _fileName = fileName;
- _document = new Lazy(() => new Document(_fileName));
- }
+ public void DisplayDocument() => _document.Value.DisplayDocument();
+}
- public void DisplayDocument()
- {
- _document.Value.DisplayDocument();
- }
+///
+/// Proxy
+///
+public class ProtectedDocumentProxy : IDocument
+{
+ readonly string _fileName;
+ readonly string _userRole;
+ readonly DocumentProxy _documentProxy;
+
+ public ProtectedDocumentProxy(string fileName,
+ string userRole)
+ {
+ _fileName = fileName;
+ _userRole = userRole;
+ _documentProxy = new DocumentProxy(_fileName);
}
- public class ProtectedDocumentProxy : IDocument
+ public void DisplayDocument()
{
- private string _fileName;
- private string _userRole;
- private DocumentProxy _documentProxy;
+ Console.WriteLine("Entering DisplayDocument " +
+ $"in {nameof(ProtectedDocumentProxy)}.");
- public ProtectedDocumentProxy(string fileName,
- string userRole)
+ if (_userRole != "Viewer")
{
- _fileName = fileName;
- _userRole = userRole;
- _documentProxy = new DocumentProxy(_fileName);
+ throw new UnauthorizedAccessException();
}
-
- public void DisplayDocument()
- {
- Console.WriteLine($"Entering DisplayDocument in {nameof(ProtectedDocumentProxy)}.");
-
- if (_userRole != "Viewer")
- {
- throw new UnauthorizedAccessException();
- }
- _documentProxy.DisplayDocument();
+ _documentProxy.DisplayDocument();
- Console.WriteLine($"Exiting DisplayDocument in {nameof(ProtectedDocumentProxy)}.");
- }
+ Console.WriteLine("Exiting DisplayDocument " +
+ $"in {nameof(ProtectedDocumentProxy)}.");
}
}
diff --git a/Finished sample/Proxy/Program.cs b/Finished sample/Proxy/Program.cs
index 741215e..f40cad9 100644
--- a/Finished sample/Proxy/Program.cs
+++ b/Finished sample/Proxy/Program.cs
@@ -1,4 +1,5 @@
-
+Console.Title = "Proxy";
+
// without proxy
Console.WriteLine("Constructing document.");
var myDocument = new Proxy.Document("MyDocument.pdf");
@@ -28,3 +29,5 @@
myProtectedDocumentProxy = new Proxy.ProtectedDocumentProxy("MyDocument.pdf", "AnotherRole");
Console.WriteLine("Protected document proxy constructed.");
myProtectedDocumentProxy.DisplayDocument();
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/ReadMe.txt b/Finished sample/ReadMe.txt
new file mode 100644
index 0000000..8653c1c
--- /dev/null
+++ b/Finished sample/ReadMe.txt
@@ -0,0 +1,14 @@
+My primary reason for raising this PR was to eliminate the noise distractions of excess warnings
+
+Some personal preferences caused significant style differences, so I commented those out ("#Dick ") in the .editorconfig to minimse extraneous changes
+- feel free to uncomment to taste !
+
+The added .editorconfig file resides here at solution-level. Unusually, it contains the setting
+"dotnet_style_namespace_match_folder = false"
+to address the 2 projects with peculiar namespace designs
+1. Adapter teaches 2 alternates in the same folder but with different namespaces to distinguish
+ ClassAdapterImplementation.cs, ObjectAdapterImplementation.cs have same class definitions
+ if you set "dotnet_style_namespace_match_folder = true", the classes will collide
+
+2. Builder pattern originally had a "namespace BuilderPattern;", and Program.cs in the minimal style (i.e. implicit namespace)
+ but now simplified to match the containing folder structure, so Program needs an explicit "using Builder;" to link-in.
diff --git a/Finished sample/Singleton/Implementation.cs b/Finished sample/Singleton/Implementation.cs
index 929a610..a7c3ac8 100644
--- a/Finished sample/Singleton/Implementation.cs
+++ b/Finished sample/Singleton/Implementation.cs
@@ -1,47 +1,27 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Singleton;
-namespace Singleton
+///
+/// Singleton
+///
+public class Logger
{
- ///
- /// Singleton
- ///
- public class Logger
- {
- //private static Logger? _instance;
+ // Lazy
+ static readonly Lazy _lazyLogger
+ = new(() => new Logger());
- private static readonly Lazy _lazyLogger
- = new Lazy(() => new Logger());
+ // static Logger? _instance;
- ///
- /// Instance
- ///
- public static Logger Instance
- {
- get { return _lazyLogger.Value; }
- //get
- //{
- // if (_instance == null)
- // {
- // _instance = new Logger();
- // }
- // return _instance;
- //}
- }
-
- protected Logger()
- {
- }
+ ///
+ /// Instance
+ ///
+ public static Logger Instance => _lazyLogger.Value;//if (_instance == null)//{// _instance = new Logger();//}//return _instance;
- ///
- /// SingletonOperation
- ///
- public void Log(string message)
- {
- Console.WriteLine($"Message to log: {message}");
- }
+ protected Logger()
+ {
}
+
+ ///
+ /// SingletonOperation
+ ///
+ public static void Log(string message) => Console.WriteLine($"Message to log: {message}");
}
diff --git a/Finished sample/Singleton/Program.cs b/Finished sample/Singleton/Program.cs
index bd57b5b..3782977 100644
--- a/Finished sample/Singleton/Program.cs
+++ b/Finished sample/Singleton/Program.cs
@@ -1,16 +1,20 @@
using Singleton;
+Console.Title = "Singleton";
+
// call the property getter twice
-var instance1 = Logger.Instance;
-var instance2 = Logger.Instance;
+Logger instance1 = Logger.Instance;
+Logger instance2 = Logger.Instance;
if (instance1 == instance2 && instance2 == Logger.Instance)
{
Console.WriteLine("Instances are the same.");
}
-instance1.Log($"Message from {nameof(instance1)}");
+Logger.Log($"Message from {nameof(instance1)}");
// or
-instance1.Log($"Message from {nameof(instance2)}");
+Logger.Log($"Message from {nameof(instance2)}");
// or
-Logger.Instance.Log($"Message from {nameof(Logger.Instance)}");
\ No newline at end of file
+Logger.Log($"Message from {nameof(Logger.Instance)}");
+
+Console.ReadLine();
\ No newline at end of file
diff --git a/Finished sample/State/Implementation.cs b/Finished sample/State/Implementation.cs
index 36c7db6..a32749d 100644
--- a/Finished sample/State/Implementation.cs
+++ b/Finished sample/State/Implementation.cs
@@ -1,169 +1,136 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace State;
-namespace State
+///
+/// State
+///
+public abstract class BankAccountState
{
- ///
- /// State
- ///
- public abstract class BankAccountState
+ public BankAccount BankAccount { get; protected set; } = null!;
+ public decimal Balance { get; protected set; }
+
+ public abstract void Deposit(decimal amount);
+ public abstract void Withdraw(decimal amount);
+}
+
+///
+/// ConcreteState
+///
+public class GoldState : BankAccountState
+{
+ public GoldState(decimal balance, BankAccount bankAccount)
{
- public BankAccount BankAccount { get; protected set; } = null!;
- public decimal Balance { get; protected set; }
+ Balance = balance;
+ BankAccount = bankAccount;
+ }
- public abstract void Deposit(decimal amount);
- public abstract void Withdraw(decimal amount);
+ public override void Deposit(decimal amount)
+ {
+ Console.WriteLine($"In {GetType()}, depositing " +
+ $"{amount} + 10% bonus: {amount / 10}");
+ Balance += amount + amount / 10;
}
- ///
- /// ConcreteState
- ///
- public class OverdrawnState : BankAccountState
+ public override void Withdraw(decimal amount)
{
- public OverdrawnState(decimal balance, BankAccount bankAccount)
+ Console.WriteLine($"In {GetType()}, withdrawing {amount} from {Balance}");
+ // change state to overdrawn when withdrawing results in less than zero
+ Balance -= amount;
+ if (Balance is < 1000 and >= 0)
{
- Balance = balance;
- BankAccount = bankAccount;
+ // change state to regular
+ BankAccount.BankAccountState = new RegularState(Balance, BankAccount);
}
-
- ///
- /// Handle a deposit
- ///
- public override void Deposit(decimal amount)
+ else if (Balance < 0)
{
- Console.WriteLine($"In {GetType()}, depositing {amount}");
- Balance += amount;
- if (Balance >= 0)
- {
- // change state to regular
- BankAccount.BankAccountState = new RegularState(Balance, BankAccount);
- }
+ // change state to overdrawn
+ BankAccount.BankAccountState = new OverdrawnState(Balance, BankAccount);
}
+ }
+}
- ///
- /// Handle withdrawing
- ///
- public override void Withdraw(decimal amount)
- {
- // cannot withdraw
- Console.WriteLine($"In {GetType()}, cannot withdraw, balance {Balance}");
- }
+///
+/// ConcreteState
+///
+public class RegularState : BankAccountState
+{
+ public RegularState(decimal balance, BankAccount bankAccount)
+ {
+ Balance = balance;
+ BankAccount = bankAccount;
}
- ///
- /// ConcreteState
- ///
- public class RegularState : BankAccountState
+ public override void Deposit(decimal amount)
{
- public RegularState(decimal balance, BankAccount bankAccount)
+ Console.WriteLine($"In {GetType()}, depositing {amount}");
+ Balance += amount;
+ if (Balance >= 1000)
{
- Balance = balance;
- BankAccount = bankAccount;
+ // change state to gold
+ BankAccount.BankAccountState = new GoldState(Balance, BankAccount);
}
+ }
- ///
- /// Handle a deposit
- ///
- public override void Deposit(decimal amount)
+ public override void Withdraw(decimal amount)
+ {
+ Console.WriteLine($"In {GetType()}, withdrawing {amount} from {Balance}");
+ // change state to overdrawn when withdrawing results in less than zero
+ Balance -= amount;
+ if (Balance < 0)
{
- Console.WriteLine($"In {GetType()}, depositing {amount}");
- Balance += amount;
- if (Balance >= 1000)
- {
- // change state to gold
- BankAccount.BankAccountState = new GoldState(Balance, BankAccount);
- }
+ // change state to overdrawn
+ BankAccount.BankAccountState = new OverdrawnState(Balance, BankAccount);
}
+ }
+}
- ///
- /// Handle withdrawing
- ///
- public override void Withdraw(decimal amount)
- {
- Console.WriteLine($"In {GetType()}, withdrawing {amount} from {Balance}");
- // change state to overdrawn when withdrawing results in less than zero
- Balance -= amount;
- if (Balance < 0)
- {
- // change state to overdrawn
- BankAccount.BankAccountState = new OverdrawnState(Balance, BankAccount);
- }
- }
+///
+/// ConcreteState
+///
+public class OverdrawnState : BankAccountState
+{
+ public OverdrawnState(decimal balance, BankAccount bankAccount)
+ {
+ Balance = balance;
+ BankAccount = bankAccount;
}
- ///
- /// ConcreteState
- ///
- public class GoldState : BankAccountState
+ public override void Deposit(decimal amount)
{
- public GoldState(decimal balance, BankAccount bankAccount)
+ Console.WriteLine($"In {GetType()}, depositing {amount}");
+ Balance += amount;
+ if (Balance >= 0)
{
- Balance = balance;
- BankAccount = bankAccount;
+ // change state to regular
+ BankAccount.BankAccountState = new RegularState(Balance, BankAccount);
}
+ }
- ///
- /// Handle a deposit
- ///
- public override void Deposit(decimal amount)
- {
- Console.WriteLine($"In {GetType()}, depositing {amount} + 10% bonus: {amount/10}");
- Balance += amount + (amount/10);
- }
+ public override void Withdraw(decimal amount) =>
+ // cannot withdraw
+ Console.WriteLine($"In {GetType()}, cannot withdraw, balance {Balance}");
+}
- ///
- /// Handle withdrawing
- ///
- public override void Withdraw(decimal amount)
- {
- Console.WriteLine($"In {GetType()}, withdrawing {amount} from {Balance}");
- // change state to overdrawn when withdrawing results in less than zero
- Balance -= amount;
- if (Balance < 1000 && Balance >= 0)
- {
- // change state to regular
- BankAccount.BankAccountState = new RegularState(Balance, BankAccount);
- }
- else if (Balance < 0)
- {
- // change state to overdrawn
- BankAccount.BankAccountState = new OverdrawnState(Balance, BankAccount);
- }
- }
- }
+///
+/// Context
+///
+public class BankAccount
+{
+ public BankAccountState BankAccountState { get; set; }
+ public decimal Balance => BankAccountState.Balance;
+
+ public BankAccount() => BankAccountState = new RegularState(200, this);
///
- /// Context
+ /// Request a deposit
///
- public class BankAccount
- {
- public BankAccountState BankAccountState { get; set; }
- public decimal Balance { get { return BankAccountState.Balance; } }
+ public void Deposit(decimal amount) =>
+ // let the current state handle the deposit
+ BankAccountState.Deposit(amount);
- public BankAccount()
- {
- BankAccountState = new RegularState(200, this);
- }
-
- ///
- /// Request a deposit
- ///
- public void Deposit(decimal amount)
- {
- // let the current state handle the deposit
- BankAccountState.Deposit(amount);
- }
-
- ///
- /// Request a withdrawal
- ///
- public void Withdraw(decimal amount)
- {
- // let the current state handle the withdrawel
- BankAccountState.Withdraw(amount);
- }
- }
-}
+ ///
+ /// Request a withdrawal
+ ///
+ public void Withdraw(decimal amount) =>
+ // let the current state handle the withdrawel
+ BankAccountState.Withdraw(amount);
+}
\ No newline at end of file
diff --git a/Finished sample/State/Program.cs b/Finished sample/State/Program.cs
index d9f8fc6..9d99427 100644
--- a/Finished sample/State/Program.cs
+++ b/Finished sample/State/Program.cs
@@ -1,5 +1,7 @@
using State;
+Console.Title = "State";
+
BankAccount bankAccount = new();
bankAccount.Deposit(100);
bankAccount.Withdraw(500);
@@ -13,4 +15,5 @@
// should transition to regular
bankAccount.Deposit(3000);
// should still be in regular
-bankAccount.Deposit(100);
\ No newline at end of file
+bankAccount.Deposit(100);
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/Strategy/Implementation.cs b/Finished sample/Strategy/Implementation.cs
index 118a283..a9f6f55 100644
--- a/Finished sample/Strategy/Implementation.cs
+++ b/Finished sample/Strategy/Implementation.cs
@@ -1,71 +1,61 @@
-namespace Strategy
+namespace Strategy;
+
+///
+/// Strategy
+///
+public interface IExportService
{
- ///
- /// Strategy
- ///
- public interface IExportService
- {
- void Export(Order order);
- }
+ void Export(Order order);
+}
- ///
- /// ConcreteStrategy
- ///
- public class JsonExportService : IExportService
- {
- public void Export(Order order)
- {
- Console.WriteLine($"Exporting {order.Name} to Json.");
- }
- }
+///
+/// ConcreteStrategy
+///
+public class JsonExportService : IExportService
+{
+ public void Export(Order order) => Console.WriteLine($"Exporting {order.Name} to Json.");
+}
- ///
- /// ConcreteStrategy
- ///
- public class XMLExportService : IExportService
- {
- public void Export(Order order)
- {
- Console.WriteLine($"Exporting {order.Name} to XML.");
- }
- }
+///
+/// ConcreteStrategy
+///
+public class XMLExportService : IExportService
+{
+ public void Export(Order order) => Console.WriteLine($"Exporting {order.Name} to XML.");
+}
+
+///
+/// ConcreteStrategy
+///
+public class CSVExportService : IExportService
+{
+ public void Export(Order order) => Console.WriteLine($"Exporting {order.Name} to CSV.");
+}
+
+///
+/// Context
+///
+public class Order
+{
+ public string Customer { get; set; }
+ public int Amount { get; set; }
+ public string Name { get; set; }
+ public string? Description { get; set; }
- ///
- /// ConcreteStrategy
- ///
- public class CSVExportService : IExportService
+ public Order(string customer, int amount, string name)
{
- public void Export(Order order)
- {
- Console.WriteLine($"Exporting {order.Name} to CSV.");
- }
+ Customer = customer;
+ Amount = amount;
+ Name = name;
}
-
- ///
- /// Context
- ///
- public class Order
- {
- public string Customer { get; set; }
- public int Amount { get; set; }
- public string Name { get; set; }
- public string? Description { get; set; }
- public Order(string customer, int amount, string name)
+ public void Export(IExportService exportService)
+ {
+ if (exportService is null)
{
- Customer = customer;
- Amount = amount;
- Name = name;
+ throw new ArgumentNullException(nameof(exportService));
}
- public void Export(IExportService exportService)
- {
- if (exportService is null)
- {
- throw new ArgumentNullException(nameof(exportService));
- }
-
- exportService.Export(this);
- }
+ exportService.Export(this);
}
}
diff --git a/Finished sample/Strategy/Program.cs b/Finished sample/Strategy/Program.cs
index 794591f..b5cc766 100644
--- a/Finished sample/Strategy/Program.cs
+++ b/Finished sample/Strategy/Program.cs
@@ -1,5 +1,9 @@
using Strategy;
+Console.Title = "Strategy";
+
var order = new Order("Marvin Software", 5, "Visual Studio License");
order.Export(new CSVExportService());
-order.Export(new JsonExportService());
\ No newline at end of file
+order.Export(new JsonExportService());
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/TemplateMethod/Implementation.cs b/Finished sample/TemplateMethod/Implementation.cs
index d42d7f1..5cef5cf 100644
--- a/Finished sample/TemplateMethod/Implementation.cs
+++ b/Finished sample/TemplateMethod/Implementation.cs
@@ -1,67 +1,44 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace TemplateMethod;
-namespace TemplateMethod
-{
- ///
- /// AbstractClass
- ///
- public abstract class MailParser
- {
- public virtual void FindServer()
- {
- Console.WriteLine("Finding server...");
- }
-
- public abstract void AuthenticateToServer();
-
+///
+/// AbstractClass
+///
+public abstract class MailParser
+{
+ public virtual void FindServer() => Console.WriteLine("Finding server...");
- public virtual string ParseHtmlMailBody(string identifier)
- {
- Console.WriteLine("Parsing HTML mail body...");
- return $"This is the body of mail with id {identifier}";
- }
+ public abstract void AuthenticateToServer();
- ///
- /// Template method
- ///
- public string ParseMailBody(string identifier)
- {
- Console.WriteLine("Parsing mail body (in template method)...");
- FindServer();
- AuthenticateToServer();
- return ParseHtmlMailBody(identifier);
- }
- }
-
- public class ExchangeMailParser : MailParser
+ public static string ParseHtmlMailBody(string identifier)
{
- public override void AuthenticateToServer()
- {
- Console.WriteLine("Connecting to Exchange");
- }
+ Console.WriteLine("Parsing HTML mail body...");
+ return $"This is the body of mail with id {identifier}";
}
- public class ApacheMailParser : MailParser
+ ///
+ /// Template method
+ ///
+ public string ParseMailBody(string identifier)
{
- public override void AuthenticateToServer()
- {
- Console.WriteLine("Connecting to Apache");
- }
+ Console.WriteLine("Parsing mail body (in template method)...");
+ FindServer();
+ AuthenticateToServer();
+ return ParseHtmlMailBody(identifier);
}
+}
- public class EudoraMailParser : MailParser
- {
- public override void FindServer()
- {
- Console.WriteLine("Finding Eudora server through a custom algorithm...");
- }
- public override void AuthenticateToServer()
- {
- Console.WriteLine("Connecting to Eudora");
- }
- }
+public class ExchangeMailParser : MailParser
+{
+ public override void AuthenticateToServer() => Console.WriteLine("Connecting to Exchange");
+}
+
+public class ApacheMailParser : MailParser
+{
+ public override void AuthenticateToServer() => Console.WriteLine("Connecting to Apache");
+}
+
+public class EudoraMailParser : MailParser
+{
+ public override void FindServer() => Console.WriteLine("Finding Eudora server through a custom algorithm...");
+ public override void AuthenticateToServer() => Console.WriteLine("Connecting to Eudora");
}
diff --git a/Finished sample/TemplateMethod/Program.cs b/Finished sample/TemplateMethod/Program.cs
index f4de8ca..6ccf979 100644
--- a/Finished sample/TemplateMethod/Program.cs
+++ b/Finished sample/TemplateMethod/Program.cs
@@ -1,5 +1,7 @@
using TemplateMethod;
+Console.Title = "Template Method";
+
ExchangeMailParser exchangeMailParser = new();
Console.WriteLine(exchangeMailParser.ParseMailBody("bf3a298c-9990-4b02-873d-3d3c98ad16d2"));
Console.WriteLine();
@@ -9,4 +11,6 @@
Console.WriteLine();
EudoraMailParser eudoraMailParser = new();
-Console.WriteLine(eudoraMailParser.ParseMailBody("789fe935-ced2-4fbd-865b-172909560a93"));
\ No newline at end of file
+Console.WriteLine(eudoraMailParser.ParseMailBody("789fe935-ced2-4fbd-865b-172909560a93"));
+
+Console.ReadKey();
\ No newline at end of file
diff --git a/Finished sample/TemplateMethod/TemplateMethod - Backup.csproj b/Finished sample/TemplateMethod/TemplateMethod - Backup.csproj
new file mode 100644
index 0000000..f02677b
--- /dev/null
+++ b/Finished sample/TemplateMethod/TemplateMethod - Backup.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+
diff --git a/Finished sample/Visitor/Implementation.cs b/Finished sample/Visitor/Implementation.cs
index 6c507f0..b9a5d2a 100644
--- a/Finished sample/Visitor/Implementation.cs
+++ b/Finished sample/Visitor/Implementation.cs
@@ -1,170 +1,135 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Visitor;
-namespace Visitor
+///
+/// ConcreteElement
+///
+public class Customer : IElement
{
- /////
- ///// Visitor
- /////
- //public interface IVisitor
- //{
- // void VisitCustomer(Customer customer);
- // void VisitEmployee(Employee employee);
- //}
+ public decimal AmountOrdered { get; }
+ public decimal Discount { get; set; }
+ public string Name { get; }
- ///
- /// Visitor (alternative)
- ///
- public interface IVisitor
+ public Customer(string name, decimal amountOrdered)
{
- void Visit(IElement element);
+ Name = name;
+ AmountOrdered = amountOrdered;
}
- ///
- /// Element
- ///
- public interface IElement
+ public void Accept(IVisitor visitor)
{
- void Accept(IVisitor visitor);
+ // visitor.VisitCustomer(this);
+ visitor.Visit(this);
+ Console.WriteLine($"Visited {nameof(Customer)} {Name}, " +
+ $"discount given: {Discount}");
}
+}
- ///
- /// ConcreteElement
- ///
- public class Customer : IElement
- {
- public decimal AmountOrdered { get; private set; }
- public decimal Discount { get; set; }
- public string Name { get; private set; }
+///
+/// ConcreteElement
+///
+public class Employee : IElement
+{
+ public int YearsEmployed { get; }
+ public decimal Discount { get; set; }
+ public string Name { get; }
- public Customer(string name, decimal amountOrdered)
- {
- Name = name;
- AmountOrdered = amountOrdered;
- }
-
- public void Accept(IVisitor visitor)
- {
- // alternative
- // visitor.VisitCustomer(this);
- visitor.Visit(this);
- Console.WriteLine($"Visited {nameof(Customer)} {Name}, discount given: {Discount}");
- }
+ public Employee(string name, int yearsEmployed)
+ {
+ Name = name;
+ YearsEmployed = yearsEmployed;
}
- ///
- /// ConcreteElement
- ///
- public class Employee : IElement
+ public void Accept(IVisitor visitor)
{
- public int YearsEmployed { get; private set; }
- public decimal Discount { get; set; }
- public string Name { get; private set; }
-
- public Employee(string name, int yearsEmployed)
- {
- Name = name;
- YearsEmployed = yearsEmployed;
- }
-
- public void Accept(IVisitor visitor)
- {
- // alternative
- // visitor.VisitEmployee(this);
- visitor.Visit(this);
- Console.WriteLine($"Visited {nameof(Employee)} {Name}, discount given: {Discount}");
- }
+ // visitor.VisitEmployee(this);
+ visitor.Visit(this);
+ Console.WriteLine($"Visited {nameof(Employee)} " +
+ $"{Name}, discount given: {Discount}");
}
+}
- /////
- ///// ConcreteVisitor
- /////
- //public class DiscountVisitor : IVisitor
- //{
- // public decimal TotalDiscountGiven { get; set; }
+/////
+///// Visitor
+/////
+//public interface IVisitor
+//{
+// void VisitCustomer(Customer customer);
+// void VisitEmployee(Employee employee);
+//}
+
+///
+/// Visitor (alternative)
+///
+public interface IVisitor
+{
+ void Visit(IElement element);
+}
- // public void VisitCustomer(Customer customer)
- // {
- // // percentage of total amount
- // var discount = customer.AmountOrdered / 10;
- // // set it on the customer
- // customer.Discount = discount;
- // // add it to the total amount
- // TotalDiscountGiven += discount;
- // }
+///
+/// Element
+///
+public interface IElement
+{
+ void Accept(IVisitor visitor);
+}
- // public void VisitEmployee(Employee employee)
- // {
- // // fixed value depending on the amount of years employed
- // var discount = employee.YearsEmployed < 10 ? 100 : 200;
- // // set it on the employee
- // employee.Discount = discount;
- // // add it to the total amount
- // TotalDiscountGiven += discount;
- // }
- //}
+///
+/// ConcreteVisitor
+///
+public class DiscountVisitor : IVisitor
+{
+ public decimal TotalDiscountGiven { get; set; }
- ///
- /// ConcreteVisitor (alternative)
- ///
- public class DiscountVisitor : IVisitor
+ public void Visit(IElement element)
{
- public decimal TotalDiscountGiven { get; set; }
-
- public void Visit(IElement element)
+ if (element is Customer customer)
{
- if (element is Customer)
- {
- VisitCustomer((Customer)element);
- }
- else if (element is Employee)
- {
- VisitEmployee((Employee)element);
- }
+ VisitCustomer(customer);
}
-
- private void VisitCustomer(Customer customer)
+ else if (element is Employee employee)
{
- // percentage of total amount
- var discount = customer.AmountOrdered / 10;
- // set it on the customer
- customer.Discount = discount;
- // add it to the total amount
- TotalDiscountGiven += discount;
+ VisitEmployee(employee);
}
+ }
- private void VisitEmployee(Employee employee)
- {
- // fixed value depending on the amount of years employed
- var discount = employee.YearsEmployed < 10 ? 100 : 200;
- // set it on the employee
- employee.Discount = discount;
- // add it to the total amount
- TotalDiscountGiven += discount;
- }
+ void VisitCustomer(Customer customer)
+ {
+ // percentage of total amount
+ var discount = customer.AmountOrdered / 10;
+ // set it on the customer
+ customer.Discount = discount;
+ // add it to the total amount
+ TotalDiscountGiven += discount;
}
- ///
- /// ObjectStructure
- ///
- public class Container
+ void VisitEmployee(Employee employee)
{
- public List Employees { get; set; } = new();
- public List Customers { get; set; } = new();
+ // fixed value depending on the amount of years employed
+ var discount = employee.YearsEmployed < 10 ? 100 : 200;
+ // set it on the employee
+ employee.Discount = discount;
+ // add it to the total amount
+ TotalDiscountGiven += discount;
+ }
+}
+
+///
+/// ObjectStructure
+///
+public class Container
+{
+ public List Employees { get; set; } = new();
+ public List Customers { get; set; } = new();
- public void Accept(IVisitor visitor)
+ public void Accept(IVisitor visitor)
+ {
+ foreach (Employee employee in Employees)
+ {
+ employee.Accept(visitor);
+ }
+ foreach (Customer customer in Customers)
{
- foreach (var employee in Employees)
- {
- employee.Accept(visitor);
- }
- foreach (var customer in Customers)
- {
- customer.Accept(visitor);
- }
+ customer.Accept(visitor);
}
}
-}
+}
\ No newline at end of file
diff --git a/Finished sample/Visitor/Program.cs b/Finished sample/Visitor/Program.cs
index 4d28a5a..be089bc 100644
--- a/Finished sample/Visitor/Program.cs
+++ b/Finished sample/Visitor/Program.cs
@@ -1,7 +1,10 @@
using Visitor;
-// create container & add conrete elements
+Console.Title = "Visitor";
+
+// create container & add concrete elements
var container = new Container();
+
container.Customers.Add(new Customer("Sophie", 500));
container.Customers.Add(new Customer("Karen", 1000));
container.Customers.Add(new Customer("Sven", 800));
@@ -15,4 +18,6 @@
container.Accept(discountVisitor);
// write out gathered amount
-Console.WriteLine($"Total discount: {discountVisitor.TotalDiscountGiven}");
\ No newline at end of file
+Console.WriteLine($"Total discount: {discountVisitor.TotalDiscountGiven}");
+
+Console.ReadKey();
\ No newline at end of file