软件设计模式--第二章 创建型模式--工厂方法模式


第二章 创建型模式

1、创建型模式概述

  • 主要特点
    对象的创建与使用分离”,这样可以降低系统的耦合度。

  • 创建型模式分为以下几种:
    单例(Singleton)模式 :某个类只能生成一个实例,该类提供了一个全 局访问点供外部获取该实例,其拓展是有限多例模式。
    原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克 隆出多个和原型类似的新实例。
    工厂方法(Factory Method)模式:定义一个用于创建产品的接口,由子 类决定生产什么产品。
    抽象工厂(Abstract Factory)模式:提供一个创建产品族的接口,其每 个子类可以生产一系列相关的产品。
    建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分, 然后根据不同需要分别创建它们,最后构建成该复杂对象。

2、工厂方法模式(Factory method)

(1)模式的定义与特点

  1. 定义:定义一个创建产品对象的工厂接口,将产品对象的实际创 建工作推迟到具体子工厂类当中。
  • 这满足创建型模式中所要求的“创建与使用相分离”的特点。
  1. 优点:用户知道具体工厂的名称就可得到所要的产品,无须知道产品的创建过程满足开闭原则。

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

(2)模式的结构与实现

1、结构

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

结构图:
在这里插入图片描述
2、实现

例:用工厂方法 模式设计畜牧场

  • 有很多种类的 畜牧场,如养马场用于养 马,养牛场用于养牛。
    在这里插入图片描述

代码:
抽象产品,动物类:

//抽象产品:动物类
interface Animal {
    public void show();
}

具体产品,马类:

//具体产品:马类
class Horse implements Animal {
    String horse;

    public Horse() {
        horse = "马";
    }

    public void show() {
        // // 调用父类的show方法时显示
        System.out.println(horse);
    }
}

具体产品,牛类:

//具体产品:牛类
class Cattle implements Animal {
    String cattle;

    public Cattle() {
        cattle = "牛";
    }

    public void show() {
        // 调用父类的show方法时显示
        System.out.println(cattle);
    }
}

抽象工厂,畜牧场:

//抽象工厂:畜牧场
interface AnimalFarm {
    // 创建产品,动物
    public Animal newAnimal();
}

具体工厂,养马场:

//具体工厂:养马场
class HorseFarm implements AnimalFarm {

    // 重写父类方法,创建具体动物
    public Animal newAnimal() {
        System.out.println("新马出生!");
        // 创建并返回马
        return new Horse();
    }
}

具体工厂,养牛场:

//具体工厂:养牛场
class CattleFarm implements AnimalFarm {
    public Animal newAnimal() {
        System.out.println("新牛出生!");
        return new Cattle();
    }
}

config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
	// 养牛场
	<className>CattleFarm</className>
</config>

ReadXML:该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象

class ReadXML{
    //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
    public static Object getObject() {
        try {
            //创建文档对象
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;
            // 对读取配置文件路径
            doc = builder.parse(new File("src/chapter03/factoryMethod/config.xml"));
            //获取包含类名的文本节点
            NodeList nl = doc.getElementsByTagName("className");  
            Node classNode = nl.item(0).getFirstChild();  // classNode =CattleFarm
            String cName = "chapter03.factoryMethod." + classNode.getNodeValue();
            // cName : chapter03.factoryMethod.CattleFarm
           
            //通过类名生成实例对象并将其返回
            Class<?> c = Class.forName(cName);
            Object obj = c.newInstance();
            return obj;  // return new CattleFarm();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

测试:

public class AnimalFarmTest {
    public static void main(String[] args) {
        try {
            // 抽象产品
            Animal a;
            // 抽象工厂
            AnimalFarm af;
            // 读取配置文件中的具体工厂
            af = (AnimalFarm) ReadXML2.getObject();
            // 通过获得的具体工厂创建具体产品
            a = af.newAnimal();
            // 展示
            a.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

(3)应用场景

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

(4)扩展

  • 当需要生成的产品不多且不会增加,一个具体工厂类就可以完成任务时,可删除抽象工厂类。这时工厂方法模式将退化到简单工厂模式

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绿箭柠檬茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值