创建型模式(一):工厂方法模式(含简单工厂模式)

1、创建型模式的特点

创建型模式关注的是“怎样创建对象”,特点是“将对象的创建与使用分离”。
这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。就像我们去商场购买商品时,并不需要知道商品是怎么生产出来的,因为它们由专门的厂商生产。

2、工厂方法模式的定义

工厂方法(FactoryMethod)模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
这满足创建型模式中所要求的“创建与使用相分离”的特点。

我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。
如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于 GoF 的 23 种经典[设计模式],它的缺点是增加新产品时会违背“开闭原则”。

本节介绍的“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。

3、工厂方法模式的特点

优点:
1、用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
2、在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

缺点:
每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

4、工厂方法模式的应用场景

1、客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
2、创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
3、客户不关心创建产品的细节,只关心产品的品牌。

5、工厂方法模式的结构

工厂方法模式由抽象工厂、具体工厂、抽象产品和具体产品等4个要素构成。
抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
1-1 工厂方法模式结构图

1-1 工厂方法模式结构图

6、工厂方法模式的扩展-简单工厂模式

简单工厂模式即静态工厂方法模式
当需要生成的产品不多且不会增加,一个具体工厂类就可以完成任务时,可删除抽象工厂类。这时工厂方法模式将退化到简单工厂模式,只包含3个要素:工厂类角色、抽象产品角色、具体产品角色。
1-2 简单工厂模式的结构图

1-2 简单工厂模式的结构图

7、工厂方法模式的实现-含简单工厂模式实现

7.1 简单工厂模式示例

1-3 简单工厂模式示例结构图

1-3 简单工厂模式示例结构图

抽象产品类Car.java:

package com.example.designpattern.simplefactory;

/**
 * 抽象产品角色
 * Created by Administrator on 2019/10/30.
 */
public abstract class Car {
    public abstract void drive();
}

具体产品类Benz.java:

package com.example.designpattern.simplefactory;

import android.util.Log;

/**
* 具体产品角色
 * @author Administrator
 * @date 2019/10/30
 */
public class Benz extends Car {

    @Override
    public void drive() {
        System.out.println("奔驰汽车在狂奔");
    }

}

具体产品类BMW.java:

package com.example.designpattern.simplefactory;

import android.util.Log;

/**
* 具体产品角色
 * @author Administrator
 * @date 2019/10/30
 */
public class BMW extends Car {

    @Override
    public void drive() {
        System.out.println("宝马汽车在狂奔");
    }

}

工厂类Factory.java:

package com.example.designpattern.simplefactory;

/**
 * 工厂角色
 *
 * @author Administrator
 * @date 2019/10/30
 */
public class Factory {

    public static Car create(int type) {
        if (1 == type) {
            return new Benz();
        } else if (2 == type) {
            return new BMW();
        } else {
            return null;
        }
    }

}

客户端调用类Client.java:

package com.example.designpattern.simplefactory;

/**
 * @author Administrator
 * @date 2019/10/30
 * 客户端调用类
 */
public class Client {

    public static void main(String[] args) {
        Car car1 = Factory.create(1);
        assert car1 != null;
        car1.drive();

        Car car2 = Factory.create(2);
        assert car2 != null;
        car2.drive();
    }

}

为了解决简单工厂模式无法新增产品的弊端,我们改进下,在工厂类中,使用类的反射机制来增加产品,见Factory2.java:

package com.example.designpattern.simplefactory;


/**
 * 工厂角色
 *
 * @author Administrator
 * @date 2019/10/30
 */
public class Factory2 {

    /**
     * 根据类的反射机制,传入包名,生成对应的类,可以规避简单工厂模式无法新增产品的缺点
     */
    public static Car create(String className) {
        try {
            Car car=(Car) Class.forName(className).newInstance();
            return car;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (InstantiationException e) {
            e.printStackTrace();
            return null;
        }
    }

}

此时,我们新增一个产品,即QQ.java:

package com.example.designpattern.simplefactory;

/**
 * 具体产品角色-新增产品
 * @author Administrator
 * @date 2019/11/1
 *
 * 简单工厂模式缺点:
 * 当要新增QQ汽车时,工厂类Factory也必须修改,否则无法new出新的
 */
public class QQ extends Car {
    @Override
    public void drive() {
        System.out.println("QQ汽车在狂奔");
    }
}

最后,我们要改进Client.java类:

package com.example.designpattern.simplefactory;

/**
 * @author Administrator
 * @date 2019/10/30
 * 客户端调用类
 */
public class Client {

