工厂模式是我们最常用的实例化对象模式了, 是用工厂方法代替 new 操作的一种模式, 工厂模式在 Java 程序中可以说是随处可见. 本文来给大家详细介绍下工厂模式
面向对象设计的基本原则:
OCP(开闭原则, Open-Closed Principle): 一个软件的实体应当对扩展开放, 对修改关闭.
DIP(依赖倒转原则, Dependence Inversion Principle): 要针对接口编程, 不要针对实现编程.
LoD(迪米特法则, Law of Demeter): 只与你直接的朋友通信, 而避免和陌生人通信
三种工厂模式的区别
模式 | 说明 |
---|---|
简单工厂 | 用来生产同一等级结构中的任意产品。 (对于增加新的产品,需要修改已有代码) |
工厂方法 | 用来生产同一等级结构中的固定产品。(支持增加任意产品) |
抽象工厂 | 用来生产不同产品族的全部产品。 (对于增加新的产品,无能为力;支持增加产品族) |
实现了创建者和调用者的分离
核心本质:
实例化对象, 用工厂方法代替 new 操作.
将选择实现类, 创建对象统一管理和控制. 从而将调用者跟我们的实现类解耦
简单工厂模式
接口定义
- public interface Car {
- void run();
- }
Car 实现类
- public class Audi implements Car {
- @Override
- public void run() {
- System.out.println("奥迪再跑...");
- }
- }
- public class Byd implements Car {
- @Override
- public void run() {
- System.out.println("比亚迪再跑!");
- }
- }
简单工厂类
- public class CarFactory {
- public static Car createCar(String type){
- if("奥迪".equals(type)){
- return new Audi();
- }else if("比亚迪".equals(type)){
- return new Byd();
- }else{
- return null;
- }
- }
- }
- public class CarFactory2 {
- public static Car createAudi(){
- return new Audi();
- }
- public static Car createByd(){
- return new Byd();
- }
- }
测试
- public class Client02 { // 调用者
- public static void main(String[] args) {
- Car c1 =CarFactory.createCar("奥迪");
- Car c2 = CarFactory.createCar("比亚迪");
- c1.run();
- c2.run();
- }
- }
小结:
简单工厂模式也叫静态工厂模式, 就是工厂类一般是使用静态方法, 通过接收的参数的不同来返回不同的对象实例.
对于增加新产品无能为力! 不修改代码的话, 是无法扩展的.
工厂方法模式
工厂方法模式要点:
为了避免简单工厂模式的缺点, 不完全满足 OCP.
工厂方法模式和简单工厂模式最大的不同在于, 简单工厂模式只有一个 (对于一个项目工厂方法模式和简单工厂模式最大的不同在于, 简单工厂模式只有一个(对于一个项目或者一个独立模块而言) 工厂类, 而工厂方法模式有一组实现了相同接口的工厂类
业务接口
- public interface Car {
- void run();
- }
car 实现类
- public class Audi implements Car {
- @Override
- public void run() {
- System.out.println("奥迪再跑!");
- }
- }
- public class Benz implements Car {
- @Override
- public void run() {
- System.out.println("奔驰再跑!");
- }
- }
工厂接口
- public interface Car {
- void run();
- }
每个 car 实现类对应创建一个工厂类
- public class AudiFactory implements CarFactory {
- @Override
- public Car createCar() {
- return new Audi();
- }
- }
- public class BenzFactory implements CarFactory {
- @Override
- public Car createCar() {
- return new Benz();
- }
- }
测试
- public class Client {
- public static void main(String[] args) {
- Car c1 = new AudiFactory().createCar();
- Car c2 = new BydFactory().createCar();
- c1.run();
- c2.run();
- }
- }
简单工厂模式和工厂方法模式 PK:
结构复杂度
从这个角度比较, 显然简单工厂模式要占优. 简单工厂模式只需一个工厂类, 而工厂方法模式的工厂类随着产品类个数增加而增加, 这无疑会使类的个数越来越多, 从而增加了结构的复杂程度.
代码复杂度
代码复杂度和结构复杂度是一对矛盾, 既然简单工厂模式在结构方面相对简洁, 那么它在代码方面肯定是比工厂方法模式复杂的了. 简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码), 而工厂方法模式每个具体工厂类只完成单一任务, 代码简洁.
客户端编程难度
工厂方法模式虽然在工厂类结构中引入了接口从而满足了 OCP, 但是在客户端编码中需要对工厂类进行实例化. 而简单工厂模式的工厂类是个静态类, 在客户端无需实例化, 这无疑是个吸引人的优点.
管理上的难度
这是个关键的问题.
我们先谈扩展. 众所周知, 工厂方法模式完全满足 OCP, 即它有非常良好的扩展性. 那是否就说明了简单工厂模式就没有扩展性呢? 答案是否定的. 简单工厂模式同样具备良好的扩展性 -- 扩展的时候仅需要修改少量的代码(修改工
厂类的代码)就可以满足扩展性的要求了. 尽管这没有完全满足 OCP, 但我们不需要太拘泥于设计理论, 要知道, sun 提供的 java 官方工具包中也有想到多没有满足 OCP 的例子啊. 然后我们从维护性的角度分析下. 假如某个具体产品类需要进行一定的修改, 很可能需要修改对应的工厂类. 当同时需要修改多个产品类的时候, 对工厂类的修改会变得相当麻烦(对号入座已经是个问题了). 反而简单工厂没有这些麻烦, 当多个产品类需要修改是, 简单工厂模式仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧? 大不了把这个类重写).
根据设计理论建议: 工厂方法模式. 但实际上, 我们一般都用 == 简单工厂模式 ==.
抽象工厂模式
用来生产不同产品族的全部产品.(对于增加新的产品, 无能为力;
支持增加产品族)
抽象工厂模式是工厂方法模式的升级版本, 在有多个业务品种, 业务
分类时, 通过抽象工厂模式产生需要的对象是一种非常好的解决方式.
类图
案例代码
- public interface Engine {
- void run();
- void start();
- }
- class LuxuryEngine implements Engine{
- @Override
- public void run() {
- System.out.println("转的快!");
- }
- @Override
- public void start() {
- System.out.println("启动快! 可以自动启停!");
- }
- }
- class LowEngine implements Engine{
- @Override
- public void run() {
- System.out.println("转的慢!");
- }
- @Override
- public void start() {
- System.out.println("启动慢!");
- }
- }
- public interface Seat {
- void massage();
- }
- class LuxurySeat implements Seat {
- @Override
- public void massage() {
- System.out.println("可以自动按摩!");
- }
- }
- class LowSeat implements Seat {
- @Override
- public void massage() {
- System.out.println("不能按摩!");
- }
- }
- public interface Tyre {
- void revolve();
- }
- class LuxuryTyre implements Tyre {
- @Override
- public void revolve() {
- System.out.println("旋转不磨损!");
- }
- }
- class LowTyre implements Tyre {
- @Override
- public void revolve() {
- System.out.println("旋转磨损快!");
- }
- }
工厂模式
- public interface CarFactory {
- Engine createEngine();
- Seat createSeat();
- Tyre createTyre();
- }
- public class LowCarFactory implements CarFactory {
- @Override
- public Engine createEngine() {
- return new LowEngine();
- }
- @Override
- public Seat createSeat() {
- return new LowSeat();
- }
- @Override
- public Tyre createTyre() {
- return new LowTyre();
- }
- }
- public class LuxuryCarFactory implements CarFactory {
- @Override
- public Engine createEngine() {
- return new LuxuryEngine();
- }
- @Override
- public Seat createSeat() {
- return new LuxurySeat();
- }
- @Override
- public Tyre createTyre() {
- return new LuxuryTyre();
- }
- }
测试
- public class Client {
- public static void main(String[] args) {
- CarFactory factory = new LuxuryCarFactory();
- Engine e = factory.createEngine();
- e.run();
- e.start();
- }
- }
工厂模式要点:
简单工厂模式(静态工厂模式)
• 虽然某种程度不符合设计原则, 但实际使用最多.
工厂方法模式
• 不修改已有类的前提下, 通过增加新的工厂类实现扩展.
抽象工厂模式
• 不可以增加产品, 可以增加产品族!
应用场景
| 序号 | 应用场景 |
|--|:--|
|1|JDK 中 Calendar 的 getInstance 方法 |
|2|JDBC 中 Connection 对象的获取 |
|3|Hibernate 中 SessionFactory 创建 Session|
|4| spring 中 IoC 容器创建管理 bean 对象 |
|5|xml 解析时的 DocumentBuilderFactory 创建解析器对象 |
|6| 反射中 Class 对象的 newInstance()|
posted on 2019-02-23 21:26 ゞ . 邓澎波 阅读(...) 评论(...) 编辑 收藏
来源: https://www.cnblogs.com/dengpengbo/p/10424325.html