设计模式之创建型模式—— 1.3 抽象工厂模式

<?php

	/**
	 * 1.3 抽象工厂模式
	 * 解决的问题:
	 * 		如何解决多个类实例化对象的问题。
	 * 解决的方案:
	 * 		提供一个创建一系列相关或相互依赖对象的
	 * 	 	接口,而无需指定它们具体的类。
	 * 该模式包含四种角色:
	 * 		1. 抽象产品角色(两个或多个)
	 * 			职责:同工厂方法模式
	 * 	 	2. 具体产品角色
	 * 		 	职责:同工厂方法模式
	 * 	   	3. 抽象工厂角色
	 * 		 	职责:同工厂方法模式
	 * 	   	4. 具体工厂角色
	 * 		   职责:同工厂方法模式
	 * 优点:
	 * 		1. 易于交换产品系列,由于工厂类在
	 * 		   一个应用中只需要在初始化的时候
	 * 		   出现一次,这就使得改变一个应用
	 * 		   的具体工厂变得非常容易,它只需
	 * 		   要改变具体工厂即可使用不同的产
	 * 		   品配置。
	 * 		2. 使具体的创建实例过程与客户端分
	 * 		   离,客户端时通过它们的抽象接口
	 * 		   操纵实例,产品的具体类名也被具
	 * 		   体工厂的实现分离,不会出现在客
	 * 		   户代码中。
	 * 缺点:
	 * 		1. 当增加新的产品时,就要增加抽象
	 * 		   产品角色、具体产品角色、具体工
	 * 		   厂角色三个角色(类),另外至少
	 * 		   还要修改抽象工厂角色。
	 * 		2. 在客户端很多的话,如果要进行产
	 * 		   品的切换,那么就会出现大批量的
	 * 		   改动。
	 * 使用场景:
	 * 		1. 一个系统要独立于它的产品的创建
	 * 		   、组合和表示时。
	 * 		2. 一个系统要由多个产品系列中的一
	 * 		   个来配置时(比如数据库)。
	 * 		3. 当你要强调一系列相关产品对象的
	 * 		   设计以便进行联合使用时。
	 * 		4. 当你提供一个产品类库,而只想显
	 * 		   示它们的接口而不是实现时。
	 * 		   
	 */

	/**
	 * 以两种数据库产品来举例
	 */

	//第一种抽象产品类
	abstract class User{
		abstract public function addUser();
		abstract public function queryUser();
	}

	//第二种抽象产品类
	abstract class Department{
		abstract public function addDeptmt();
		abstract public function queryDeptmt();
	}
	/**
	 * 第三种抽象产品类
	 * 		.
	 * 		.
	 * 		.
	 * 		.
	 * 	第N种抽象产品类
	 */

	//第一种抽象产品类的具体产品类
	//用户的添加和查询
	//MysqlUser是抽象产品User的第一个具体产品类
	class MysqlUser extends User{
		public function addUser(){
			echo ‘在Mysql数据库中添加一个用户‘;
		}
		public function queryUser(){
			echo ‘在Mysql数据库中查询某个用户信息‘;
		}
	}

	//MongodbUser是抽象产品User的第二个具体产品类
	class MongodbUser extends User{
		public function addUser(){
			echo ‘在MongoDB数据库中添加一个新用户‘;
		}
		public function queryUser(){
			echo ‘在MongoDB数据库中查询某个用户信息‘;
		}
	}  

	//第二种抽象产品类的具体产品类
	//部门的添加和查询
	//MysqlDeptmt是抽象产品Department的第一个具体产品类
	class MysqlDeptmt extends Department{
		public function addDeptmt(){
			echo ‘在Mysql数据库中添加一个新部门‘;
		}
		public function queryDeptmt(){
			echo ‘在Mysql数据库中查询某个部门信息‘;
		}
	}

	//MongodbDeptmt是抽象产品Department的第二个具体产品类
	class MongodbDeptmt extends Department{
		public function addDeptmt(){
			echo ‘在MongoDB数据库中添加一个新部门‘;
		}
		public function queryDeptmt(){
			echo ‘在MongoDB数据库中查询部门信息‘;
		}
	}

	//抽象工厂角色
	abstract class DBFactry{
		//因为是有两个抽象产品,多以与之对应的
		//应该有两个创建响应产品对象的方法。
		abstract static public function createUser();
		abstract static public function createDept();
	}

	/**
	 * 具体工厂角色
	 * 每个抽象产品角色对应的具体产品角色都有
	 * 一个与之对应的具体工厂角色,也就是说抽
	 * 象产品对应多少个具体的产品,就有多少个
	 * 具体产品工厂角色与之对应。因为抽象工厂
	 * 方法对应的是多个产品,所以可以在具体工
	 * 厂中返回多个具体产品的实例对象。
	 */
	//MysqlDBFactry是与具体产品MysqlUser和
	//MysqlDeptmt对应的具体工厂类。
	class MysqlDBFactry extends DBFactry{
		public static function createUser(){
			return new MysqlUser();
		}
		public static function createDept(){
			return new MysqlDeptmt();
		}
	}

	//MongoDBFactry是与具体产品MongodbUser和
	//MongoDeptmt对应的具体工厂类。
	class MongoDBFactry extends DBFactry{
		public static function createUser(){
			return new MongodbUser();
		}
		public static function createDept(){
			return new MongodbDeptmt();
		}
	}

	/**
	 * 使用简单工厂改进抽象工厂
	 * 改进后的优点:
	 * 		1. 当切换数据库时,客户端无需任何
	 * 		   修改。
	 * 	缺点: 
	 * 		如果再新增一种数据库,那么就要添加
	 * 		一个具体产品类,修改简单工厂中相关
	 * 		的switch语句。
	 * 		   
	 */
	class SimpleFactry{
		//$db:作为数据库切换变量
		private static $db=‘mysql‘;
		public static function createUser(){
			switch (self::$db) {
				case ‘mysql‘:
					$obj=new MysqlUser();
					break;
				case ‘mongodb‘:
					$obj=new MongodbUser;
					break;
			}
			return $obj;
		}

		public static function createDept(){
			switch(self::$db){
				case ‘mysql‘:
					$obj=new MysqlDeptmt();
					break;
				case ‘mongodb‘:
					$obj=new MongodbDeptmt();
					break;
			}
			return $obj;
		}
	}

	/**
	 * 利用反射技术进一步改进抽象工厂模式
	 */
	class ReflctSmplFactry{
		private static $db=‘Mysql‘;
		public static function createUser(){
			$className=self::$db.‘User‘;
			$reflct=new ReflectionClass($className);
			return $reflct->newInstance();
		}	

		public static function createDept(){
			$className=self::$db.‘Deptmt‘;
			$reflct=new ReflectionClass($className);
			return $reflct->newInstance();
		}
	}

