当前位置: 首页 > wzjs >正文

建设工程造价员网站网站运营及推广方案

建设工程造价员网站,网站运营及推广方案,软件工程师岗位职责,青海格尔木建设局网站目录 前言 一、面向对象的两类对象创建问题 二、解决问题 三、工厂模式代码示例 四、工厂模式的核心功能 五、工厂模式的应用场景 六、工厂模式的实现与结构 七、工厂模式的优缺点 八、工厂模式的扩展与优化 九、总结 前言 在面向对象系统设计中,开发者常…

目录

前言

一、面向对象的两类对象创建问题

二、解决问题

三、工厂模式代码示例

四、工厂模式的核心功能

五、工厂模式的应用场景

六、工厂模式的实现与结构

七、工厂模式的优缺点

八、工厂模式的扩展与优化

九、总结


前言

        在面向对象系统设计中,开发者常常面临两类典型的对象创建问题。为了解决这些问题,工厂模式(Factory Pattern)应运而生,成为了一种广泛应用的解决方案。本文将详细探讨这两类问题,并分析工厂模式的功能、实现及其在实际开发中的应用。

一、面向对象的两类对象创建问题

(1)抽象基类与多态带来的问题

        为了提高代码的内聚性(Cohesion)和降低耦合性(Coupling),我们通常会抽象出类的公共接口,形成抽象基类或接口。通过声明指向基类的指针来指向实际子类的实现,从而实现多态性。然而,这种做法也带来了以下问题:
        子类名称依赖:客户端代码必须知道具体子类的名称。随着系统复杂度的增加,命名冲突和可读性问题变得难以处理,尤其是当开发者有不同的命名偏好时。
        扩展性与维护困难:每次使用子类时都需要显式地实例化(如 `new ×××`),导致代码重复,扩展性和维护性变差。

(2)父类无法确定具体子类的问题

        在某些情况下,父类并不知道具体要实例化哪一个子类。例如,假设在类 A 中需要使用类 B,而 B 是一个抽象父类。在类 A 中无法确定具体实例化哪一个 B 的子类,但类 A 的子类 D 可以知道。此时,在类 A 中无法直接使用类似 `new ×××` 的语句,因为具体类型未知。

二、解决问题

        我们通常使用工厂模式(Factory Pattern)来解决上述两个问题。在处理第一个问题时,常见的做法是声明一个创建对象的接口,并将对象的创建过程封装起来。此时,工厂类就像一个真正的“生产工厂”,负责生成所需的对象。

        而在第二个问题中,我们需要提供一个对象创建的接口,并在子类中实现具体的创建逻辑,因为只有子类能够决定实例化哪个具体类。 

第一中情况的 Factory 的结构示意图为:

图1

        图1展示了第一种情况的工厂模式结构示意图。

        这种模式在系统开发中经常被使用,但这并不是工厂模式的最大优势所在(因为这个问题可以通过其他方式解决)。工厂模式不仅仅提供了创建对象的接口,更重要的是它延迟了子类的实例化(即第二个问题)。以下是这种情况的工厂模式结构示意图: 

图2

        图2展示了第二种情况的工厂模式结构示意图。图2中的关键在于,工厂模式的应用并不仅限于封装对象的创建,而是将对象的创建过程放到子类中实现:工厂类只提供对象创建的接口,而具体的实现则由其子类(如 `ConcreteFactory`)完成。这正是图2与图1的主要区别所在。

三、工厂模式代码示例


Product.h

#ifndef PRODUCT_H
#define PRODUCT_H#include <iostream>// 抽象基类 Product
class Product {
public:virtual ~Product() = 0; // 纯虚析构函数
protected:Product() = default; // 默认构造函数,限制为派生类访问
};// 具体派生类 ConcreteProduct
class ConcreteProduct : public Product {
public:ConcreteProduct();~ConcreteProduct() override;
};#endif // PRODUCT_H


Product.cpp

#include "Product.h"// 纯虚析构函数的实现
Product::~Product() = default;// ConcreteProduct 实现
ConcreteProduct::ConcreteProduct() {std::cout << "ConcreteProduct created." << std::endl;
}ConcreteProduct::~ConcreteProduct() {std::cout << "ConcreteProduct destroyed." << std::endl;
}


Factory.h

