设计模式之工厂模式的理解

设计模式之工厂模式的理解

工厂模式是一种创建型模式,相信工作中大家都会接触过一些,下面将详细讨论一下

讲解流程主要是:UML类图 + 代码实现 + 优势与劣势

一、简单工厂模式:

创建对象时做简单的封装

1、UML类图:
在这里插入图片描述
UML类图分析:

1、创建一个产品接口 (AbstractProduct)
2、产品的具体实现类(Product1 和 Product2)
3、工厂类 (Factory)

2、代码实现:

// 产品接口
public interface AbstractProduct {
    doSomething();
}

// 产品具体实现类 Product1
public class Product1 implements AbstractProduct {
    @override
    public doSomething() {
        System.out.println("Product1");
    }
}

// 产品具体实现类 Product2
public class Product2 implements AbstractProduct {
    @override
    public doSomething() {
        System.out.println("Product2");
    }
}

// 工厂类:
public class Factory {
    public AbstractProduct do(String productType) {
        if (productType.equals("Product1")) {
            return new Product1();
        } else if (productType.equals("Product2")) {
		   return new Product2();
        }
    }
}

3、分析:简单工厂模式实际就是所有产品类都交给一个具体的工厂进行实现,主要的好处是 :

	传统的方式是在使用对象的时候通过new方法进行创建,通过简单工厂模式就可以在使用时通过工厂创建
(将对象创建与对象使用进行解耦)

​ 但是当引入新的产品Product3时,就需要添加一个Product3实现类,并且修改原本的工厂类,如下:

// 新增产品具体实现类 Product3
public class Product2 implements AbstractProduct {
    @override
    public doSomething() {
        System.out.println("Product2");
    }
}

// 修改工厂类为:
public class Factory {
    public AbstractProduct do(String productType) {
        if (productType.equals("Product1")) {
            return new Product1();
        } else if (productType.equals("Product2")) {
		   return new Product2();
        } else if (productType.equals("Product3")) {
		   return new Product3();
        }
    }
}

在面向对象开发中有一个很重要的原则:开闭原则

概念:程序扩展是开放的,程序修改是封闭的,扩展优于修改

在新增产品时,很明显的,我们要修改原有的工厂代码,违背了开闭原则。

二、工厂方法模式

应对要新增产品带来开闭原则的问题,这里引入了工厂方法模式:

将工厂类抽象,由多个产品对应一个工厂 ----> 多个产品对应多个工厂

1、UML类图:
在这里插入图片描述
UML类图分析:

1、 创建一个产品接口: AbStractProduct
2、 创建产品的具体实现类: Product1 、 Product2 
3、 创建一个工厂接口 : AbstractFactory
4、 创建工厂的具体实现类 : ConcreteFactory1 、ConcreteFactory2

2、代码实现:

// 产品接口
public interface AbstractProduct {
    doSomething();
}

// 产品具体实现类 Product1
public class Product1 implements AbstractProduct {
    @override
    public doSomething() {
        System.out.println("Product1");
    }
}

// 产品具体实现类 Product2
public class Product2 implements AbstractProduct {
    @override
    public doSomething() {
        System.out.println("Product2");
    }
}


// 工厂接口:AbstractFactory
public interface AbstractFactory {
    public AbstractProduct do();
}

// 针对 Product1 的的工厂类
public ConcreteFactory1 implements AbstractFactory {
    public AbstractProduct do() {
        return new Product1();
    }
}

// 针对 Product2 的工厂类
public ConcreteFactory1 implements AbstractFactory {
    public AbstractProduct do() {
        return new Product2();
    }
}

3、分析:

主要优势:

在新增一个产品类时,需要新增一个产品具体实现类和具体产品对应的工厂类,包含简单工厂模式的解耦优点,也实现扩展由于修改,没有违背开闭原则
三、抽象工厂模式

引入抽象工厂模式时,不能说这个模式就一定高大上,主要还是看使用场景

