/* This is my own example of the Factory Method pattern. Its principal difference from the example on the patterns website is that it separates the interface from the abstract class. Like Java, C# prohibits multiple-inheritance. You can implement as many interfaces as you want, but you can only inherit code from one class. If you use that class for the purpose of the interface, you would not have the flexibility of inheriting from other classes. */ using System; using System.Collections.Generic; // product/ingredient (abstract items to be produced by factory) public interface ingredient {} public interface topping : ingredient {} // a topping is also an ingredient // concrete product/ingredients: class pepperoni : topping {} class cheese : ingredient {} class tomatosauce : ingredient{} class dough : ingredient {} class sausage : topping {} class mushrooms : topping {} class pineapple : topping {} class bbqchicken : topping {} class greenpeppers : topping {} class canadianbacon : topping {} // "Creator" - the pizza factory interface - every factory must define // makepizza interface pizza { double price(); // abstract properties of pizzas int calories(); void makepizza(); } // factory dispatch, also makes plain pizza by default. // this is called the abstract creator class plain // inheritance base class: note a "plain" IS NOT a pizza. { protected List A = new List(); // list of ingredients protected int cals = 1000; // calories public plain() // dispatches to makepizza proc based on dynamic type { A.Add(new dough()); A.Add(new cheese()); A.Add(new tomatosauce()); makepizza(); // dispatch to subclass method // ... bake ... Console.WriteLine("pizza with "+A.Count+" ingredients created"); } // default makepizza make a plain cheese pizza public virtual void makepizza() { /* nothing to do in default */ } public virtual double price() {return 9.99;} public int calories() { return cals; } } //plain // Concrete Factories: type of these factories is "pizza", while // they inherit the code in "plain" and override the method makepizza. class cheesepizza : plain, pizza // just an alias? {} class pepperonipizza : plain, pizza { public override void makepizza() { A.Add( new pepperoni() ); cals += 400; } public override double price() { return 10.99; } } class hawaiian : plain, pizza { public override void makepizza() { A.Add(new canadianbacon()); A.Add(new pineapple()); cals += 500; } public override double price() { return 11.99; } } class veggiepizza : plain, pizza // for vegetarians { public override void makepizza() { A.Add(new mushrooms()); A.Add(new greenpeppers()); cals += 100; } public override double price() { return 10.99; } } public class pizzafactory2010 // test client { public static void Main() { pizza[] order = { new cheesepizza(), new hawaiian(), new pepperonipizza(), new veggiepizza() }; double cost = 0; foreach (pizza p in order) cost += p.price(); Console.WriteLine("Pay me "+cost+". Bon appetite."); } }