/* 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; // product/ingridient (abstract items to be produced by factory) public interface ingridient {} public interface topping : ingridient {} // concrete product/ingridients: class pepperoni : topping {} class cheese : ingridient {} class tomatosauce : ingridient{} class dough : ingridient {} class sausage : topping {} class mushrooms : topping {} class pineapple : topping {} class bbqchicken : topping {} class greenpeppers : topping {} class canadianbacon : topping {} // simple linked list class of ingredients: class cons { public ingridient car; public cons cdr; public cons(ingridient a, cons b) { car=a; cdr=b; } public int length() // length of list { if (cdr==null) return 1; else return 1+cdr.length(); } public string tostring() // string rep for printing { string s=""; for(cons i=this;i!=null;i=i.cdr) { s=s+i+"-"; } return s; } } // cons cell class // creator - the pizza factory interface - every factory must define // makepizza interface pizza { void makepizza(); // can also call this "the factory method" double price(); // other abstract properties of pizzas } // factory dispatch, also makes plain pizza by default. // this is called the abstract creator class plain : pizza { public cons A = null; // list of ingredients public plain() // dispatches to correct makepizza proc based on dyn. type { A = new cons(new dough(),new cons(new tomatosauce(), new cons(new cheese(),null))); this.makepizza(); // dispatch to subclass method int l = A.length(); Console.WriteLine("pizza with "+l+" ingridients created"); } // default makepizza make a plain chees pizza public virtual void makepizza() { /* nothing else to do for plain pizza */ } public virtual double price() { return 8.99; } } // concrete factories: type type of these factories is "pizza", while // they inherit the code in "plain" and override makepizza. class pepperonipizza : plain, pizza { public override void makepizza() { A = new cons(new pepperoni(),A); // add new ingridient to existing list } public override double price() { return 9.99; } } class hawaiian : plain, pizza { public override void makepizza() { A = new cons(new canadianbacon(), new cons(new pineapple(),A)); } public override double price() { return 10.99; } } class veggiepizza : plain, pizza { public override void makepizza() { A = new cons(new mushrooms(), new cons(new greenpeppers(),A)); } public override double price() { return 9.99; } } public class pizzafactory // test client { public static void Main() { pizza p1, p2, p3, p4; p1 = new plain(); p2 = new hawaiian(); p3 = new pepperonipizza(); p4 = new veggiepizza(); double cost = p1.price()+p2.price()+p3.price()+p4.price(); Console.WriteLine("Pay me "+cost+". Bon appetite."); } }