与工厂方法模式相比,抽象工厂模式主要是打破了工厂与产品一对一,使得具体工厂可以创造一个大类

1、UML类图
在这里插入图片描述

UML类图分析:与工厂方法模式对比

1、引入了新的产品维度(产品AB),即在原本的产品维度(12)基础上加上了产品维度(AB)
2、创建俩个大类产品接口 AbstractProductA 和 AbstractProductB
3、编写产品的具体实现类: ProductA1、ProductA2、ProductB1、ProductB2
4、针对大类产品接口,编写大类工厂接口 AbstractFactory
5、编写俩个大类工厂类: ConcreteFactory1、 ConcreteFactory2

代码实现:

// 大类产品接口 AbstractProductA
public interface AbstractProductA {
    doSomething();
}

// 大类产品接口 AbstractProductB
public interface AbstractProductB {
    doSomething();
}

// 产品具体实现类 ProductA1
public class ProductA1 implements AbstractProductA {
    @override
    public doSomething() {
        System.out.println("ProductA1");
    }
}

// 产品具体实现类 ProductA2
public class ProductA2 implements AbstractProductA {
    @override
    public doSomething() {
        System.out.println("ProductA2");
    }
}

// 产品具体实现类 ProductB1
public class ProductB1 implements AbstractProductB {
    @override
    public doSomething() {
        System.out.println("Product2");
    }
}

// 产品具体实现类 ProductB2
public class ProductB2 implements AbstractProductB {
    @override
    public doSomething() {
        System.out.println("ProductB2");
    }
}


// 工厂接口:AbstractFactory
public interface AbstractFactory {
    public AbstractProduct createProductA();
    public AbstractProduct createProductB();
}

// 针对 Product1 的的工厂类
public ConcreteFactory1 implements AbstractFactory {
    public AbstractProduct createProductA() {
        return new ProductA1();
    }
    public AbstractProduct createProductB() {
        return new ProductB1();
    }
}

// 针对 Product2 的工厂类
public ConcreteFactory2 implements AbstractFactory {
    public AbstractProduct createProductA() {
        return new ProductA2();
    }
    public AbstractProduct createProductB() {
        return new ProductB2();
    }
}

分析:

当新增一个产品维度时,使用抽象工厂模式可以减少创建工厂类,但是当在引入一个新的产品ProductC时,就需要改变工厂类的方法,又会违背开闭原则 。

当引入ProductC时:

// 改变 Product1 的的工厂类
public ConcreteFactory1 implements AbstractFactory {
    public AbstractProduct createProductA() {
        return new ProductA1();
    }
    public AbstractProduct createProductB() {
        return new ProductB1();
    }
    public AbstractProduct createProductB() {
        return new ProductC1();
    }
}

// 改变 Product2 的的工厂类
public ConcreteFactory2 implements AbstractFactory {
    public AbstractProduct createProductA() {
        return new ProductA2();
    }
    public AbstractProduct createProductB() {
        return new ProductB2();
    }
    public AbstractProduct createProductB() {
        return new ProductC2();
    }
}

总结:上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可,可灵活变通,无所谓高级与低级。

此外无论哪种模式,由于可能封装了大量对象和工厂创建,新加产品需要修改已定义好的工厂相关的类,因此对于产品和工厂的扩展不太友好,利弊需要权衡一下。

实际应用1

集合类的Collection:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YXtuYgex-1604249312752)(C:\Users\晓\AppData\Roaming\Typora\typora-user-images\1604243974896.png)]

blic AbstractProduct createProductB() {
return new ProductC2();
}
}




总结:上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可,可灵活变通,无所谓高级与低级。

此外无论哪种模式,由于可能封装了大量对象和工厂创建,新加产品需要修改已定义好的工厂相关的类,因此对于产品和工厂的扩展不太友好,利弊需要权衡一下。



##### 实际应用1

集合类的Collection:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201102005205235.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDQzNDIxNA==,size_16,color_FFFFFF,t_70#pic_center)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值