//正常抽象工厂模式的客户端
	$factry=MysqlDBFactry::createDept();
	$factry->addDeptmt();
	$factry->queryDeptmt();
	$f2=MongoDBFactry::createUser();
	$f2->addUser();
	$f2->queryUser();

// 使用简单工厂改进后的抽象工厂模式的客户端
	$fcty=SimpleFactry::createUser();
	$fcty->addUser();
	$fcty->queryUser();
	$fcty2=SimpleFactry::createDept();
	$fcty2->addDeptmt();
	$fcty2->queryDeptmt();

// 使用反射技术改进后的抽象工厂模式的客户端
	$fctry=ReflctSmplFactry::createUser();
	$fctry->addUser();
	$fctry->queryUser();

	$fctry2=ReflctSmplFactry::createDept();
	$fctry2->addDeptmt();
	$fctry2->queryDeptmt();
?>
时间: 2024-10-06 14:18:53

设计模式之创建型模式—— 1.3 抽象工厂模式的相关文章

设计模式(一): abstract factory抽象工厂模式 -- 创建型模式

1.定义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.适用场景 1.一个系统要独立于它的产品创建.组合和表示. 2.一个系统要由多个产品系列中的一个来配置. 3.当你要强调一系列相关的产品对象的设计以便进行联合使用. 4.当你提供一个产品类库,而只想显示它们的接口而不是实现. 3.评价 1.它分离了具体的类 2.它使得易于交换产品系列 3.它有利于产品的一致性 4.难以支持新种类的产品 5."开放-封闭"原则要求系统对扩展开放,对修改封闭.通过扩展达到增