    public static void main(String[] args) {
        Car car1 = Factory.create(1);
        assert car1 != null;
        car1.drive();

        Car car2 = Factory.create(2);
        assert car2 != null;
        car2.drive();

        System.out.println("------------");

        //传入包名,使用类的反射机制增加新产品
        Car c1 = Factory2.create("com.example.designpattern.simplefactory.Benz");
        Car c2 = Factory2.create("com.example.designpattern.simplefactory.QQ");
        assert c1 != null;
        c1.drive();
        assert c2 != null;
        c2.drive();
    }

}

最终测试结果如下:
1-4 简单工厂模式测试结果

1-4 简单工厂模式测试结果

7.2 工厂方法模式示例

1-5 工厂方法模式示例结构图

1-5 工厂方法模式示例结构图

抽象产品类Car.java:

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 抽象产品角色
 */
public abstract class Car {
    public abstract void drive();
}

抽象工厂类Factory.java:

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 抽象工厂角色
 */
public abstract class Factory {
    public abstract Car createCar();
}

具体产品类Benz.java:

package com.example.designpattern.factorymethod;

/**
 * 具体产品
 * @author Administrator
 * @date 2019/11/25
 */
public class Benz extends Car {
    @Override
    public void drive() {
        System.out.println("奔驰在飞奔");
    }
}

具体工厂类BenzFactory.java:

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 具体工厂角色
 */
public class BenzFactory extends Factory {
    @Override
    public Car createCar() {
        return new Benz();
    }
}

具体产品BMW.java:

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 具体产品
 */
public class BMW extends Car {
    @Override
    public void drive() {
        System.out.println("宝马在飞奔");
    }
}

具体工厂BMWFactory.java:

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 具体工厂角色
 */
public class BMWFactory extends Factory {
    @Override
    public Car createCar() {
        return new BMW();
    }
}

客户端调用类:

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 客户端调用类
 */
public class Client {
    public static void main(String[] args){
        Car benz=new BenzFactory().createCar();
        benz.drive();

        Car bmw=new BMWFactory().createCar();
        bmw.drive();
    }
}

当增加新产品时,只需要新增一个具体产品类和一个具体工厂类,如

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 具体产品-增加新产品QQ时,只需要扩展出一个对应的工厂即可,即QQFactory
 */
public class QQ extends Car {
    @Override
    public void drive() {
        System.out.println("QQ在慢行");
    }
}

package com.example.designpattern.factorymethod;



/**
 * @author Administrator
 * @date 2019/11/25
 * 具体工厂角色-新增产品
 */
public class QQFactory extends Factory {
    @Override
    public Car createCar() {
        return new QQ();
    }
}

调用时,只需增加新产品调用即可:

package com.example.designpattern.factorymethod;

/**
 * @author Administrator
 * @date 2019/11/25
 * 客户端调用类
 */
public class Client {
    public static void main(String[] args){
        Car benz=new BenzFactory().createCar();
        benz.drive();

        Car bmw=new BMWFactory().createCar();
        bmw.drive();

        //增加新产品
        Car qq=new QQFactory().createCar();
        qq.drive();
    }
}

测试结果:
1-6 工厂方法模式测试结果

1-6 工厂方法模式测试结果

8、工厂方法模式知识问答

1、关于工厂方法,以下叙述不正确的是(C)
A、Factory Method 是一个用于帮助分配创建的责任的模式。
B、Factory Method 模式和 Abstract Factory 模式总是配合使用
C、Factory Method 适用于将对象实例化的规则推迟到某个派生类的情形
D、Factory Method 是属于创建型模式。

2、Factory Method(工厂方法)模式的意图是(A)
A、定义一个用于创建对象的接口,让子类决定实例化哪一个类。将实例化延迟到其子类
B、为一个对象动态连接附加的职责
C、你希望只拥有一个对象,但不用全局对象来控制对象的实例化
D、定义一个操作中的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算 法的某些特定步骤

3、下列关于静态工厂与工厂方法表述错误的是(A)
A、两者都满足开闭原则:静态工厂以 if else 方式创建对象,增加需求的时候会修改源代码
B、静态工厂对具体产品的创建类别和创建时机的判断是混和在一起的,这点在工厂方法是分开的
C、不能形成静态工厂的继承结构
D、在工厂方法模式中,对于存在继承等级结构的产品树,产品的创建是通过相应等级结构的工厂创建的

9、工厂方法模式PPT素材

01_设计模式

01_设计模式

02_设计模式分类

02_设计模式分类

03_创建模式

03_创建模式

04_工厂模式

04_工厂模式

05_简单工厂模式的角色

05_简单工厂模式的角色

06_简单工厂模式类图

06_简单工厂模式类图

07_简单工厂模式示例

07_简单工厂模式示例

08_简单工厂模式改进版

08_简单工厂模式改进版

09_简单工厂模式优缺点

09_简单工厂模式优缺点

10_工厂方法模式

10_工厂方法模式

11_工厂方法模式角色

11_工厂方法模式角色

12_工厂方法模式类图

12_工厂方法模式类图

13_工厂方法模式

13_工厂方法模式

14_设计模式的优点

14_设计模式的优点

15_设计模式用来解决什么问题

15_设计模式用来解决什么问题

16_设计模式的两大主题

16_设计模式的两大主题

17_设计模式不能解决什么

17_设计模式不能解决什么

18_静态工厂的核心

18_静态工厂的核心

19_工厂方法题

19_工厂方法题

20_工厂方法题

20_工厂方法题

21_工厂方法题

21_工厂方法题

微信公众号: TechU
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值