设计模式专题(五)——工厂方法模式

设计模式专题(五)——工厂方法模式

(原创内容,转载请注明来源,谢谢)

一、概述

1、工厂方法与简单工厂模式区别

工厂方法模式与简单工厂模式不同

简单工厂模式最大优点在于工厂类类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,除去了与具体产品的依赖。但是,当需要新增、删除工厂类的功能,违反了开放-封闭原则。

工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其他子类。对工厂需要新增功能,只需要新增具体的工厂类,去继承工厂接口;再新增实现方法类,去继承实现接口,符合开放-封闭原则。

2、工厂方法模式存在问题

1)简单方法模式中在工厂类的逻辑判断部分,被交到客户端去实现,因此客户端处还需要进行逻辑判断的功能。

2)仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建一个Creator子类。

3、类图

4、工厂方法模式结构

1)抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

2)具体工厂(ConcreteCreator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。

3)抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。

4)具体产品(ConcreteProduct)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

二、业务实现

1、业务场景

工厂类的设计模式最适合用于需要整合各类相似要求的业务场景,例如对数据库的操作,就可以使用工厂方法模式,现仅考虑增、删、改三个操作。

1)工厂接口

工厂接口定义具体工厂类需要的方法,在操作数据库中如连接不同表,每个表对应一个实体。

2)工厂类

工厂类继承工厂接口,其定义工厂的具体,实现对具体表产品的操作类的调用。

3)产品接口

产品接口定义产品所需要实现的功能的方法,对于每个表,有具体的方法定义。

4)产品类

产品类定义产品的具体功能实体,即对于每个表,有自己独特的增、删、改的方法。

这样的设计很灵活,且新增表格、改动表格在项目中很常见,改动后相应的增删改的操作肯定有所变动,而工厂方法模式可以很方便的对其进行改动。

另外,每个表有自己的类,因此表格的改动,可以快速找到相关客户端、服务端的调用点,进行进一步的检查。避免因某个业务调整、表格改动,导致影响其他使用该表格的业务也发生异常。

2、程序实现

<?php
//工厂方法模式,实现数据库对于每个表的增删改的定义,建立相关实体
//工厂接口
interface Factory{
       publicfunction connectDetailTable($host,$username,$password);
}
//工厂实现类——针对表table1、表table2
class table1Service implements Factory{
       publicfunction connectDetailTable($host,$username,$password){
//在已知具体某个表格的情况下,其在哪个数据库中可以确定 
              $database= 'database of table1'; 
              returnnew table1Entity(
                     newPDO('mysql:host='.$server.';dbname='.$database.'',$username,$password)
              );
       }
}
class table2Service implements Factory{
       publicfunction connectDetailTable($host,$username,$password){
              $database= 'database of table2';
              return new table2Entity(
                     newPDO('mysql:host='.$server.';dbname='.$database.'',$username,$password)
              );
       }
}
//产品接口,定义表格应该有的方法,包括新增、批量新增、修改、删除四种方法
interface Product{
       publicfunction __construct($conn);
       //createDatas=array(col1=>val1,col2=>val2...)
       publicfunction create(array $createDatas);    
//createBatchDatas=array(array(col1=>val1,col2=>val2...),array(col1=>val1...)...)
public functioncreateBatch(array $createBatchDatas);
//modifyDatas=array(array(condition1=>val1,condition2=>val2...),array(col1=>val1,col2=>val2...))
       publicfunction modify(array $modifyDatas);
//deleteDatas=array(condition1=>val1,condition2=>val2...)
       publicfunction delete(array $deleteDatas);
}
//产品实现类,实现产品接口,table1的实体
class table1Entity implements Product{
       private$conn;
       private$table;
       publicfunction __construct($conn){
              $this->conn= $conn;
              $this->table= 'table1';
       }
       publicfunction create(array $createDatas){
              //...新增逻辑,主要是针对字段的判断以及表格具体新增规则的限制,如非空、数据内容等,返回last_insert_id
       }
       publicfunction createBatch(array $createBatchDatas){
              //...批量新增逻辑,主要是针对字段的判断以及表格具体新增规则的限制,如非空、数据内容等,返回affect_rows
       }      
       publicfunction modify(array $modifyDatas){
              //...修改逻辑,主要是针对表格特有的字段进行判断,以及对特定列是否允许修改进行判断,返回affect_rows
       }
       publicfunction delete(array $deleteDatas){
              //...删除逻辑,主要是针对表格特定的删除规则,另外如果有关联其他表,还需要判断是需要删除其他表相关的数据还是不允许删除此条数据等,返回affect_rows
       }
}
//table2的实体不再描述