#ifndef FACTORY_H
#define FACTORY_Hclass Product;// 抽象基类 Factory
class Factory {
public:virtual ~Factory() = 0; // 纯虚析构函数virtual Product* CreateProduct() = 0; // 工厂方法
protected:Factory() = default; // 默认构造函数,限制为派生类访问
};// 具体派生类 ConcreteFactory
class ConcreteFactory : public Factory {
public:ConcreteFactory();~ConcreteFactory() override;Product* CreateProduct() override;
};#endif // FACTORY_H


Factory.cpp

#include "Factory.h"
#include "Product.h"
#include <iostream>// 纯虚析构函数的实现
Factory::~Factory() = default;// ConcreteFactory 实现
ConcreteFactory::ConcreteFactory() {std::cout << "ConcreteFactory created." << std::endl;
}ConcreteFactory::~ConcreteFactory() {std::cout << "ConcreteFactory destroyed." << std::endl;
}Product* ConcreteFactory::CreateProduct() {return new ConcreteProduct();
}


main.cpp

#include "Factory.h"
#include "Product.h"
#include <iostream>int main() {// 创建工厂对象Factory* fac = new ConcreteFactory();// 使用工厂创建产品对象Product* p = fac->CreateProduct();// 释放对象delete p;delete fac;return 0;
}

        在示例代码中,工厂模式(Factory Pattern)被用来解决父类无法确定具体要实例化哪一个子类的问题。至于为创建对象提供接口的问题,可以通过在工厂类中附加相应的创建操作来实现,例如添加 `Create***Product()` 方法。

        工厂模式(Factory Pattern)在实际开发中应用非常广泛,尤其是在面向对象系统中,开发者经常面临对象创建的问题:需要创建的类数量非常多。工厂模式通过提供创建对象的接口封装(第一个功能)以及将类的实例化推迟到子类(第二个功能),部分地解决了这些实际问题。一个典型的例子是笔者在开发 VisualCMCS 系统的语义分析模块时,由于需要为文法中的每个非终结符构造一个处理类,因此对象的创建非常频繁。采用工厂模式后,系统的可读性和维护性都变得更加优雅(elegant)。

        然而,工厂模式也带来至少以下两个问题:  
        (1)接口封闭性问题:如果为每一个具体的 `ConcreteProduct` 类的实例化提供一个单独的函数体,那么我们可能不得不在系统中不断添加新的方法来处理这些新创建的 `ConcreteProduct`。这样,工厂接口就难以做到封闭(Close)。虽然可以通过创建一个工厂的子类来利用多态性实现这一点,但这也会导致需要新增一个类作为代价。  
        (2)参数化工厂方法:在实现中,我们可以通过参数化工厂方法,即给 `FactoryMethod()` 传递一个参数来决定创建哪一个具体的 `Product`(实际上,笔者在 VisualCMCS 中也采用了这种方式)。此外,还可以通过模板化来避免第一个问题中的子类创建,具体方法是将具体的 `Product` 类作为模板参数,实现起来也非常简单。  

        可以看出,工厂模式为对象的创建提供了一种优秀的实现策略。然而,工厂模式仅限于处理同一类别的类(即这些类有一个共同的基类)。如果我们需要为不同类别的类提供一个对象创建的接口,那么就需要使用抽象工厂模式(AbstractFactory)了。抽象工厂模式我们下节再讲。

四、工厂模式的核心功能

工厂模式通过以下两个核心功能,解决了上述问题:
(1)定义创建对象的接口,封装对象的创建过程:工厂模式将对象的创建过程抽象化,客户端代码只需依赖工厂接口,而无需关心具体类的实例化细节。
(2)将具体类的实例化延迟到子类:工厂模式允许子类决定实例化哪个具体类,从而将对象创建的决策推迟到运行时。

五、工厂模式的应用场景

(1)封装对象创建
        在第一个问题中,工厂模式通过声明一个创建对象的接口,封装了对象的创建过程。工厂类类似于一个“生产对象”的工厂,客户端代码只需调用工厂接口,而无需直接依赖具体类。

(2)延迟实例化到子类
        在第二个问题中,工厂模式将具体类的实例化延迟到子类。父类只需定义创建对象的接口,而具体实现则由子类完成。这种方式不仅解决了父类无法确定具体子类的问题,还提高了代码的灵活性和可扩展性。