浅析设计模式(六)——创建型模式之Abstract-Factory(抽象工厂模式)

抽象工厂模式Abstract-Factory 本文的套路: 抽象工厂模式的定义 抽象工厂模式的参与者及其角色 抽象工厂模式的类图 抽象工厂模式的示例 参考 抽象工厂模式的定义 提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类. 前面[浅析设计模式(四)--创建型模式之Simple-Factory(简单工厂方法,非设计模式)]中介绍的简单工厂方法,虽然已经对变化的部分进行了封装,但是这里只由一个对象负责所有的具体类的实例化,因此每次有新增对象类型时,都需要改变工厂的源码进行扩展.

(创建型模式三)抽象工厂模式

package com.eyugame.modle; /** * 抽象工厂模式 * * @author JYC506 * */ public class MyFactory implements IAbstractFactory { @Override public IProduct1 createIProduct1() { return new Product1(); } @Override public IProduct2 createIProduct2() { return new Pro

设计模式那点事读书笔记(2)----抽象工厂模式

抽象工厂模式: 此模式提供了一个接口,用于创建相关或者依赖对象的家族,而不需要指定具体实现类. 解决什么问题: 抽象工厂模式允许客户在使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无须修改就可以获得新产品.从而实现客户从具体的产品中解耦. UML: 代码结构: 代码: 定义抽象产品: package com.demo.factory.model; /** * 抽象产品 */ public abstract class AbstractBa

工厂模式三部曲:抽象工厂模式

工厂模式三部曲:简单工厂模式 工厂模式三部曲:工厂方法模式 前言 这是工厂模式三部曲中的最后一篇了,在这篇文章中将会讲述抽象工厂模式,抽象工厂模式正如其名字一样,非常抽象.但是抽象工厂模式的功能却十分强大,对抽象工厂的利用也非常好. 这篇文章中会像本系列第一篇一样,给出普通实现方式和使用了反射机制的实现两种代码,并且会说明这两种实现方式的区别.并且在文章的最后,会将这三种模式放在一起,对这三种工厂模式进行总结. 本人理解可能不够深刻,这一系列文章中存在的问题,欢迎大家提出,谢谢! 什么是抽象工厂

《JAVA与模式》之抽象工厂模式

场景问题 举个生活中常见的例子--组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如CPU.硬盘.内存.主板.电源.机箱等.为讨论使用简单点,只考虑选择CPU和主板的问题. 事实上,在选择CPU的时候,面临一系列的问题,比如品牌.型号.针脚数目.主频等问题,只有把这些问题都确定下来,才能确定具体的CPU. 同样,在选择主板的时候,也有一系列问题,比如品牌.芯片组.集成芯片.总线频率等问题,也只有这些都确定了,才能确定具体的主板. 选择不同的CPU和主板,是每个客户在组装电脑的时候,向

工厂模式三部曲之抽象工厂模式

工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码.因为抽象工厂不太好理解,我们先看看图,然后就和代码,就比较容易理解. 举例如下:(我们举一个发送邮件和短信的例子) public interface Sender { public void Send(); } 两个实现类:

设计者模式详解--抽象工厂模式

1. 概述 抽象工厂模式为一个产品家族提供了统一的创建接口.当需要这个产品家族的某一系列的时候,可以从抽象工厂中选出相对应的系列来创建一个具体的工厂类别. 2. 抽象工厂模式中的角色 2.1 抽象工厂(AbstractFactory):担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的. 2.2 具体工厂(ConcreteFactory):这个角色直接在客户端的调用下创建产品的实例.这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的. 2.3 抽象产品

抽象模式之【抽象工厂模式】

原则:依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体: 一.创建接口:发送消息 package Factory; public interface Sender{ public void Send(); } 二.创建两个实现类 1.发送邮箱 package Factory; public class MailSend implements Sender{ @Override public void Send() { System.out.println("mailsend");