相关链接:
【设计模式】专栏:【设计模式】专栏
相关例子代码可下载: 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{
@Override
public void introduce() {
System.out.println("可乐");
}
}
/**
* 简单工厂模式——具体产品 B
*
*(可以看成是一种饮料:奶茶)
*
*/
public class MilkProduct extends Product{
@Override
public void introduce() {
System.out.println("奶茶");
}
}
/**
* 简单工厂模式——具体产品 C
*
* (可以看成是一种饮料:咖啡)
*
*/
public class CofficeProduct extends Product{
@Override
public 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{
@Override
public void introduce() {
System.out.println("饮料A");
}
}
/**
* 工厂方法模式——具体产品B
*
*/
public class ProductB extends Product{
@Override
public 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{
@Override
public Product getProduct() {
return new ProductA();
}
}
/**
* 工厂方法模式——具体工厂B
*
* (负责具体的产品B生产)
*
*/
public class FactoryB extends Factory{
@Override
public 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)角色
描述具体工厂的公共接口
具体工厂(Concrete Factory)角色
描述具体工厂,创建产品的实例,供外界调用
抽象产品族(Abstract Product)角色
描述抽象产品的公共接口
抽象产品(Product)角色
描述具体产品的公共接口
具体产品(Concrete Product)角色
描述生产的具体产品
举个栗子:
假设有各类的自动售卖机(抽象工厂),可以出售各类食品(抽象产品族)。
有饮料、零食(抽象产品),比如常见的零售售卖机(具体工厂),出售矿泉水与面包(具体产品)。
抽象产品族: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{
@Override
public void introduce() {
System.out.println("矿泉水");
}
}
/**
* 抽象工厂模式——具体产品
*
*/
public class ProductBb extends ProductB{
@Override
public 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{
@Override
public Product getProductA() {
// 生产矿泉水
return new ProductAa();
}
@Override
public 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常用设计模式例子 】 内已包含 【设计模式】专栏 里涉及的代码,如果之前已下载过的同学,就不需要重复下载啦~
以上内容如有不正确或需要补充的地方,还请多多请教,会及时更新改正~
欢迎评论~ 感谢点赞~