设计模式学习04----之简单工厂模式以及工厂方法模式以及抽象工厂模式
Spring Boot 的学习先告一段落,我们先温习下相关设计模式。我们先学习下简单工厂模式和工厂方法模式。
简单工厂模式
定义和结构
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory
Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
优缺点
优点: 实现了封装
缺点:违反了高内聚的原则
工厂方法模式
定义和结构
GOF中给出的定义是:工厂方法模式定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。
有以下四种角色:
抽象工厂角色:定义创建产品的方法
具体工厂角色: 具体实现创建产品的方法
抽象产品角色: 抽象产品的共有方法
具体产品角色:实现产品的共有方法。
以下是一个demo
抽象产品类(Product):
package com.factory.factoryMethod;
/**
-
抽象产品
-
@author xiang.wei
-
@create 2018/4/8 10:42
/
abstract class Product {
/*- 商品展示
*/
public abstract void show();
}
具体产品类 (ProductA 与ProductB)
- 商品展示
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:55
*/
public class ProductA extends Product {@Override
public void show() {
System.out.println(“产品A被生产出来”);
}
}
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:02
*/
public class ProductB extends Product {@Override
public void show() {
System.out.println(“产品B被生产”);
}
}抽象工厂类(Factory)
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:35
/
abstract class Factory {
/*- 抽象工厂
- @return
*/
public abstract Product manufacture();
}
具体工厂类(FactoryA与FactoryB),不同的工厂生产不同的产品
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:54
*/
public class FactoryA extends Factory {@Override
public Product manufacture() {
return new ProductA();
}
}
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:03
*/
public class FactoryB extends Factory {@Override
public Product manufacture() {
return new ProductB();
}
}客户端调用
package com.factory.factoryMethod;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:05
*/
public class FactoryPattern {
public static void main(String[] args) {
//客户需要产品A
Factory factoryA = new FactoryA();
factoryA.manufacture().show();
//客户需要产品B
FactoryB factoryB = new FactoryB();
factoryB.manufacture().show();
}
}
优缺点
优点:
扩展性好,符合开闭原则,对扩展开放,对修改关闭,在增加产品类的情况下,只需要适当修改具体的工厂类或扩展一个工厂类。
多态性:客户代码可以做到与特定应用无关,使用于任何实体类。
良好的封装性,代码结构清晰。
屏蔽产品类
典型的解耦框架:高层模块只需要知道产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合里氏替换原则。
缺点:
一个具体工厂只能创建一类产品。
抽象工厂模式
定义和结构
GOF 中给出的定义是:抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。
抽象工厂模式
从类图中我们可以看出,抽象工厂中每个工厂可以创建多种产品,比如:Factory1可以创建ProductA和ProductB两种产品。
组成 关系 作用
抽象工厂类(Factory) 具体工厂的父类 定义具体工厂的公共接口方法
具体工厂类(Factory1) 抽象工厂的子类,被外界调用 描述具体工厂,实现FactoryMethod工厂方法创建产品的实例
抽象产品类(ProductA) 具体产品的父类 定义具体产品的公共接口
具体产品类(ProductA1) 抽象产品的子类,工厂类创建的目标类 定义生产的具体产品
抽象工厂类
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:35
/
public interface Factory {
/*- 创建抽象产品A
- @return
*/
ProductA createProductA();
/**
- 创建抽象产品B
- @return
*/
ProductB createProductB();
}
具体工厂类A和具体工厂类B
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:54
*/
public class FactoryA implements Factory {public ProductA createProductA() {
return new ProductA1();
}public ProductB createProductB() {
return new ProductB1();
}
}
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:03
*/
public class FactoryB implements Factory {public ProductA createProductA() {
return new ProductA2();
}public ProductB createProductB() {
return new ProductB2();
}
}
抽象产品A
package com.factory.abstractFactory;
/**
-
抽象产品
-
@author xiang.wei
-
@create 2018/4/8 10:42
/
public interface ProductA {
/*- 商品展示
*/
void show();
}
- 商品展示
具体产品A1和具体产品A2
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:55
*/
public class ProductA1 implements ProductA {public void show() {
System.out.println(“产品A1被生产出来”);
}
}
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 10:55
*/
public class ProductA2 implements ProductA {public void show() {
System.out.println(“产品A2被生产出来”);
}
}
抽象产品B
package com.factory.abstractFactory;
/**
-
抽象产品
-
@author xiang.wei
-
@create 2018/4/8 10:42
/
public interface ProductB {
/*- 商品展示
*/
void show();
}
- 商品展示
具体产品B1和具体产品B2
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:02
*/
public class ProductB1 implements ProductB {public void show() {
System.out.println(“产品B1被生产”);
}
}
package com.factory.abstractFactory;
/**
-
@author xiang.wei
-
@create 2018/4/8 11:02
*/
public class ProductB2 implements ProductB {public void show() {
System.out.println(“产品B2被生产”);
}
}
总结:抽象工厂模式的角色与工厂方法模式的角色相同,可以将抽象工厂模式看成是工厂方法模式的扩展。
优缺点
优点
降低耦合
抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展。
更符合开-闭原则
新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可。而简单工厂模式需要修改工厂类的判断逻辑。
符合单一职责原则
每个具体工厂类只负责创建对应的产品,而简单工厂中的工厂类存在复杂的switch逻辑判断。
不使用静态工厂方法, 可以形成基于继承的等级结构
不使用静态工厂方法, 可以形成基于继承的等级结构,简单工厂模式的工厂类使用静态工厂方法。
缺点
抽象工厂模式很难支持新种类产品的变化。
这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
对于新的产品族符合开-闭原则;对于新的产品种类不符合开-闭原则,这一特性称为开-闭原则的倾斜性。
不管简单工厂模式,工厂方法模式还是抽象工厂模式,他们具有相似的特性,所以他们的适用场景也是类似的。
首先,作为一种创建型模式,在任何需要生成复杂对象的地方。都可以使用工厂方法模式,有一点需要注意的是复杂对象适合适用工厂模式,而简单对象,特别是只需要通过new
就可以完成创建的对象,无需适用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
其次,工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中的表现的尤其明显。例如调用者自己组装增加依赖关系时,可以考虑试用工厂模式。将会大大降低对象之间的耦合度。
最后,由于工厂模式是依赖抽象架构的。它把实例化产品的任务交由实现类完成,扩展性比较好,也就是,当系统需要有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
引用
https://www.cnblogs.com/yumo1627129/p/7197524.html
https://blog.csdn.net/qq_25551295/article/details/49837513
作者:码农飞哥
微信公众号:码农飞哥