工厂模式
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的实现为工厂方法:纽约店,芝加哥店);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通