【设计模式学习笔记】 之 工厂方法模式
简介:
一个类编写过程中,需要一个不能确定的对象,去执行一些操作,这个时候,我们需要使用一个抽象的方法或者已实现的方法来返回需要的对象,这个对象的实现,可以根据继承让子类覆盖重写,从而起到一个占位的作用,以及使对象更佳灵活。
举例:
类似前一篇博客的例子,同样以4s店为例,这次的4s店是厂家直营店,意思是这个直营店只经营一种品牌,这里没有定义工厂,那么每个品牌4s店有一个get方法可以返回一个汽车的对象,但是此时我们不确定返回汽车的具体类型,我们只知道它是辆汽车,我们需要这辆汽车去做试车(haveATry()方法),所以我们定义这个方法为抽象方法,让其子类去实现这个方法,同时这个类也变成了抽象类
创建一个Car接口,并实现两辆汽车BenzCar和VolvoCar
1 package com.mi.factorymethod; 2 3 /** 4 * 汽车接口 5 * @author hellxz 6 */ 7 public interface Car { 8 9 //接口中的方法与变量均为public static final修饰的 10 void run(); 11 }
1 package com.mi.factorymethod; 2 3 /** 4 * 奔驰汽车 5 * @author hellxz 6 */ 7 public class BenzCar implements Car{ 8 9 @Override 10 public void run() { 11 System.out.println("开着奔驰去兜风"); 12 } 13 14 }
1 package com.mi.factorymethod; 2 3 /** 4 * 沃尔沃汽车 5 * @author hellxz 6 */ 7 public class VolvoCar implements Car{ 8 9 @Override 10 public void run() { 11 System.out.println("沉稳大气的沃尔沃"); 12 } 13 14 }
接下来定义直营店的抽象类,正如开始所说的那样
1 package com.mi.factorymethod; 2 3 /** 4 * 工厂方法设计模式:一个类编写过程中,需要一个不能确定的对象,去执行一些操作,这个时候, 5 * 我们需要使用一个抽象的方法或者已实现的方法来返回需要的对象,这个对象的实现,可以根据 6 * 继承让子类覆盖重写,从而起到一个占位的作用,以及使对象更佳灵活 7 * @author hellxz 8 * 9 * 直售4s店抽象类 10 */ 11 public abstract class StraightSale4S { 12 13 public void haveATry() { 14 //此处我们需要一个汽车对象,但是我们不确定需要什么样的汽车 15 getCar().run(); 16 } 17 18 //定义一个返回Car对象的方法,可以默认实现,也可以抽象方法让子类必须实现 19 public abstract Car getCar(); 20 21 }
创建继承StraightSale4S的实现类,在BenzCarSSSS和VolvoCarSSSS分别重写getCar方法返回不同的实例
1 package com.mi.factorymethod; 2 3 /** 4 * 奔驰4s直营店 5 * @author hellxz 6 */ 7 public class BenzCarSSSS extends StraightSale4S { 8 9 @Override 10 public Car getCar() { 11 //创建一个BenzCar实例 12 return new BenzCar(); 13 } 14 15 }
1 package com.mi.factorymethod; 2 3 /** 4 * 沃尔沃4s直营店 5 * @author hellxz 6 */ 7 public class VolvoCarSSSS extends StraightSale4S { 8 9 @Override 10 public Car getCar() { 11 //创建一个VolvoCar实例 12 return new VolvoCar(); 13 } 14 15 }
写个测试类:
1 package com.mi.factorymethod; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 // StraightSale4S ssss = new BenzCarSSSS(); 7 /* 8 * 仅需要切换4s直营店的名称就能获得不同品牌的汽车对象 9 */ 10 StraightSale4S ssss = new VolvoCarSSSS(); 11 ssss.haveATry(); 12 } 13 14 }
输出:
沉稳大气的沃尔沃
注掉第10行,开启第6行
开着奔驰去兜风
总结:
工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
优点:新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
缺点:和优点一样,为了生产更多不同的产品需要创建更多的实现类和产品类,即一个具体工厂只能创建一种具体产品。
应用场景:
- 当一个类不知道它所需要的对象的类时
- 当一个类希望通过其子类来指定创建对象时