设计模式-工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式分类三类:(在《设计模式》一书中将简单工厂模式与工厂方法模式合称为工厂方法模式)
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
简单工厂模式(Simple Factory)
建立一个工厂(一个函数或一个类方法)来制造新的对象。
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据自变量的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式优点
工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
简单工厂模式缺点
由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
简单工厂模式示例 定义抽象产品类
1 2 3 4 5 6 7 8 public abstract class Vehicle { public abstract void run () ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class Car extends Vehicle { private Double speed; private String name; Car(Double speed, String name) { this .speed = speed; this .name = name; } public Double getSpeed () { return speed; } public void setSpeed (Double speed) { this .speed = speed; } public String getName () { return name; } public void setName (String name) { this .name = name; } @Override public void run () { System.out.println(getName() + " speed is :" + getSpeed()); } }
定义具体的汽车实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class SedanCar extends Car { public SedanCar () { super (200D ,"SedanCar" ); } } public class Motobike extends Car { public Motobike () { super (120D , "Motobike" ); } }
定义工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class CarFactory { public static Vehicle createCar (CarType carType) { switch (carType) { case MOTOBIKE: return new Motobike (); case SEDANCAR: return new SedanCar (); default : return null ; } } }
1 2 3 4 5 6 7 8 9 10 public enum CarType { SEDANCAR, MOTOBIKE; }
模拟运行
1 2 3 4 5 6 7 8 9 10 11 public class SimpleMain { public static void main (String[] args) { Vehicle v1 = CarFactory.createCar(CarType.MOTOBIKE); v1.run(); Vehicle v2 = CarFactory.createCar(CarType.SEDANCAR); v2.run(); } }
控制台输出
1 2 Motobike speed is :120.0 SedanCar speed is :200.0
工厂方法模式(Factory Method)
工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method是一个类的实例化延迟到其子类。
在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
工厂方法模式优点
在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无需关心创建细节,甚至无需知道具体产品类的类名
基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,正是因为所有的具体工厂类都具有同一抽象父类
使用工厂方法模式的另一个优点是在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”
工厂方法模式缺点
在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度
工厂方法模式示例 Factory方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public interface VehicleFacotry { public Vehicle createVehicle () ; } public interface CarFactory extends VehicleFacotry {} public class MotobikeFactory implements CarFactory { @Override public Vehicle createVehicle () { return new Motobike (); } } public class SedanCarFactory implements CarFactory { @Override public Vehicle createVehicle () { return new SedanCar (); } }
抽象工厂模式(Abstract Factory)
抽象工厂模式提供一个创建一系列或相互依赖的对象的接口,而无需指定它们具体的类。
抽象工厂模式优点
隔离了具体类的生成,使得用户不需要知道什么被创建了。
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
抽象工厂模式缺点
添加新的产品对像时,难以扩展抽象工厂以便生产新种类的产品。
抽象工厂模式示例 定义ProductB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public abstract class Tv { public abstract void player () ; } public class LeTv extends Tv { @Override public void player () { System.out.println("player LeTv" ); } } public class ChangTv extends Tv { @Override public void player () { System.out.println("player ChangTv" ); } }
定义Factory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public interface Factory { public Tv createTv () ; public Vehicle createVehicle () ; } public class ConOneFactory implements Factory { @Override public Tv createTv () { return new LeTv (); } @Override public Vehicle createVehicle () { return new Motobike (); } } public class ConTwoFactory implements Factory { @Override public Tv createTv () { return new ChangTv (); } @Override public Vehicle createVehicle () { return new SedanCar (); } }
参考资料
http://design-patterns.readthedocs.io/zh_CN/latest/
https://www.jianshu.com/p/bf8341c75304