六、工厂模式的实现与结构

(1)简单工厂模式
        简单工厂模式通过一个工厂类封装对象的创建过程。客户端代码只需调用工厂类的方法,即可获取所需对象。然而,这种模式的扩展性较差,新增产品类型时需要修改工厂类。

(2)工厂方法模式
        工厂方法模式将对象的创建延迟到子类。抽象工厂类定义创建对象的接口,具体工厂类负责实例化具体产品。这种方式符合开闭原则,新增产品类型时只需添加新的工厂类,而无需修改现有代码。

(3)抽象工厂模式
        抽象工厂模式用于创建一系列相关或依赖的对象。它为不同产品族提供创建接口,而具体工厂类负责实例化特定产品族中的对象。这种方式适用于需要创建多个不同类型对象的场景。

七、工厂模式的优缺点

(1)优点
        解耦:将对象创建与使用分离,降低了代码的耦合性。
        扩展性:新增产品类型时无需修改现有代码,符合开闭原则。
        灵活性:通过多态将对象创建延迟到运行时,支持动态决策。

(2)缺点
        类数量增加:每新增一个产品类型,可能需要添加新的工厂类,导致类数量膨胀。
        复杂性增加:工厂模式的实现可能增加系统的复杂性,尤其是抽象工厂模式。

八、工厂模式的扩展与优化

(1)参数化工厂方法
        通过为工厂方法传递参数,决定具体创建哪一个产品。这种方式可以减少工厂类的数量,但可能增加工厂方法的复杂性。

(2)模板化工厂
        将具体产品类作为模板参数,避免为每个产品类型创建新的工厂类。这种方式在 C++ 等支持模板的语言中实现较为简单。

(3)抽象工厂模式
        当需要为不同类的产品提供创建接口时,可以使用抽象工厂模式。抽象工厂模式为每个产品族提供一个创建接口,适用于复杂对象创建的场景。

九、总结

        工厂模式是面向对象设计中解决对象创建问题的经典模式。它通过封装对象创建过程和延迟实例化到子类,有效地降低了代码的耦合性,提高了系统的扩展性和灵活性。尽管工厂模式可能增加类的数量和系统的复杂性,但其在解耦和支持变化方面的优势使其在实际开发中得到了广泛应用。对于需要频繁创建对象的系统,工厂模式无疑是一种优雅且高效的解决方案。

        参考学习书籍:设计模式精解-GoF 23 种设计模式解析

http://www.dtcms.com/wzjs/138136.html

相关文章:

  • 北京做视觉网站3分钟搞定网站seo优化外链建设
  • 云南集优科技网站企业网址怎么注册
  • 深圳松岗网站建设韶关seo
  • 有什么好的网站做推广的全球搜官网
  • 如何能进腾讯做游戏视频网站python培训
  • 有口碑的番禺网站建设免费友链平台
  • 电脑做网站主机青岛百度快速排名优化
  • 湖南网站搜索排名优化公司百度资源提交
  • 购买域名之后怎么做网站软文大全500篇
  • 做网站报价出名的如何做好一个网站
  • 做网站学哪种代码好东莞seo网络营销
  • 做网站需要ps吗关键词排名点击软件怎样
  • 用rp怎么做网站原型网站建设推广优化
  • wordpress 页面顺序seo优化好做吗
  • 云南省网站备案要求百度搜索关键词推广
  • .net 开源 企业网站链接买卖
  • 厦门服装商城网站建设关键词采集网站
  • 美国客户打不开我们的网站百度统计工具
  • 网站建设及维护合同网络营销推广处点
  • 做网站5年工资多少seo优化排名营销
  • 2345网址大全最新版关于进一步优化落实疫情防控措施
  • 柳州网站建设公百度网盘会员
  • 2013电子商务网站建设考试试卷网站查询入口
  • 自己做网站成本百度资源
  • 网站建设教程论坛交换链接营销实现方式解读
  • 怎样清理网站后门山东做网站公司
  • 网站建设前期需要准备什么资料网络域名综合查询
  • 佛山企业网站建设咨询互联网营销师怎么报名
  • 威海建设局网站楼盘信息公布网上竞价平台
  • 正常网站 月均ip pv网络营销公司好不好