工厂模式

1.定义了一个创建对象的接口,工厂方法创建一个框架,让子类决定如何实现

2.代码:

C++

  1 //factory c++
  2 #include <iostream>
  3 #include <string>
  4 using namespace std;
  5 
  6 //面团 
  7 class Dough{
  8 public:
  9     virtual string getIngredientInfo() = 0;
 10 };
 11 //薄饼
 12 class ThinCrustDough : public Dough {
 13 public:
 14     string getIngredientInfo() {
 15         return "Thin Crust Dough";
 16     }
 17 };
 18 //厚的
 19 class ThickCrustDough : public Dough {
 20 public:
 21     string getIngredientInfo(){
 22         return "ThickCrust style extra thick crust dough";
 23     }
 24 };
 25 
 26 //酱料
 27 class Sauce {
 28 public:
 29     virtual string getIngredientInfo() = 0;
 30 };
 31 //意大利红酱
 32 class MarinaraSauce : public Sauce {
 33 public:
 34     string getIngredientInfo(){
 35         return "Marinara Sauce";
 36     }
 37 };
 38 //番茄酱
 39 class PlumTomatoSauce : public Sauce {
 40 public:
 41     string getIngredientInfo() {
 42         return "Tomato sauce with plum tomatoes";
 43     }
 44 };
 45 
 46 //奶酪
 47 class Cheese {
 48 public:
 49     virtual string getIngredientInfo() = 0;
 50 };
 51 //莫泽雷勒干酪
 52 class MozzarellaCheese : public Cheese {
 53 public:
 54     string getIngredientInfo(){
 55         return "Shredded Mozzarella";
 56     }
 57 };
 58 //巴马干酪
 59 class ReggianoCheese : public Cheese {
 60 public:
 61     string getIngredientInfo(){
 62         return "Reggiano Cheese";
 63     }
 64 };
 65 
 66 //原材料
 67 class PizzaIngredientFactory{
 68 public:
 69     virtual Dough  * createDough()  = 0;
 70     virtual Sauce  * createSauce()  = 0;
 71     virtual Cheese * createCheese() = 0;
 72     //...
 73 };
 74 
 75 //生产 纽约口味
 76 class NYPizzaIngredientFactory : public PizzaIngredientFactory{
 77 public:
 78     Dough* createDough(){
 79         return new ThinCrustDough();
 80     }
 81     Sauce* createSauce(){
 82         return new MarinaraSauce();
 83     }
 84     Cheese* createCheese(){
 85         return new ReggianoCheese();
 86     }
 87 };
 88 
 89 //生产 芝加哥口味
 90 class ChicagoPizzaIngredientFactory : public PizzaIngredientFactory{
 91 public: 
 92     Dough* createDough(){
 93         return new ThickCrustDough();
 94     }
 95     Sauce* createSauce(){
 96         return new PlumTomatoSauce();
 97     }
 98     Cheese* createCheese(){
 99         return new MozzarellaCheese();
100     }
101 };
102 
103 //披萨
104 class Pizza{
105 public:
106     virtual void prepare() = 0;           //统一原材料配给
107     
108     void bake()                { cout<<"Bake for 25 minutes..."<<endl; }
109     void box()                 { cout<<"box done"<<endl; }
110     
111     void   setName(string name){ this->name = name; }
112     string getName()           { return this->name; }
113     string getIngredientInfo() {
114         string str = "---- ";
115                str += this->name;
116                str += " ----\n";
117         if (dough) {
118             str += dough->getIngredientInfo() + "\n\r";
119         }
120         if (sauce) {
121             str += sauce->getIngredientInfo() + "\n\r";
122         }
123         if (cheese) {
124             str += cheese->getIngredientInfo() + "\n\r";
125         }
126         return str;
127     }
128 
129     string  name;
130     Dough * dough;  //
131     Sauce * sauce;  //酱料
132     Cheese* cheese; //奶酪
133 };
134 
135 //生产奶酪披萨
136 class CheesePizza : public Pizza{
137 public:
138     CheesePizza(PizzaIngredientFactory* factory): m_ingredientFactory(factory){}
139     void prepare(){
140         cout<<"Preparing "<<this->getName()<<endl;
141         dough  = m_ingredientFactory->createDough();
142         sauce  = m_ingredientFactory->createSauce();
143         cheese = m_ingredientFactory->createCheese(); 
144     }
145 private:
146     PizzaIngredientFactory* m_ingredientFactory;
147 };
148 
149 //披萨店
150 class PizzaStore{
151 public:
152     virtual Pizza* createPizza(string type) = 0; //不同地域口味的披萨
153     Pizza* orderPizza(string type)              //统一品牌流程
154     {
155         Pizza* pizza = createPizza(type);
156         pizza->prepare();
157         pizza->bake();
158         pizza->box();
159         return pizza;
160     }
161 };
162 
163 //纽约的加盟店
164 class NYPizzaStore : public PizzaStore{
165 public:
166     Pizza* createPizza(string type){
167         Pizza *pizza = NULL;
168         PizzaIngredientFactory* ingredientFactory = new NYPizzaIngredientFactory();
169         if("cheese" == type){
170             pizza = new CheesePizza(ingredientFactory);
171             pizza->setName("New York Style Cheese Pizza");
172         }
173         else if("veggie" == type){
174             //...
175         }
176         return pizza;
177     }
178 };
179 
180 //芝加哥的
181 class ChicagoPizzaStore : public PizzaStore{
182 public:
183     Pizza* createPizza(string type){
184         Pizza *pizza = NULL;
185         PizzaIngredientFactory* ingredientFactory = new ChicagoPizzaIngredientFactory();
186         if("cheese" == type){
187             pizza = new CheesePizza(ingredientFactory);
188             pizza->setName("Chicago Style Cheese Pizza");
189         }
190         else if("veggie" == type){
191             //...
192         }
193         return pizza;
194     }
195 };
196 
197 //点餐
198 int main()
199 {
200     //1
201     PizzaStore *nyStore = new NYPizzaStore();
202     Pizza      *pizza   = nyStore->orderPizza("cheese");
203     cout<<"order a " <<pizza->getIngredientInfo()<<endl;
204     //2
205     PizzaStore *chStore = new ChicagoPizzaStore();
206                 pizza   = chStore->orderPizza("cheese");
207     cout<<"order a " <<pizza->getIngredientInfo();
208     return 0;
209 }

  Java

  1 //factory java
  2 
  3 //PizzaStore
  4 abstract class PizzaStore{
  5     public final Pizza orderPizza(String type){ //order same
  6         Pizza pizza;
  7         pizza = createPizza(type);              //
  8         pizza.prepare();
  9         pizza.bake();
 10         pizza.box();
 11         return pizza;
 12     }
 13     abstract Pizza createPizza(String type);    //taste different in other area
 14 }
 15 
 16 //New York Pizza Store
 17 class NYPizzaStore extends PizzaStore{
 18     Pizza createPizza(String item){
 19         Pizza pizza = null;
 20         PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
 21         if(item.equals("cheese")){
 22             pizza = new CheesePizza(ingredientFactory);
 23             pizza.setName("New York Style Cheese Pizza");
 24         }
 25         else if(item.equals("veggie")){
 26             //...
 27         }
 28         return pizza;
 29     }
 30 }
 31 //Chicago Pizza Store
 32 class ChicagoPizzaStore extends PizzaStore{
 33     Pizza createPizza(String item){
 34         Pizza pizza = null;
 35         PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();
 36         if(item.equals("cheese")){
 37             pizza = new CheesePizza(ingredientFactory);
 38             pizza.setName("Chicago Style Cheese Pizza");
 39         }
 40         else if(item.equals("veggie")){
 41             //...
 42         }
 43         return pizza;
 44     }
 45 }
 46 
 47 //Pizza
 48 abstract class Pizza{
 49     String name;
 50     Dough  dough;
 51     Sauce  sauce;
 52     Cheese cheese;
 53     //ArrayList<String> toppings = new ArrayList<String>();
 54     
 55     abstract void prepare();   //
 56     void bake(){
 57         System.out.println("Bake for 25 minutes...");
 58     }
 59     //...
 60     void box(){
 61         System.out.println("box done");
 62     }
 63     void setName(String name){
 64         this.name = name;
 65     }
 66     public String getName(){
 67         return name;
 68     }
 69     public String toString() {
 70         StringBuffer result = new StringBuffer();
 71         result.append("---- " + name + " ----\n");
 72         if (dough != null) {
 73             result.append(dough);
 74             result.append("\n");
 75         }
 76         if (sauce != null) {
 77             result.append(sauce);
 78             result.append("\n");
 79         }
 80         if (cheese != null) {
 81             result.append(cheese);
 82             result.append("\n");
 83         }
 84         return result.toString();
 85     }
 86 }
 87 
 88 //CheesePizza
 89 //do not need class NYStyleCheesePizza and class ChicagoStyleCheesePizza
 90 class CheesePizza extends Pizza{
 91     PizzaIngredientFactory ingredientFactory;
 92     public CheesePizza(PizzaIngredientFactory ingredientFactory){
 93         this.ingredientFactory = ingredientFactory;
 94     }
 95     void prepare(){
 96         System.out.println("Preparing " + name);
 97         dough  = ingredientFactory.createDough();
 98         sauce  = ingredientFactory.createSauce();
 99         cheese = ingredientFactory.createCheese(); 
100     }
101 }
102 
103 //ingredient factory
104 interface PizzaIngredientFactory{
105     public Dough  createDough();
106     public Sauce  createSauce();
107     public Cheese createCheese();
108     //...
109 }
110 
111 //NYPizzaIngredientFactory
112 class NYPizzaIngredientFactory implements PizzaIngredientFactory{
113     public Dough createDough(){
114         return new ThinCrustDough();
115     }
116     public Sauce createSauce(){
117         return new MarinaraSauce();
118     }
119     public Cheese createCheese(){
120         return new ReggianoCheese();
121     }
122 } 
123 
124 //ChicagoPizzaIngredientFactory
125 class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory{
126     public Dough createDough(){
127         return new ThickCrustDough();
128     }
129     public Sauce createSauce(){
130         return new PlumTomatoSauce();
131     }
132     public Cheese createCheese(){
133         return new MozzarellaCheese();
134     }
135 }
136 
137 //Dough
138 interface Dough {
139     public String toString();
140 }
141 class ThinCrustDough implements Dough {
142     public String toString() {
143         return "Thin Crust Dough";
144     }
145 }
146 class ThickCrustDough implements Dough {
147     public String toString() {
148         return "ThickCrust style extra thick crust dough";
149     }
150 }
151 
152 //Sauce
153 interface Sauce {
154     public String toString();
155 }
156 class MarinaraSauce implements Sauce {
157     public String toString() {
158         return "Marinara Sauce";
159     }
160 }
161 class PlumTomatoSauce implements Sauce {
162     public String toString() {
163         return "Tomato sauce with plum tomatoes";
164     }
165 }
166 
167 //Cheese
168 interface Cheese {
169     public String toString();
170 }
171 class MozzarellaCheese implements Cheese {
172 
173     public String toString() {
174         return "Shredded Mozzarella";
175     }
176 }
177 class ReggianoCheese implements Cheese {
178 
179     public String toString() {
180         return "Reggiano Cheese";
181     }
182 }
183 
184 //SimpleFactory
185 public class SimpleFactory{
186     public static void main(String[] args){
187         //1
188         PizzaStore nyStore = new NYPizzaStore();
189         Pizza      pizza   = nyStore.orderPizza("cheese");
190         System.out.println("order a " + pizza);
191         
192         //2
193         PizzaStore chStore = new ChicagoPizzaStore();
194                    pizza   = chStore.orderPizza("cheese");
195         System.out.println("order a " + pizza);
196     }
197 }

  3.杂记:

