相关链接:
【设计模式】专栏:【设计模式】专栏
相关例子代码可下载:Java常用设计模式例子
简介
目前工厂模式大致分为3种,分别是:
简单工厂模式
工厂方法模式
抽象工厂模式
简单工厂模式
简单工厂模式(Simple Factory Pattern)是属于创建型模式,又叫做静态工厂方法(Static Factory Method Pattern)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
作用:
将“类实例化”的操作和“使用对象”的操作分开,让使用者不用知道具体参数就可以实例化所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。
主要角色
具体工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需要的产品对象。
抽象产品(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色
简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
举个栗子:
假设有一台饮料机(工厂),可以调出各种口味的饮料(抽象产品),有三个按钮(参数)对应这三种饮料(具体产品)。这时候你可以根据点击按钮来选择你喜欢的饮料。
抽象产品:Product.java
/*** 简单工厂模式——抽象产品* 说明:* 描述产品的公共接口**/public abstract class Product {/*** 产品介绍*/public abstract void introduce();}
具体产品:CocoProduct.java 、 MilkProduct.java 、CofficeProduct.java
/*** 简单工厂模式——具体产品 A** (可以看成是一种饮料:可乐)**/public class CocoProduct extends Product{@Overridepublic void introduce() {System.out.println("可乐");}}/*** 简单工厂模式——具体产品 B**(可以看成是一种饮料:奶茶)**/public class MilkProduct extends Product{@Overridepublic void introduce() {System.out.println("奶茶");}}/*** 简单工厂模式——具体产品 C** (可以看成是一种饮料:咖啡)**/public class CofficeProduct extends Product{@Overridepublic void introduce() {System.out.println("咖啡");}}
具体工厂:SimpleFactory.java
/*** 简单工厂模式——具体工厂* * 负责实现创建所有实例的内部逻辑,并提供一个外接调用的方法,创建所需的产品对象**/public class SimpleFactory {/*** 提供给外接调用的方法* (可以看成是对外提供的三个小按钮)** @param type 产品类型* @return FactoryPattern.SimpleFactoryPattern.Product*/public static Product getProduct(String type) {switch (type) {case "coco":return new CocoProduct();case "milk":return new MilkProduct();case "coffice":return new CofficeProduct();default:return null;}}}
测试:SimpleFactoryDemo.java
/*** 简单工厂模式**/public class SimpleFactoryDemo {public static void main(String[] args) {// 创建具体的工厂SimpleFactory factory = new SimpleFactory();// 根据传入的参数生产不同的产品实例// (按下不同的按钮,获取饮料)Product coco = SimpleFactory.getProduct("coco");coco.introduce();Product milk = SimpleFactory.getProduct("milk");milk.introduce();Product coffice = SimpleFactory.getProduct("coffice");coffice.introduce();}}
根据栗子可以描述为:
一个抽象产品类,可以派生出多个具体产品类
一个具体工厂类,通过往此工厂的static
方法中传入不同参数,产出不同的具体产品类实例
优缺点
优点
将创建、使用工作分开,不必关心类对象如何创建,实现了解耦
把初始化实例时的工作放到工厂里进行,使代码更容易维护。更符合面向对象的原则&面向接口编程,而不是面向实现编程
缺点
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响
违背“开放-关闭”原则,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成
工厂方法模式
工厂方法模式,又称工厂模式(Factory Pattern)、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。(常用!)
作用:
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。
主要角色
抽象工厂(Abstract Factory)角色
描述具体工厂的公共接口。
具体工厂(Concrete Factory)角色
描述具体工厂,创建产品的实例,供外界调用,主要实现了抽象工厂中的抽象方法,完成具体产品的创建。
抽象产品(Product)角色
负责描述产品的公共接口,定义了产品的规范,描述了产品的主要特性和功能。
具体产品(Concrete Product)角色
描述生产的具体产品,实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
举个栗子:
假设有各类的饮料机(抽象工厂),可以调出各种的饮料(抽象产品)。但是一类饮料机(具体工厂),只能生产一种饮料(具体产品)。如果你需要喝可乐,就需要买可乐饮料机。
抽象产品:Product.java
/*** 工厂方法模式——抽象产品**/public abstract class Product {/*** 产品介绍*/public abstract void introduce();}
具体产品:ProductA.java 、ProductB.java
/*** 工厂方法模式——具体产品A**/public class ProductA extends Product{@Overridepublic void introduce() {System.out.println("饮料A");}}/*** 工厂方法模式——具体产品B**/public class ProductB extends Product{@Overridepublic void introduce() {System.out.println("饮料B");}}
抽象工厂:Factory.java
/*** 工厂方法模式——抽象工厂**/public abstract class Factory {/*** 生产产品** @return FactoryPattern.FactoryPattern.Product*/public abstract Product getProduct();}
具体工厂:FactoryA.java 、FactoryB.java
/*** 工厂方法模式——具体工厂A** (负责具体的产品A生产)**/public class FactoryA extends Factory{@Overridepublic Product getProduct() {return new ProductA();}}/*** 工厂方法模式——具体工厂B** (负责具体的产品B生产)**/public class FactoryB extends Factory{@Overridepublic Product getProduct() {return new ProductB();}}
测试:FactoryDemo.java
/*** 工厂方法模式**/public class FactoryDemo {public static void main(String[] args) {// 创建具体的工厂FactoryA factoryA = new FactoryA();// 生产相对应的产品factoryA.getProduct().introduce();FactoryB factoryB = new FactoryB();factoryB.getProduct().introduce();}}
根据栗子可以描述为
一个抽象产品类,可以派生出多个具体产品类
一个抽象工厂类,可以派生出多个具体工厂类
每个具体工厂类只能创建一个具体产品类的实例
优缺点
优点
符合“开-闭原则”,扩展性高:新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
符合单一职责原则:每个具体工厂类只负责创建对应的产品
缺点
增加了系统的复杂度:类的个数将成对增加
增加了系统的抽象性和理解难度
一个具体工厂只能创建一种具体产品
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
抽象工厂模式和工厂方法模式最大的区别:
抽象工厂中,每个工厂可以创建多种类的产品工厂方法中,每个工厂只能创建一类产品
作用
允许使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。
主要角色
抽象工厂(Abstract Factory)角色
描述具体工厂的公共接口
具体工厂(ConcreteFactory)角色
描述具体工厂,创建产品的实例,供外界调用
抽象产品族(Abstract Product)角色
描述抽象产品的公共接口
抽象产品(Product)角色
描述具体产品的公共接口
具体产品(ConcreteProduct)角色
描述生产的具体产品
举个栗子:
假设有各类的自动售卖机(抽象工厂),可以出售各类食品(抽象产品族)。
有饮料、零食(抽象产品),比如常见的零售售卖机(具体工厂),出售矿泉水与面包(具体产品)。
抽象产品族:Product.java
/*** 抽象工厂模式——抽象产品族(食品)**/public abstract class Product {/*** 产品介绍*/public abstract void introduce();}
抽象产品:ProductA.java、ProductB.java
/*** 抽象工厂模式——抽象产品(饮料)**/public abstract class ProductA extends Product{}/*** 抽象工厂模式——抽象产品(零食)**/public abstract class ProductB extends Product{}
具体产品:ProductAa.java、ProductBb.java
/*** 抽象工厂模式——具体产品**/public class ProductAa extends ProductA{@Overridepublic void introduce() {System.out.println("矿泉水");}}/*** 抽象工厂模式——具体产品**/public class ProductBb extends ProductB{@Overridepublic void introduce() {System.out.println("面包");}}
抽象工厂:AbstractFactory.java
/*** 抽象工厂模式——抽象工厂**/public abstract class AbstractFactory {/*** 生产饮料*/public abstract Product getProductA();/*** 生产零食*/public abstract Product getProductB();}
具体工厂:AbstractFactoryA.java
/*** 抽象工厂模式——具体工厂** 负责具体的A类产品生产**/public class AbstractFactoryA extends AbstractFactory{@Overridepublic Product getProductA() {// 生产矿泉水return new ProductAa();}@Overridepublic Product getProductB() {// 生产面包return new ProductBb();}}
测试:AbstractFactoryDemo.java
/*** 抽象工厂模式**/public class AbstractFactoryDemo {public static void main(String[] args) {// 创建零食售卖机(具体工厂)AbstractFactoryA abstractFactoryA = new AbstractFactoryA();// 获取矿泉水与面包(具体产品)abstractFactoryA.getProductA().introduce();abstractFactoryA.getProductB().introduce();}}
根据实例可以描述为:
多个抽象产品类,每个抽象产品可以派生出多个具体产品类
一个抽象工厂类,可以派生出多个具体工厂类
每个具体工厂类可以创建多个 具体产品类的实例
优缺点
优点
降低耦合
符合“开-闭原则”
符合单一职责原则
不使用静态工厂方法,可以形成基于继承的等级结构
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点
难以扩展新种类产品,要增加一个系列的某一产品,既要在抽象产品里加代码,又要在具体的里面加代码。
结束语
1、更多设计模式内容请看【设计模式】专栏
2、相关例子代码可下载:Java常用设计模式例子
PS:【Java常用设计模式例子】 内已包含【设计模式】专栏里涉及的代码,如果之前已下载过的同学,就不需要重复下载啦~
以上内容如有不正确或需要补充的地方,还请多多请教,会及时更新改正~
欢迎评论~ 感谢点赞~
如果觉得《设计模式——工厂模式(包含:简单工厂模式 工厂方法模式 抽象工厂模式)》对你有帮助,请点赞、收藏,并留下你的观点哦!