-
工厂模式用于解决哪些问题?
在开发大型系统过程中,往往会出现这样一种情况:我有一部分基础数据,是类classA是从数据库A读取出来的,其他很多的功能都是基于这个基础数据来操作的。现在呢,我想把数据从数据库A变成从另外的数据源去获取,这时候,要修改起来就比较麻烦,要修改其他很多类的代码。这种设计显然是不够灵活的,换句话说,就是紧耦合的,系统中某个部分的函数或类严重依赖于系统的其他部分中的函数或类的行为和结构。
-
什么是工厂模式?
工厂模式,就是解决这样的一些情况的设计方法。工厂模式是一种类,建立了一个工厂来根据所需来创建对象,这种方式在多态性编程中是很重要的,允许动态替换类,修改配置等。不论是工厂模式还是其它创建型模式,都是一个目的——为了初始化一个对象。
-
为什么要使用工厂模式?
那么,问题来了,为什么有 new 这样方式可以创建一个对象,还要使用设计模式。本质上就是一个原因,不想让上层使用者直接使用 new 来初始化对象。这样的原因有很多,绝大多数原因就是对上层的使用者隔离对象创建的过程;或者是对象创建的过程复杂,使用者不容易掌握;或者是对象创建要满足某种条件,这些条件是业务的需求也好,是系统约束也好,没有必要让上层使用者掌握,增加别人开发的难度。
-
工厂模式的分类
工厂模式分为:简单工厂模式、工厂方法模式、抽象工厂模式。抽象工厂由多条产品线,而工厂方法只有一条产品线,是抽象工厂的简化。而工厂方法和简单工厂相对,大家初看起来好像工厂方法增加了许多代码但是实现的功能和简单工厂一样。但本质是,简单工厂并未严格遵循设计模式的开闭原则,当需要增加新产品时也需要修改工厂代码。但是工厂方法则严格遵守开闭原则,模式只负责抽象工厂接口,具体工厂交给客户去扩展。在分工时,核心工程师负责抽象工厂和抽象产品的定义,业务工程师负责具体工厂和具体产品的实现。只要抽象层设计的好,框架就是非常稳定的。
4.1 简单工厂模式
简单工厂模式,通过静态方法创建对象。可以理解成,只负责生产同一等级结构中的任何一个产品,但是不能新增产品。
/**
*简单工厂模式与工厂方法模式比较。
*简单工厂又叫静态工厂方法模式,这样理解可以确定,简单工厂模式是通过一个静态方法创建对象的。
*/
interface people {
function jiehun();
}
class man implements people{
function jiehun() {
echo '送玫瑰,送戒指!<br>';
}
}
class women implements people {
function jiehun() {
echo '穿婚纱!<br>';
}
}
class SimpleFactoty {
// 简单工厂里的静态方法
static function createMan() {
return new man;
}
static function createWomen() {
return new women;
}
}
$man = SimpleFactoty::createMan();
$man->jiehun();
$man = SimpleFactoty::createWomen();
$man->jiehun();
4.2 工厂方法模式
/*
*工厂方法模式:
*定义一个创建对象的接口,让子类决定哪个类实例化。 他可以解决简单工厂模式中的封闭开放原则问题。
*/
interface people {
function jiehun();
}
class man implements people{
function jiehun() {
echo '送玫瑰,送戒指!<br>';
}
}
class women implements people {
function jiehun() {
echo '穿婚纱!<br>';
}
}
interface createMan { // 注意了,这里是简单工厂本质区别所在,将对象的创建抽象成一个接口。
function create();
}
class FactoryMan implements createMan{
function create() {
return new man;
}
}
class FactoryWomen implements createMan {
function create() {
return new women;
}
}
class Client {
// 简单工厂里的静态方法
function test() {
$Factory = new FactoryMan;
$man = $Factory->create();
$man->jiehun();
$Factory = new FactoryWomen;
$man = $Factory->create();
$man->jiehun();
}
}
$f = new Client;
$f->test();
4.3 抽象工厂
/*
抽象工厂:提供一个创建一系列相关或相互依赖对象的接口。
注意:这里和工厂方法的区别是:一系列,而工厂方法则是一个。
那么,我们是否就可以想到在接口create里再增加创建“一系列”对象的方法呢?
*/
interface people {
function jiehun();
}
class Oman implements people{
function jiehun() {
echo '美女,我送你玫瑰和戒指!<br>';
}
}
class Iman implements people{
function jiehun() {
echo '我偷偷喜欢你<br>';
}
}
class Owomen implements people {
function jiehun() {
echo '我要穿婚纱!<br>';
}
}
class Iwomen implements people {
function jiehun() {
echo '我好害羞哦!!<br>';
}
}
interface createMan { // 注意了,这里是本质区别所在,将对象的创建抽象成一个接口。
function createOpen(); //分为 内敛的和外向的
function createIntro(); //内向
}
class FactoryMan implements createMan{
function createOpen() {
return new Oman;
}
function createIntro() {
return new Iman;
}
}
class FactoryWomen implements createMan {
function createOpen() {
return new Owomen;
}
function createIntro() {
return new Iwomen;
}
}
class Client {
// 简单工厂里的静态方法
function test() {
$Factory = new FactoryMan;
$man = $Factory->createOpen();
$man->jiehun();
$man = $Factory->createIntro();
$man->jiehun();
$Factory = new FactoryWomen;
$man = $Factory->createOpen();
$man->jiehun();
$man = $Factory->createIntro();
$man->jiehun();
}
}
$f = new Client;
$f->test();
5 各工厂模式的区别:
简单工厂模式:用来生产同一等级结构中的任意产品。对与增加新的产品,无能为力
工厂模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法
6 工厂模式的适用范围:
简单工厂模式:
工厂类负责创建的对象较少,客户只知道传入工厂类的参数,对于如何创建对象不关心。
工厂方法模式:
当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中得某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法模式。
抽象工厂模式:
一个系统不应当依赖于产品类实例何如被创建,组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统有多于一个的产品族,而系统只消费其 中某一产品族。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从 而使客户端不依赖于实现。
无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定。
网友评论