(1)“实现一个接口” 并不一定 表示写一个类并利用 implements 实现某个java接口;

         “实现一个接口” 泛指实现某个超类型(类或接口)

(2)一个好的加盟店 不需要 管他在披萨中放了什么东西(允许厨师创意)

(3)参数可以利用enum等防止写错

(4)“依赖倒置原则”(Pependency Inversion Principle)

           依赖抽象,不依赖具体类,听起来像“针对接口..不针对实现”;

           意思是:高层组件 和 低层组件都依赖抽象,而不是高层依赖低层,低层能变成了实现;(披萨各地口味不同,奶酪披萨各地口味再由配料组成)

          “倒置”:不是从顶部(披萨店)开始然后往下到具体类, 否则披萨店将全部依赖这些具体类;

                      而是从Pizza开始(别从顶端开始)然后想想看能抽象化些什么

                      依赖一个工厂 将具体类从披萨店取出,

                      倒置了一个商店依赖具体类的设计,也倒置了思考方式

(5)尽量,非必须:

                    变量不可以持有具体类的引用

                    不让类派生自具体类

                    不覆盖基类已实现方法

(6)如果一个类可能改变,可以采用一些好的技巧(例如工厂)来封装改变

  (7)  “抽象工厂” 和 “工厂方法” 是两个东西:

         抽象工厂:提供创建一个产品族的抽象类型(Pizza类:能生产各种披萨);

         工厂方法:创建一个产品(PizzaStore的实现为工厂方法:纽约店,芝加哥店);

 

posted @ 2020-04-10 03:01  三岁玩童  阅读(160)  评论(0编辑  收藏  举报