“ 王刚师傅说:“不想杀鱼的可以交给热心摊主处理”。看来是深得工厂模式的精髓,将创建对象的步骤交给工厂来创建,对象创建将会更加的规范化”
简单工厂模式(静态工厂模式)
定义
定义一个接口,其有多种实现类,当需要在不同场景下使用不同的子类的实例对象时,由工厂代为创建。
实现要素
一个抽象接口多个抽象接口的实现类一个可管理创建多个对象的工厂类
UML类图

代码实现
抽象接口Shape
public interface Shape {void draw();}
抽象接口实现类
public class Circle implements Shape {public void draw() {System.out.println("Inside Circle::draw() method.");}}
public class Rectangle implements Shape {public void draw() {System.out.println("Inside Rectangle::draw() method.");}}
public class Square implements Shape {public void draw() {System.out.println("Inside Square::draw() method.");}}
public class ShapeFactory {//使用 getShape 方法获取形状类型的对象public static Shape getShape(String shapeType){if(shapeType == null){return null;}if(shapeType.equalsIgnoreCase("CIRCLE")){return new Circle();} else if(shapeType.equalsIgnoreCase("RECTANGLE")){return new Rectangle();} else if(shapeType.equalsIgnoreCase("SQUARE")){return new Square();}return null;}}
public class TestDemo {public static void main(String[] args) {//获取 Circle 的对象,并调用它的 draw 方法Shape shape1 = ShapeFactory.getShape("CIRCLE");//调用 Circle 的 draw 方法shape1.draw();//获取 Rectangle 的对象,并调用它的 draw 方法Shape shape2 = ShapeFactory.getShape("RECTANGLE");//调用 Rectangle 的 draw 方法shape2.draw();//获取 Square 的对象,并调用它的 draw 方法Shape shape3 = ShapeFactory.getShape("SQUARE");//调用 Square 的 draw 方法shape3.draw();}}
优点
将创建实例的方法交给工厂,使用者不必关心如何创建实例,实现了解耦
实例化代码放在工厂中,更符合面向对象及面向接口编程,而不是面向实现编程
缺点
工厂类中集中实现了所有实例的创建方法,一旦工厂类不能使用,整个系统都将受到影响
违反了“开放-关闭原则”,一旦要新增新的产品类,必然要修改工厂类,随着产品类越来越多,工厂类的业务逻辑将会很复杂
工厂方法模式
定义
定义一个抽象产品接口,其有多种产品实现类,定义一个工厂接口,其有多种工厂实现类,每种工厂类负责一种产品的实例化,当需要在不同场景下使用不同的子类的实例对象时,由对应的工厂代为创建。
当新增一种产品类时,不再修改原本的工厂类,符合”开闭原则“,解决了简单工厂中出现的问题
实现要素
一个抽象接口一个工厂接口多个抽象接口的实现类多个工厂接口的实现类
UML类图

代码实现
定义产品接口public interface Car {//获取车的品牌String getCarBrand();}
public interface CarFactory {Car createCar();}
public class JiLiCar implements Car{public String getCarBrand() {return "吉利星瑞";}}
public class WuLingCar implements Car{public String getCarBrand() {return "五菱宏光";}}
public class JiLiFactory implements CarFactory{public Car createCar() {return new JiLiCar();}}
public class WuLingFactory implements CarFactory{public Car createCar() {return new WuLingCar();}}
public class TestDemo {public static void main(String[] args) {WuLingFactory wuLingFactory = new WuLingFactory();System.out.println(wuLingFactory.createCar().getCarBrand());JiLiFactory jiLiFactory = new JiLiFactory();System.out.println(jiLiFactory.createCar().getCarBrand());}}
优点
符合开闭原则,新增一个产品实现类时,不用修改工厂类
符合单一职责原则,每种工厂只负责其对应的产品实例化,与其他无关
缺点
当新增一个产品实现类,需要同时新增一个对应的工厂类,这样无疑会产生类爆炸,增加系统在编译时的负担
对于工厂内部的方法符合”开闭原则“,但是使用工厂类的用户,仍然需要去实例化工厂类对象
抽象工厂模式
定义
在工厂方法模式中,一个工厂只能生产一种产品,那如果想要生产多种产品呢?就需要将产品工厂再向上抽象,使用抽象工厂模式
定义一个抽象产品工厂接口,抽象工厂接口中可以定义多种产品的”生产方法“
其有多个产品工厂实现类;既然是多种产品,就需要多种产品接口,且有多个产品实现类
由于该设计模式过于抽象,简要解释下接下来的例子
抽象工厂的”生产方法“:生产手机和PAD
品牌(抽象工厂实现):华为工厂、小米工厂
产品(产品接口实现):手机、PAD
品牌+产品:华为手机、华为PAD、小米手机、小米PAD
实现要素
一个抽象工厂接口,定义多种产品的”生产方法”多个抽象工厂实现类,实现产品的“生产方法”,用来生产产品多个产品接口多个产品接口的实现类
UML类图


代码实现
抽象产品工厂接口
public interface IProductFactory {IphoneProduct productPhone();IpadProduct productPad();}
产品工厂实现类-HuaWeiProductFactory
public class HuaWeiProductFactory implements IProductFactory{public IphoneProduct productPhone() {return new HuaWeiPhone();}public IpadProduct productPad() {return new HuaWeiPad();}}
产品工厂实现类-XiaoMiProductFactory
public class XiaoMiProductFactory implements IProductFactory{public IphoneProduct productPhone() {return new XiaoMiPhone();}public IpadProduct productPad() {return new XiaoMiPad();}}
产品抽象接口-IpadProduct
public interface IpadProduct {//看电影void seeMovie();//玩游戏void playGame();}
IpadProduct接口实现类-HuaWeiPad
public class HuaWeiPad implements IpadProduct{public void seeMovie() {System.out.println("我用华为Pad看电影");}public void playGame() {System.out.println("我用华为Pad玩游戏");}}
IpadProduct接口实现类-XiaoMiPad
public class XiaoMiPad implements IpadProduct{public void seeMovie() {System.out.println("我用小米Pad看电影");}public void playGame() {System.out.println("我用小米Pad玩游戏");}}
产品抽象接口-IphoneProduct
public interface IphoneProduct {//打电话void call();//照相void takingPictures();}
IphoneProduct接口实现类-HuaWeiPhone
public class HuaWeiPhone implements IphoneProduct{public void call() {System.out.println("我用华为手机打电话");}public void takingPictures() {System.out.println("我用华为手机照相");}}
IphoneProduct接口实现类-XiaoMiPhone
public class XiaoMiPhone implements IphoneProduct{public void call() {System.out.println("我用小米手机打电话");}public void takingPictures() {System.out.println("我用小米手机照相");}}
测试类
public class TestDemo {public static void main(String[] args) {XiaoMiProductFactory xiaoMiProductFactory = new XiaoMiProductFactory();IphoneProduct xiaomiIphoneProduct = xiaoMiProductFactory.productPhone();xiaomiIphoneProduct.call();xiaomiIphoneProduct.takingPictures();IpadProduct xiaomiIpadProduct = xiaoMiProductFactory.productPad();xiaomiIpadProduct.playGame();xiaomiIpadProduct.seeMovie();HuaWeiProductFactory huaWeiProductFactory = new HuaWeiProductFactory();IphoneProduct huaWeiIphoneProduct = huaWeiProductFactory.productPhone();huaWeiIphoneProduct.call();huaWeiIphoneProduct.takingPictures();IpadProduct huaweiIpadProduct = huaWeiProductFactory.productPad();huaweiIpadProduct.playGame();huaweiIpadProduct.seeMovie();}}
测试结果

优点
当多种产品族被设计在一起工作时,可以保证一个应用一次只能使用同一个系列中的对象,这一点很重要(比如,你在华为工厂里只能见到华为品牌的产品,不可能见到小米的产品)
缺点
难以新增新的种类的产品,因为抽象工厂限制了可以生产的“产品种类“,例如,抽象工厂规定了只能生产手机和PAD,想要生产电脑,是不可以的




