1.工厂模式的初心,本质
工厂模式:本质是创建类的实例,将类的实例的创建和使用隔离。
模型特点:创建时根据参输的不同返回不同的实例。而这些个不同的类型的实例,都是同一个基类的实例。简单工厂的特点:
定义了一个类,这个类专门用于创建其他类的实例,这些被创建的类都有一个共同的父类。
工厂模式的特点:
当这基类的子类因为业务分类为不同分组时,将简单工厂抽象出为接口,接口的不同实现中分别做对应的分组的实例创建。 特别的,这里工厂模式本质不变,只是对基类是实例的创建作了分组,不同分组各自做自己的 类的创建。
抽象工厂模式的特点:
工厂模式中根据某个业务条件做了类的实例创建上的分组。但现在说除了 这个分组,还有个另一个维度的分组。这个时候实例的创建上就得考虑两个维度的事情。此时,要做的就是对外统一提供一个工厂类,用于实例的创建。对内将新的维度再次抽象出一个接口,用不同的实现类来做新维度的分类处理。
即经验上来讲,用一般维度的划分不会太多,第二个维度,多会出现业务上的分族处理。
2.解决了什么问题
在于当你需要什么实例,只需要传入一个正确的参数,就可以获取你所需要的类的实例,而无须知道其创建细节。
3.工厂模式结构图
简单
模式分析:
Factory:工厂角色。专门用于创建实例类的工厂,提供一个方法,该方法根据传递的参数不同返回不同类的具体实例。
Product:抽象产品角色。为所有产品的父类。
ConcreteProduct:具体的产品角色。
简单工厂模式将对象的创建和对象本身业务处理分离了,可以降低系统的耦合度,使得两者修改起来都相对容易些。当以后实现改变时,只需要修改工厂类即可。
工厂模式:
Pizz:抽象产品:披萨。所有的披萨产品必须实现这个共同的接口,这样一来,使用这些产品的类既可以引用这个接口。而不是具体类。
NYStyleCheesePizza:具体一种披萨。
ChiagoStyleCh eesePizza:具体一种披萨。
PizaStore:抽象工厂。它实现了所有操纵产品的方法,但不实现工厂方法,即披萨类实例创建的方法。具体披萨实例创建的方法都在实现类中去做。这样就做到了分组。
NYPizzaStore、ChicagoPizzaStore:具体工厂。制造产品的实际工厂。各自负责创建各自分组的披萨实例。
抽象工厂模式:
模式结构说明。
AbstractFactory:抽象工厂。抽象工厂定义了一个接口,所有的具体工厂都必须实现此接口,这个接口包含了一组方法用来生产产品。
ConcreteFactory:具体工厂。具体工厂是用于生产不同产品族。要创建一个产品,客户只需要使用其中一个工厂完全不需要实例化任何产品对象。
AbstractProduct:抽象产品。这是一个产品家族,每一个具体工厂都能够生产一整组产品。
Product:具体产品。
本质上还是一个系统的产品比如说披萨,由两个维度作了分类。比如一个是产品口味,一个是产品原料地。
这个思想可以迁移到产品个族中,比如格力,可以生产冰箱族,可以生产空调族,冰箱族中又有不同品牌的冰箱,空调族中又有不同型号的空调。
4.实战
4.1、简单工厂模式实战
模式场景:
在一个披萨店中,要根据不同客户的口味,生产不同的披萨,如素食披萨、希腊披萨等披萨。
package com.example.demo.factory.simpleFactory.module; /** * 抽象披萨类 */ public abstract class Pizza { public abstract void prepare(); public abstract void bake(); public abstract void cut(); public abstract void box(); }
package com.example.demo.factory.simpleFactory.module; /** *具体的某种披萨 */ public class CheesePizza extends Pizza { @Override public void bake() { System.out.println("bake CheesePizza ..."); } @Override public void box() { System.out.println("box CheesePizza ..."); } @Override public void cut() { System.out.println("cut CheesePizza ..."); } @Override public void prepare() { System.out.println("prepare CheesePizza ..."); } }
package com.example.demo.factory.simpleFactory; import com.example.demo.factory.simpleFactory.module.CheesePizza; import com.example.demo.factory.simpleFactory.module.Pizza; /** * 披萨工厂类,用于创建不同类型口味的披萨 */ public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if (type.equals("cheese")) { pizza = new CheesePizza(); System.out.println("cheese pizza make successful"); } // else if (type.equals("clam")) { // pizza = new ClamPizza(); // } else if (type.equals("pepperoni")) { // pizza = new PepperoniPizza(); // } else if (type.equals("veggie")) { // pizza = new VeggiePizze(); // // } return pizza; } }
package com.example.demo.factory.simpleFactory; import com.example.demo.factory.simpleFactory.module.Pizza; /** * 披萨商场需要往外卖披萨,在披萨生产(实例创建时只需要调用披萨生产工厂就行,至于烘烤,切块,装盒等等其他工功能属性走其他流程) */ public class PizzaStore { //SimplePizzaFactory的引用 SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } public Pizza orderPizza(String type) { // //使用工厂对象的创建方法,而不是直接new。这里不再使用具体实例化 Pizza pizza; pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } public static void main(String[] args) { new PizzaStore(new SimplePizzaFactory()).orderPizza("cheese"); } }
4.2、工厂模式实战
模式场景:
通过披萨的实例介绍了简单工厂模式。在披萨实例中,如果我想根据地域的不同生产出不同口味的披萨,如纽约口味披萨,芝加哥口味披萨。如果利用简单工厂模式,我们需要两个不同的工厂,NYPizzaFactory、ChicagoPizzaFactory。在该地域中有很多的披萨店,他们并不想依照总店的制作流程来生成披萨,而是希望采用他们自己的制作流程。本质上是披萨生产要分组了。此时披萨的生产用工厂模式。、
package com.example.demo.factory.factory;
import com.example.demo.factory.module.Pizza;
/**
* 通过工厂模式创建披萨实例,其他业务问题交给其他逻辑处理,也可以封装在对应工厂类型地下去处理,就是一个入口通过入参驱动类型,往下是越来越复杂
*/
public abstract class PizzaStore {
/*
* 创建pizza的方法交给对应类别的子类去实现
*/
abstract Pizza createPizza(String type);
public Pizza orderPizza(String type) {
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
package com.example.demo.factory.factory;
import com.example.demo.factory.module.NYStyleCheesePizza;
import com.example.demo.factory.module.Pizza;
/**
* 具体工厂。披萨分店。NYPizzaStore.java
*/
public class NYPizzaStoreFactory extends PizzaStore {
@Override
Pizza createPizza(String item) {
Pizza pizza = null;
if ("cheese".equals(item)) {
pizza = new NYStyleCheesePizza();
}
// else if ("veggie".equals(item)) {
// pizza = new NYStyleVeggiePizza();
// } else if ("clam".equals(item)) {
// pizza = new NYStyleClamPizza();
// } else if ("pepperoni".equals(item)) {
// pizza = new NYStylePepperoniPizza();
// }
return pizza;
}
}
package com.example.demo.factory.factory;
import com.example.demo.factory.module.ChicagoStyleCheesePizza;
import com.example.demo.factory.module.Pizza;
public class ChicagoPizzaStoreFactory extends PizzaStore {
@Override
Pizza createPizza(String type) {
Pizza pizza = null;
if ("cheese".equals(type)) {
pizza = new ChicagoStyleCheesePizza();
}
// else if ("clam".equals(type)) {
// pizza = new ChicagoStyleClamPizza();
// } else if ("pepperoni".equals(type)) {
// pizza = new ChicagoStylePepperoniPizza();
// } else if ("veggie".equals(type)) {
// pizza = new ChicagoStyleVeggiePizza();
// }
return pizza;
}
}
package com.example.demo.factory.module;
import java.util.ArrayList;
import java.util.List;
/**
* 抽象产品类:Pizza.java
*/
public abstract class Pizza {
protected String name; //名称
protected String dough; //面团
protected String sause; //酱料
protected List<String> toppings = new ArrayList<String>(); //佐料
public void prepare() {
System.out.println("Preparing " + name);
System.out.println("Tossing dough");
System.out.println("Adding sause");
System.out.println("Adding toppings");
for (int i = 0; i < toppings.size(); i++) {
System.out.println(" " + toppings.get(i));
}
}
public void bake() {
System.out.println("Bake for 25 minutes at 350");
}
public void cut() {
System.out.println("Cutting the pizza into diagonal slices");
}
public void box() {
System.out.println("Place pizza in official PizzaStore box");
}
public String getName() {
return name;
}
}
package com.example.demo.factory.module;
/**
* 具体产品类:NYStyleCheesePizza
*/
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza() {
name = "Ny Style Sauce and Cheese Pizza";
dough = "Thin Crust Dough";
sause = "Marinara Sauce";
toppings.add("Crated Reggiano Cheese");
}
}
package com.example.demo.factory.module;
/**
* 具体产品类:ChicagoStyleCheesePizza
*/
public class ChicagoStyleCheesePizza extends Pizza{
public ChicagoStyleCheesePizza(){
name = "Chicago Style Deep Dish Cheese Pizza";
dough = "Extra Thick Crust Dough";
sause = "Plum Tomato Sauce";
toppings.add("Shredded Mozzarella Cheese");
}
public void cut(){
System.out.println("Cutting the Pizza into square slices");
}
}
package com.example.demo.factory;
import com.example.demo.factory.factory.ChicagoPizzaStoreFactory;
import com.example.demo.factory.factory.PizzaStore;
public class Test {
public static void main(String[] args) {
System.out.println("---------Joel 需要的芝加哥的深盘披萨---------");
System.out.println("工厂模式创建实例");
PizzaStore pizzaStore = new ChicagoPizzaStoreFactory();
// 用户只需要选好工厂,给出具体的口味,其他的流水线作业交给底层去做, 用户不关注
pizzaStore.orderPizza("cheese");
}
}
4.3、抽象模式实战
模式场景:
依然是披萨店。为了要保证每家加盟店都能够生产高质量的披萨,防止使用劣质的原料,我们打算建造一家生产原料的工厂,并将原料运送到各家加盟店。但是加盟店都位于不同的区域,比如纽约、芝加哥。纽约使用一组原料,芝加哥使用另一种原料。在这里我们可以这样理解,这些不同的区域组成了原料家族,每个区域实现了一个完整的原料家族。
首先创建一个原料工厂。该工厂为抽象工厂,负责创建所有的原料。 public interface PizzaIngredientFactory { 2 /* 3 * 在接口中,每个原料都有一个对应的方法创建该原料 4 */ 5 public Dough createDough(); 6 7 public Sauce createSauce(); 8 9 public Cheese createCheese(); 10 11 public Veggies[] createVeggies(); 12 13 public Pepperoni createPepperoni(); 14 15 public Clams createClams(); 16 }
原料工厂创建完成之后,需要创建具体的原料工厂。该具体工厂只需要继承PizzaIngredientFactory,然后实现里面的方法即可。 NYPizzaIngredientFactory.java public class NYPizzaIngredientFactory implements PizzaIngredientFactory{ 2 3 @Override 4 public Cheese createCheese() { 5 return new ReggianoCheese(); 6 } 7 8 @Override 9 public Clams createClams() { 10 return new FreshClams(); 11 } 12 13 @Override 14 public Dough createDough() { 15 return new ThinCrustDough(); 16 } 17 18 @Override 19 public Pepperoni createPepperoni() { 20 return new SlicedPepperoni(); 21 } 22 23 @Override 24 public Sauce createSauce() { 25 return new MarinaraSauce(); 26 } 27 28 @Override 29 public Veggies[] createVeggies() { 30 Veggies veggies[] = {new Garlic(),new Onion(),new Mushroom(),new RefPepper()}; 31 return veggies; 32 } 33 34 }
1 public abstract class Pizza {
2 /*
3 * 每个披萨都持有一组在准备时会用到的原料
4 */
5 String name;
6 Dough dough;
7 Sauce sauce;
8 Veggies veggies[];
9 Cheese cheese;
10 Pepperoni pepperoni;
11 Clams clams;
12
13 /*
14 * prepare()方法声明为抽象方法。在这个方法中,我们需要收集披萨所需要的原料,而这些原料都是来自原料工厂
15 */
16 abstract void prepare();
17
18 void bake(){
19 System.out.println("Bake for 25 munites at 350");
20 }
21
22 void cut(){
23 System.out.println("Cutting the pizza into diagonal slices");
24 }
25
26 void box(){
27 System.out.println("Place pizza in official PizzaStore box");
28 }
29
30 public String getName() {
31 return name;
32 }
33
34 public void setName(String name) {
35 this.name = name;
36 }
37
38 }
public class CheesePizza extends Pizza{
2 PizzaIngredientFactory ingredientFactory;
3
4 /*
5 * 要制作披萨必须要有制作披萨的原料,而这些原料是从原料工厂运来的
6 */
7 public CheesePizza(PizzaIngredientFactory ingredientFactory){
8 this.ingredientFactory = ingredientFactory;
9 prepare();
10 }
11
12 /
13 * 实现prepare方法
14 * prepare 方法一步一步地创建芝士比萨,每当需要原料时,就跟工厂要
15 */
16 void prepare() {
17 System.out.println("Prepareing " + name);
18 dough = ingredientFactory.createDough();
19 sauce = ingredientFactory.createSauce();
20 cheese = ingredientFactory.createCheese();
21 }
22
23 }
public abstract class PizzaStore {
2 public Pizza orderPizza(String type){
3 Pizza pizza;
4 pizza = createPizza(type);
5
6 pizza.prepare();
7 pizza.bake();
8 pizza.cut();
9 pizza.box();
10
11 return pizza;
12 }
13
14 /*
15 * 创建pizza的方法交给子类去实现
16 */
17 abstract Pizza createPizza(String type);
18 }
public class NYPizzaStore extends PizzaStore{
2
3 @Override
4 Pizza createPizza(String type) {
5 Pizza pizza = null;
6 //使用纽约的原料工厂
7 PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
8 if("cheese".equals(type)){
9 pizza = new CheesePizza(ingredientFactory);
10 pizza.setName("New York Style Cheese Pizza");
11 }
12 else if("veggie".equals(type)){
13 pizza = new VeggiePizza(ingredientFactory);
14 pizza.setName("New York Style Veggie Pizza");
15 }
16 else if("clam".equals(type)){
17 pizza = new ClamPizza(ingredientFactory);
18 pizza.setName("New York Style Clam Pizza");
19 }
20 else if("pepperoni".equals(type)){
21 pizza = new PepperoniPizza(ingredientFactory);
22 pizza.setName("New York Style Pepperoni Pizza");
23 }
24 return pizza;
25 }
26 }
最后
以上就是凶狠蜻蜓最近收集整理的关于设计模式-工厂模式(简单工厂,工厂模式,抽象工厂) 1.工厂模式的初心,本质2.解决了什么问题3.工厂模式结构图 4.实战的全部内容,更多相关设计模式-工厂模式(简单工厂,工厂模式,抽象工厂) 1.工厂模式内容请搜索靠谱客的其他文章。
发表评论 取消回复