工厂模式
-
定义
一个创建产品对象的工厂接口,将产品对象的实例创建工作推迟到具体子类工厂类中,满足了"创建和使用相分离"的特性
-
分类
简单工厂 工厂方法 抽象工厂
-
产品:客户端需要创建的对象
-
工厂:创建产品的类
-
产品族:同一具体工厂所生产的位于不同等级的一组产品
简单工厂模式
-
定义
又称静态工厂模式,在Java中定义了一个类来负责创建其他类的实例,被创建的实体通常具有共同的父类
-
优缺点
-
优点
工厂类包含必要的逻辑判断,可以决定创建哪一个产品的实例;客户端无需关心对象的创建过程
-
缺点
工厂类负责所有的产品创建,会导致职责过重,代码变得臃肿,不符合高内聚低耦合的设计原则 扩展性差,一旦需要增加新的产品就不得不修稿工厂逻辑,导致工厂逻辑变得复杂
-
-
使用场景
产品种类相对较少
-
模式的结构
-
抽象产品
创建所有对象的父类,负责描述所有实例共有的公共接口
-
具体产品
简单工厂模式的创建目标
-
简单工厂
简单工厂模式的核心,包含实现创建所有实例的内部逻辑
-
-
简单举例
我们拿水果来说,水果园可以被看做是一个工厂,它可以生产苹果,香蕉等水果,而具体的水果就是一个实体,其父类就是水果
-
抽象产品Fruit
//水果类 public static interface Fruit{ public void get(); }
-
具体产品Apple
public static class Apple implements Fruit { @Override public void get() { System.out.println("采集苹果"); } }
-
具体产品Banana
//香蕉 public static class Banana implements Fruit { @Override public void get() { System.out.println("采集香蕉"); } }
-
-
具体工厂FruitFactory
//水果工厂类 public static class FruitFactory{ public static Fruit createFruit(String name){ if("Apple".equalsIgnoreCase(name)){ return new Apple(); }else if("Banana".equalsIgnoreCase(name)){ return new Banana(); } return null; } }
-
客户端调用
public static void main(String[] args) { //通过调用工厂类的静态方法getFruit,创建水果的子类实例。 Fruit apple = FruitFactory.createFruit("Apple"); Fruit banana = FruitFactory.createFruit("Banana"); apple.get(); banana.get(); }
工厂方法模式
-
定义
简单工厂模式的升级版,在简单工厂模式的基础上,对工厂类进行抽象,产生一个抽象接口,将具体的工厂推迟到子类中
-
优缺点
-
优点
扩展性强,对于新产品的创建,只需要多写一个相应的工厂类 客户端无须知道对象的创建过程,只需通过对应的工厂就可获得
-
缺点
类的个数容易过多,增加复杂度 只能生产一种产品
-
-
和简单工厂的区别
简单工厂: 若需要引进新的产品需要修改核心工厂 工厂方法模式: 若需要引进新的产品无须修改核心工厂,只需要新建一个类和创建该类的具体工厂
-
模式的结构
-
抽象工厂
提供了创建产品的接口
-
具体工厂
实现了抽象工厂接口,完成具体产品的创建
-
抽象产品
对产品进行规范,描述了产品的主要特性和功能
-
具体产品
实现了抽象产品接口,由具体工厂来创建
-
-
简单举例
我们拿水果来说,水果园可以被看做是一个工厂,它可以生产苹果,香蕉等水果,而具体的水果就是一个实体,其父类就是水果-
抽象产品Fruit
//水果类 public static interface Fruit{ public void get(); }
-
具体产品Apple
public static class Apple implements Fruit { @Override public void get() { System.out.println("采集苹果"); } }
-
具体产品Banana
//香蕉 public static class Banana implements Fruit { @Override public void get() { System.out.println("采集香蕉"); } }
-
-
抽象工厂FruitFactory
//抽象工厂 public static interface FruitFactory{ public Fruit createFruit(); }
-
具体苹果工厂AppleFactory
//苹果工厂 public static class AppleFactory implements FruitFactory{ @Override public Fruit createFruit() { return new Apple(); } }
-
具体香蕉工厂BananaFactory
//苹果工厂 public static class BananaFactory implements FruitFactory{ @Override public Fruit createFruit() { return new Banner(); } }
-
客户端调用
public static void main(String[] args) { //创建苹果工厂 FruitFactory appleFactory = new AppleFactory(); //通过苹果工厂生产苹果实例 Fruit apple = appleFactory.createFruit(); apple.get(); //创建香蕉工厂 FruitFactory bananaFactory = new BananaFactory(); //通过香蕉工厂生产香蕉实例 Fruit banana = bananaFactory.createFruit(); banana.get(); }
抽象方法模式
-
定义
对工厂方法模式进行了升级,是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式
-
优缺点
-
优点
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组 增强了程序的扩展性,当新增一个新的产品族时,不需要要修改源代码,满足开闭原则
-
缺点
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改,增强了系统的抽象性和理解难度
-
-
与工厂方法模式的区别
工厂方法模式:只考虑一类产品的生产 电视厂只生产电视 水果园只种植水果 抽象方法模式:现实中需要综合型工厂,可以生产多种类的产品 机械厂既可以生产电视机又生产洗衣机 农场里即种植水果也养殖动物
-
模式的结构
* 抽象工厂 提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品
-
具体工厂
实现了抽象工厂中的多个抽象方法,完成具体产品的创建
-
抽象产品
定义了产品的规范,描述了产品的主要特征和功能
-
具体产品
实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系
-
-
简单举例
我们拿水果来说,水果园可以被看做是一个工厂,它可以生产苹果,香蕉等水果,而具体的水果就是一个实体,其父类就是水果
-
抽象产品Fruit
//水果类 public static interface Fruit{ public void get(); }
-
抽象产品Apple
//苹果抽象类 public static abstract class Apple implements Fruit{ public abstract void get(); }
-
抽象产品Banana
//香蕉抽象类 public static abstract class Banana implements Fruit{ public abstract void get(); }
-
抽象工厂FruitFactory
//抽象工厂 public interface FruitFactory{ public Fruit getApple(); public Fruit getBanana(); }
-
具体苹果工厂AppleFactory
public static class ChinaFruitFactory implements FruitFactory{ @Override public Fruit getApple() { return new ChinaApple(); } @Override public Fruit getBanana() { return new ChinaBanana(); } }
-
-
客户端调用
public static void main(String[] args) { //创建中国工厂 FruitFactory chinaFactory = new ChinaFruitFactory(); //通过中国工厂生产中国苹果实例 Fruit apple = chinaFactory.getApple(); apple.get(); //通过中国工厂生产中国香蕉实例 Fruit banana = chinaFactory.getBanana(); banana.get(); }