static void Main(string[] args) { 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 p in pf.FilterByColor(products, Color.Green)) { Console.WriteLine($" - {p.Name} is green"); } var bf = new BetterFilter(); Console.WriteLine("Green products (new): "); foreach (var p in bf.Filter(products, new ColorSpecification(Color.Green))) { Console.WriteLine($" - {p.Name} is green"); } Console.WriteLine("Large blue items:"); foreach (var p in bf.Filter(products, new AndSpecification <Product>(new ColorSpecification(Color.Blue) , new SizeSpecification(Size.Large)))) { Console.WriteLine($" - {p.Name} is big and blue"); } Console.ReadKey(); }
static void Main(string[] args) { var fender = new Product("Fender", Color.Green, Size.Small); var gibson = new Product("Gibson", Color.Blue, Size.Large); var martin = new Product("Martin", Color.Red, Size.Large); Product[] products = { fender, gibson, martin }; //OLD WAY ###################################### //var pf = new ProductFilter(); //WriteLine("Green products (old):"); //foreach (var p in pf.FilterByColor(products, Color.Green)) //{ // WriteLine($" - {p.Name} is green"); //} //NEW WAY ####################################### var bf = new BetterFilter(); WriteLine("Green products (new): "); foreach (var p in bf.Filter(products, new ColorSpecification(Color.Green))) { WriteLine($" - {p.Name} is green"); } //NEW WAY WITH COMBINATOR SPECIFICATION ############### WriteLine("Large blue products (new): "); foreach (var p in bf.Filter(products, new AndSpecification <Product>(new ColorSpecification(Color.Blue), new SizeSpecification(Size.Large)))) { WriteLine($" - {p.Name} is blue and large"); } }
private static void Main(string[] args) { var products = new[] { new Product("Coffee Table", Color.Yellow, Size.Large), new Product("iPhone 6S", Color.Blue, Size.Small), new Product("Tesla Model S", Color.Green, Size.Large), new Product("House", Color.Red, Size.Huge), new Product("Chair", Color.Green, Size.Medium) }; // WrongFilter class is an example of violation of Open / Closed principle. // According to the principle, if we have a tested, working class, in order to // introduce a new functionality we shall not have to modify the class, but, extend it // by using various methods / patterns. // In this example, WrongFilter class can perfectly filter products by their color // or size with it's two methods. Problem arises when we need to introduce new functionality // like "Filter by color and size". With the current iteration, we have to change WrongFilter class // and introduce a new method to it. This violates the Open / Closed principle. foreach (var product in WrongFilter.FilterByColor(products, Color.Green)) { WriteLine($"{product.Name} is a {product.Color} product"); } // With open / closed principle in mind, we created a new class called BetterFilter. // this class implements specification pattern and instead of bringing methods for individual // filtering actions, it introduces interfaces to define filtering specifications and a filter // method using those specifications. // With this approach, we can easily introduce new filtering mechanisms without ever touching BetterFilter // class and by simply creating new ISpecification<T> implementation for requirements. var filter = new BetterFilter(); foreach (var product in filter.Filter(products, new ColorSpecification(Color.Blue))) { WriteLine($"{product.Name} is a {product.Color} product"); } // In this example we filter Green and Medium products. foreach (var product in filter.Filter(products, new AndSpec <Product>(new ColorSpecification(Color.Green), new SizeSpecification(Size.Medium)))) { WriteLine($"{product.Name} is a {product.Color} and {product.Size} product"); } }
static void Main(string[] args) { Product[] products = new Product[] { new Product("Apple", Color.Green, Size.Small), new Product("Tree", Color.Green, Size.Huge), new Product("House", Color.Blue, Size.Huge) }; var pf = new ProductFilter(); foreach (var p in pf.FilterByColor(products, Color.Green)) { Console.WriteLine($" - {p.Name} is green"); } var bf = new BetterFilter(); foreach (var p in bf.Filter(products, new ColorSpecificaiton(Color.Green))) { Console.WriteLine($" - {p.Name} is green"); } var bf2 = new BetterFilter(); foreach (var p in bf2.Filter(products, new AndSpecification <Product>(new ColorSpecificaiton(Color.Green), new SizeSpecification(Size.Huge)))) { Console.WriteLine($" - {p.Name} is green and huge"); } Console.ReadKey(); // Go to http://aka.ms/dotnet-get-started-console to continue learning how to build a console app! }