<?php
/**抽象产品角色
* interface IPRODUCT 产品的接口
*/
interface IProduct{
/**
* x轴旋转
*/
function XRotate();
/**
* y轴旋转
*/
function YRotate();
}
/**具体产品角色
* XProduct x轴旋转产品
* 实现接口必须实现其所有方法
*/
class XProduct implements IProduct{
private $xMax=1;
private $yMax=1;
function __construct($xMax,$yMax){
$this->xMax=$xMax;
$this->yMax=1;
}
function XRotate(){
echo "我是X轴产品,我在转转转。。。。。";
}
function YRotate(){
echo "抱歉我是X轴产品,没有y轴";
}
}
/**具体产品角色
* YProduct y轴旋转产品
*/
class YProduct implements IProduct{
private $xMax=1;
private $yMax=1;
function __construct($xMax,$yMax){
$this->xMax=1;
$this->yMax=$yMax;
}
function XRotate(){
echo "抱歉我是y轴产品,没有x轴";
}
function YRotate(){
echo "我是y轴产品,我在转转转。。。。。";
}
}
/**具体产品角色
* XYProduct xy轴都可旋转产品
*/
class XYProduct implements IProduct{
private $xMax=1;
private $yMax=1;
function __construct($xMax,$yMax){
$this->xMax=$xMax;
$this->yMax=$yMax;
}
function XRotate(){
echo "我是x轴产品,我在转转转。。。。。";
}
function YRotate(){
echo "我是y轴产品,我在转转转。。。。。";
}
}
/**工厂角色
* class ProductFactory
* 根据传入的参数不同,返回不同得对象
*/
class ProductFactory{
static function GetInstance($xMax,$yMax){
if($xMax>1&&$yMax===1){
return new XProduct($xMax,$yMax);
}else if($xMax===1&&$yMax>1){
return new YProduct($xMax,$yMax);
}else if($xMax>1&&$yMax>1){
return new XYProduct($xMax,$yMax);
}else{
return null;
}
}
}
创建测试文件testsimple.php
<?php
require_once './simplefactory.php';
header("Content-Type:text/html;charset=utf-8");
$pro=array();
/**
* 生成三个对象放到数组里
*/
$pro[]=ProductFactory::GetInstance(12,1);
$pro[]=ProductFactory::GetInstance(1,12);
$pro[]=ProductFactory::GetInstance(12,12);
$pro[]=ProductFactory::GetInstance(0,12);
foreach($pro as $v){
if($v){
echo "<br/>";
$v->XRotate();
echo "<br/>";
$v->YRotate();
}else{
echo "非法产品!<br/>";
}
echo "<br/>";
}
?>
用浏览器访问测试代码,我们可以发现创建的对象依次是YProduct,XProduct,XYProduct,null。简单工厂的核心代码在于工厂(ProductFactory)这个角色,这里根据传入的xMax与yMax值去创建不同的对象,这便是简单工厂的实质,而且我们在测试调用客户端根本不知道具体的产品类是什么样,这样就做到了调用与创建的分离。
简单工厂的优点:让对象的调用者和对象创建过程分离,当对象调用者需要对象时,直接向工厂请求即可。从而避免了对象的调用者与对象的实现类以硬编码方式耦合,以提高系统的可维护性、可扩展性。
简单工厂的缺点:当产品修改时,工厂类也要做相应的修改,比如要增加一种操作类,如求M数的N次方,就得改case,修改原有类,违背了开放-封闭原则。
?>