三、实际意义

数据库的此设计方案,在实际项目中具有重要意义。

1、规范增删改的操作,避免用户随意对表进行增删改。

2、实现对每个表的具体的判断的“定制化”,针对每个表有自己的要求去设计。

3、便于查找,降低改动的风险:其实现了工厂方法接口的灵活性,需要新增表格,只需要新增相应的service和entity;修改表格字段、删除表格,往往需要检查程序的调用点,则只需要检查相应service、entity的调用点即可。

——written by linhxx 2017.07.30

相关阅读:

设计模式专题(四)——代理模式

设计模式专题(三)——装饰模式

设计模式专题(二)——策略模式

设计模式专题(一)——面向对象的设计原则

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-07-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

逆向工厂(二):静态分析技术

* 本文原创作者:追影人,本文属FreeBuf原创奖励计划,未经许可禁止转载 前言 [逆向工厂]第一章节中介绍了逆向技术的相关基础知识,其中提到逆向的两种形式:...

4598
来自专栏24K纯开源

Python 3.x自定义迭代器对象

Python 3.x与Python 2.x之间存在着较多的语法细节差异。今天在看Python核心编程的时候,说到了自定义迭代器对象。于是动手将源码打了一遍,原书...

2286
来自专栏java一日一条

java提高篇之异常(上)

在这个世界不可能存在完美的东西,不管完美的思维有多么缜密,细心,我们都不可能考虑所有的因素,这就是所谓的智者千虑必有一失。同样的道理,计算机的世界也是不完美的,...

1082
来自专栏FreeBuf

VLC播放器加载恶意字幕文件导致执行任意代码漏洞分析与POC实现

今年5月23号的时候,听说checkpoint搞了个大新闻:vlc等播放器加载特定字幕可以完全控制用户电脑。当时我就震惊了:还有何种操作。想想看,当你吃着辣条,...

4234
来自专栏程序员的知识天地

Python牛B操作:一行代码减少一半内存占用

在项目制作中,我们必须要存储和处理一个相当大的动态列表。测试人员在测试过程中,抱怨内存不足。下面介绍一个简单的方法,通过添加一行代码来解决这个问题。

1532
来自专栏海说

深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符

本文转载地址:http://www.cnblogs.com/zuoxiaolong/p/computer14.html

1375
来自专栏海说

深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符

  本文的内容其实可以成为汇编语言的基础,因为汇编语言大部分时候是在操作一些我们平时开发看不到的东西,因此本文的目的就是搞清楚,汇编语言都是在操作些什么东西。或...

932
来自专栏北京马哥教育

Python入门教程:超详细1小时学会Python

1.Hello world 安装完Python之后,打开IDLE(Python GUI) ,该程序是Python语言解释器,你写的语句能够立即运行。 我们写下...

4555
来自专栏海说

深入理解计算机系统(3.2)---数据格式、访问信息以及操作数指示符

  本文的内容其实可以成为汇编语言的基础,因为汇编语言大部分时候是在操作一些我们平时开发看不到的东西,因此本文的目的就是搞清楚,汇编语言都是在操作些什么东西。或...

1314
来自专栏奇点大数据

用python做科学计算之pandas入门简介

pandas是一个开源的python数据分析和处理包,使用灵活方便,性能高,速度快,简单介绍一下它里面比较常用的功能 数据读取 它支持多种数据读取的方式这里简...

2956

扫码关注云+社区

领取腾讯云代金券