工厂模式
工厂模式简述
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象,工厂模式使得对象的创建跟使用分离。根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式
简单工厂模式
简单工厂模式是将所有的要创建的对象放在一个工厂类中进行创建,一个成员方法创建一个类型的对象,如果工厂创建对象的方法是静态成员方法的话又叫静态工厂模式,如果工厂创建对象的方法是普通成员方法的话就叫实例工厂模式。现在以汽车生产为例来理解该模式。类图如下:
代码分析如下:
创建一个汽车Car接口(抽象产品)
/** * 定义一个汽车接口,抽象产品 */ public interface Car { void run(); }
创建一个奔驰BenZ类(具体产品)实现Car接口
/** * 定义一个奔驰类 */ public class BenZ implements Car { @Override public void run() { System.out.println("奔驰正在running..."); } }
创建一个宝马类BWM(具体产品)实现Car接口
/** * 定义一个宝马类 */ public class BWM implements Car { @Override public void run() { System.out.println("宝马正在running..."); } }
创建一个工厂类CarFactory类(实例工厂模式),创建二个方法分别用来生成宝马对象,奔驰对象。
/** * 简单工厂的实例工厂,用成员方法生产对象 * 简单工厂实现了对象的创建与调用分离,但是生产一个新类型的产品对象,需要新增一个方法,或者增加一个方法的逻辑,不遵循开闭原则。 */ public class CarFactory { //生产奔驰的方法 public Car createBenZ(){ return new BenZ(); } //生产宝马的方法 public Car createBWM(){ return new BWM(); } }
模式静态工厂模式创建一个StaticCarFactory类,创建二个静态方法分别用生产宝马对象,奔驰对象。
/** * 简单工厂的静态工厂,用静态成员方法生产对象 * 简单工厂实现了对象的创建与调用分离,但是生产一个新类型的产品对象,需要新增一个方法,或者增加一个方法的逻辑,不遵循开闭原则。 */ public class StaticCarFactory { //生产奔驰的静态方法 public BenZ createBenZ(){ return new BenZ(); } //生产宝马的静态方法 public BWM createBWM(){ return new BWM(); } }
创建一个客户端测试类ClientTest
/** * 简单工厂客户端测试类 */ public class ClientTest { public static void main(String[] args) { //创建一个汽车工厂对象 CarFactory carFactory=new CarFactory(); //生产一辆奔驰 Car benZ= carFactory.createBenZ(); //生产一辆宝马 Car bWM=carFactory.createBWM(); benZ.run(); bWM.run(); //测试静态工厂 //生产一辆奔驰 Car benZ1= carFactory.createBenZ(); //生产一辆宝马 Car bWM1=carFactory.createBWM(); benZ1.run(); bWM1.run(); } }
简单工厂模式总结:简单工厂实现了对象的创建与调用分离,但是生产一个新类型的产品对象,工厂类需要新增一个方法,或者增加一个方法的逻辑,不遵循开闭原则。为了解决这个问题就产生了工厂方法模式。
工厂方法模式
工厂方法模式是创建一个抽象类,在抽象类中定义一个创建对象的抽象方法,创建一个产品需要创建一个具体的工厂类继承该抽象类重写抽象类的抽象方法,现在以汽车生产为例来理解该模式。类图如下:
代码如下:
创建一个抽象工厂类AbstractFactory
/** *工厂方法模式,定义一个抽象工厂,如果需要新增一个类型的产品,新增一个工厂类继承抽象工厂。 * 工厂方法有力于单一产品新增,增加一个产品,新增一个工厂类,进行产品的新增,遵循了开闭原则。 *工厂方法是抽象工厂的产品族只有一种类型的产品(只有一个抽象产品)的情况 */ public abstract class AbstractFactory { //生产car的抽象方法 public abstract Car createCar(); }
创建宝马工厂类BWMFactory
/** * 宝马工厂 */ public class BWMFactory extends AbstractFactory { @Override public Car createCar() { return new BWM(); } }
创建奔驰工厂类BenZFactory
/** * 奔驰工厂继承抽象工厂 */ public class BenZFactory extends AbstractFactory { @Override public Car createCar() { return new BenZ(); } }
创建工厂方法测试类
/** * 工厂方法客户端测试类 */ public class ClientTest { public static void main(String[] args) { //创建奔驰工厂 AbstractFactory benZFactory=new BenZFactory(); //创建宝马工厂 AbstractFactory bWMFactory=new BenZFactory(); //生产一辆奔驰 Car benZ= benZFactory.createCar(); //生产一辆宝马 Car bWM=bWMFactory.createCar(); benZ.run(); bWM.run(); } }
工厂方法模式总结:工厂方法模式解决了简单工厂生产新对象时,需要修改工厂类的逻辑,工厂模式的可扩展性高。但是工厂方法也有不足,每生产一种新类型的对象,需要创建一个工厂类。这会使得系统的类过多。为了解决这个问题,当一些产品组合在一起看成一个产品族。这就诞生了抽象工厂模式。
抽象工厂模式
抽象工厂模式是将一些相关的产品组合在一起,把它们看成产品族,一个产品族创建一个具体的工厂类,产品族有几种产品就在工厂类创建几个方法来创建对象。比如:现在宝马工厂,奔驰工厂想生成轮子的。如果按照上面工厂方法模式,又多需要增加二个具体工厂类。现在把轮子和汽车看成一组产品族。类图如下:
代码如下:
创建轮子接口Wheel(抽象产品)
public interface Wheel { public void functions(); }
创建宝马轮子BWMWheel类
public class BWMWheel implements Wheel { @Override public void functions() { System.out.println("宝马汽车轮子稳定性强,耐用"); } }
创建奔驰轮子BenZWheel类
public class BenZWheel implements Wheel{ @Override public void functions() { System.out.println("奔驰汽车轮子抓地力更强..."); } }
修改上面抽象工厂类,增加一个创建轮子的抽象方法
/** *抽象工厂模式,定义一个抽象工厂,里面有生成产品族(一系列相关产品)的方法。 * 工厂方法有力于产品族的增加,增加一系列的产品,也是新增一个工厂继承该抽象工厂(不过该工厂有多个生成产品方法) * 抽象工厂要确定好产品族,不要修改产品族的产品,修改产品族的产品,抽象工厂跟具体工厂都要修改相应的产品, * */ public abstract class AbstractFactory { //生产car的抽象方法 public abstract Car createCar(); //生成wheel的抽象方法 public abstract Wheel createWheel(); }
修改具体工厂类BWMFactory类
/** * 宝马工厂 */ public class BWMFactory extends AbstractFactory { @Override public Car createCar() { return new BWM(); } @Override public Wheel createWheel() { return new BWMWheel(); } }
修改具体工厂类BenZFactory类
/** * 奔驰工厂继承抽象工厂 */ public class BenZFactory extends AbstractFactory { @Override public Car createCar() { return new BenZ(); } @Override public Wheel createWheel() { return new BenZWheel(); } }
抽象工厂模式客户端测试类
/** * 抽象工厂客户端测试类 */ public class ClientTest { public static void main(String[] args) { //创建奔驰工厂 AbstractFactory benZFactory=new BenZFactory(); //创建宝马工厂 AbstractFactory bWMFactory=new BenZFactory(); //生产一辆奔驰 Car benZ= benZFactory.createCar(); //生成奔驰轮子 Wheel benZWheel=benZFactory.createWheel(); //生产一辆宝马 Car bWM=bWMFactory.createCar(); //生成宝马轮子 Wheel bWMWheel=bWMFactory.createWheel(); benZ.run(); benZWheel.functions(); bWM.run(); bWMWheel.functions(); } }
抽象工厂模式总结:抽象工厂模式以产品族的方式进行产品新增的,二工厂方法是单一产品进行产品对新增,如果产品比较多,可以将几种相关类型的产品看成产品族,以产品族的方式进行产品的新增。如果产品不多可以选择抽象工厂进行产品的新增,其实上方法工厂模式是抽象工厂模式在产品族只有一种类型产品的情况。