public static void Start() { var apple = new Product("Apple", Color.Red, Size.Medium); var tree = new Product("Tree", Color.Green, Size.Large); var house = new Product("House", Color.Green, Size.Medium); Product[] products = { apple, tree, house }; var productFilter = new ProductFilter(); Console.WriteLine("Filter by Size {Medium}"); foreach (var item in productFilter.FilterBySize(products, Size.Medium)) { Console.WriteLine($"- {item.Name}, {item.Color}, {item.Size}"); } Console.WriteLine("Filter by Color {Green}"); foreach (var item in productFilter.FilterByColor(products, Color.Green)) { Console.WriteLine($"- {item.Name}, {item.Color}, {item.Size}"); } Console.WriteLine("Open Close Better filter"); var betterFilter = new BetterFilter(); foreach (var item in betterFilter.Filter(products, new ColorSpecification(Color.Green))) { Console.WriteLine($"- {item.Name}, {item.Color}, {item.Size}"); } Console.WriteLine("Filter by Size {Medium}"); foreach (var item in betterFilter.Filter(products, new SizeSpecification(Size.Medium))) { Console.WriteLine($"- {item.Name}, {item.Color}, {item.Size}"); } Console.WriteLine("Combination"); var andSpecification = new AndSpecification <Product>( new ColorSpecification(Color.Green), new SizeSpecification(Size.Medium)); foreach (var item in betterFilter.Filter(products, andSpecification)) { Console.WriteLine($"- {item.Name}, {item.Color}, {item.Size}"); } }
static void OpenClosed() { var products = new Product[] { new Product("Apple", Color.Green, Size.Small), new Product("Tree", Color.Green, Size.Large), new Product("House", Color.Blue, Size.Large) }; Console.WriteLine("Green Products (old filter)"); foreach (Product p in ProductFilter.FilterByColor(products, Color.Green)) { Console.WriteLine($"\t{p.Name} is {p.Color}"); } Console.WriteLine("Green Products (better filter)"); var bf = new BetterProductFilter(); foreach (Product p in bf.Filter(products, new ColorSpecification(Color.Green))) { Console.WriteLine($"\t{p.Name} is {p.Color}"); } // Abstracted logic that is open to extension (create new ISpecifications), but closed to modification (should never have to edit BetterProductFilter) Console.WriteLine("Green & Large Products (better filter)"); var andSpecification = new AndSpecification <Product>(new ColorSpecification(Color.Green), new SizeSpecification(Size.Large)); foreach (Product p in bf.Filter(products, andSpecification)) { Console.WriteLine($"\t{p.Name} is {p.Color} and {p.Size}"); } // Abstracted logic that is open to extension (create new ISpecifications), but closed to modification (should never have to edit BetterProductFilter) Console.WriteLine("Blue or Small Products (better filter)"); var orSpecification = new OrSpecification <Product>(new ColorSpecification(Color.Blue), new SizeSpecification(Size.Small)); foreach (Product p in bf.Filter(products, orSpecification)) { Console.WriteLine($"\t{p.Name} is {p.Color} and {p.Size}"); } }
static void Main(string[] args) { #region Single Responsability Principle var j = new Journal(); j.AddEntry("I cried today."); j.AddEntry("I ate a bug."); Console.WriteLine(j); var p = new Persistence(); var filename = @"c:\temp\journal.txt"; p.SaveToFile(j, filename); Process.Start(filename); #endregion #region Open-Closed Principle var apple = new Product("Apple", Color.Green, Size.Small); var tree = new Product("Tree", Color.Green, Size.Large); var house = new Product("House", Color.Blue, Size.Large); Product[] products = { apple, tree, house }; var pf = new ProductFilter(); Console.WriteLine("Green products (old):"); foreach (var pfp in pf.FilterByColor(products, Color.Green)) { Console.WriteLine($" - {pfp.Name} is green"); } // ^^ BEFORE // vv AFTER var bf = new BetterFilter(); Console.WriteLine("Green products (new):"); foreach (var pfp in bf.Filter(products, new ColorSpecification(Color.Green))) { Console.WriteLine($" - {pfp.Name} is green"); } Console.WriteLine("Large products"); foreach (var pfp in bf.Filter(products, new SizeSpecification(Size.Large))) { Console.WriteLine($" - {pfp.Name} is large"); } Console.WriteLine("Large blue items"); foreach (var pfp in bf.Filter(products, new AndSpecification <Product>(new ColorSpecification(Color.Blue), new SizeSpecification(Size.Large))) ) { Console.WriteLine($" - {pfp.Name} is big and blue"); } #endregion #region Liskov Substitution Rectangle rc = new Rectangle(2, 3); Console.WriteLine($"{rc} has area {Area(rc)}"); // should be able to substitute a base type for a subtype /*Square*/ Rectangle sq = new Square(); sq.Width = 4; Console.WriteLine($"{sq} has area {Area(sq)}"); #endregion #region Interface Segregation #endregion #region Dependency Inversion var parent = new Person { Name = "John" }; var child1 = new Person { Name = "Chris" }; var child2 = new Person { Name = "Matt" }; // low-level module var relationships = new Relationships(); //relationships.AddParentAndChild(parent, child1); //relationships.AddParentAndChild(parent, child2); new Research(relationships); #endregion Console.ReadKey(); }