PHP China | 中国开源之路 's Archiver

PHPChina 发表于 2006-3-4 19:32

->Factory Pattern 工厂模式

->工厂模式(Factory Pattern)
多型性(Polymorphism)和基础类的使用确实是面向对象编程(OOP)的核心。然而在一些情况下,我们需要用到基础类的继承类生成具体的实例。这个时候,我们可以使用工厂模式(Factory Pattern)了。一个工厂模式通过一个静态的方式函数获取数据,并且根据获取数据的类型不同生成不同的继承类的实例。
   假设在我们的Web站点里面,存在着许多不同类型的用户。一些是游客,一些是会员,还有一些是管理员。所以我们需要在用户登陆的时候通过User和它的继承对象对用户的权限进行分配。
   最好的方法就是频繁地去使用基础类这样代码就会比较精巧,并且很容易去增加新的用户类型。
   下面这个例子就是使用User和UserFactory两个类来执行并根据具体的用户名去产生正确的用户对象。
   代码:factory_pattern.php

PHPChina 发表于 2006-3-4 19:33

[php]
<?php
abstract class User{
        function __construct($name)
        {
                $this->name = $name;
        }
       
        function getName()
        {
                return $this->name;
        }
       
        //Permission methods
       
        function hasReadPermission()
        {
                return true;
        }
       
        function hasModifyPermission()
        {
                return false;
        }
       
        function hasDeletePermission()
        {
                return false;
        }
       
        //Customization methods
       
        function wantsFlashInterface()
        {
                return true;
        }
       
        protected $name = null;
}

class GuestUser extends User {
       
}

class CustomerUser extends User {
        function hasModifyPermission()
        {
                return true;
        }
}

class AdminUser extends User {
        function hasModifyPermission()
        {
                return true;
        }
        function hasDeletePermission()
        {
                return true;
        }
        function wantsFlashInterface()
        {
                return false;
        }
}

class UserFactory {
        private static $users = array("Andi"=>"admin","Stig"=>"guest",
                               "Derick"=>"customer");
        static function Create($name)
        {
                if (!isset(self::$users[$name])) {
                        // Error out because the user doesn't exist
                }
                switch (self::$users[$name]) {
                        case "guest":return new GuestUser();
                        case "customer":return new CustomerUser();
                        case "admin":return new AdminUser();
               
                        default://Error out because the user kind doesn't exist
                }
        }
}
function boolToStr($b)
{
        if ($b == true) {
                return "Yes\n";
        } else {
                return "No\n";
        }
}

function displayPermissions(User $obj)
{
        print $obj->getName() ."'s Permissions:\n";
        print "Read:" . boolToStr($obj->hasReadPermission());
        print "Modify:" . boolToStr($obj->hasModifyPermission());
        print "Delete:" . boolToStr($obj->hasDeletePermission());
}

function displayRequirements(User $obj)
{
        if ($obj->wantsFlashInterface()) {
                print $obj->getName() . "requires Flash\n";
        }
}

$logins = array("Andi","Stig","Derick");

foreach ($logins as $login) {
        displayPermissions(UserFactory::Create($login));
        displayRequirements(UserFactory::Create($login));
}
?>
[/php]

PHPChina 发表于 2006-3-4 19:33

这个代码片段是工厂模式的一个经典例子。除了Create()外,你可以经常看到factory(),factoryMethod()或者CreateInstance()等函数来构造工厂模式。

weiwei 发表于 2006-3-5 16:43

与C++的类模版有什么区别与联系吗?

leslee 发表于 2006-3-5 20:18

与Java的几乎一样..

与C++的就不是很清楚了

不玩那个了.

weiwei 发表于 2006-3-6 08:46

真是曲高和寡!

weiwei 发表于 2006-3-6 18:04

今天仔细看了代码,觉得这有点不明白

switch (self::$users[$name]) {
                        case "guest":return new GuestUser();
                        case "customer":return new CustomerUser();
                        case "admin":return new AdminUser();
               
                        default://Error out because the user kind doesn't exist
                       }
这样如是是 guest ,一样会产生 customer 与 admin对象啊!

Phzzy 发表于 2006-3-6 23:28

都return了,函数自动会跳出

leslee 发表于 2006-3-7 11:02

return 了就不需要画蛇添足 再去break了.所以只会产生对应的一个对象

teamo 发表于 2006-3-15 12:48

copy下来,仔细学习

另问,是否php5中只能静态访问类的方法?不能访问属性?

sorrowboy 发表于 2007-11-9 17:46

这里:应该把$name传入
                        case "guest":return new GuestUser($name);
                        case "customer":return new CustomerUser($name);
                        case "admin":return new AdminUser($name);

sorrowboy 发表于 2007-11-9 17:49

[quote]原帖由 [i]teamo[/i] 于 2006-3-15 12:48 发表 [url=http://www.phpchina.com/bbs/redirect.php?goto=findpost&pid=19792&ptid=2842][img]http://www.phpchina.com/bbs/images/common/back.gif[/img][/url]
copy下来,仔细学习

另问,是否php5中只能静态访问类的方法?不能访问属性? [/quote]

将类中
class UserFactory {
    [color=Red]private[/color] static $users = array("Andi"=>"admin","Stig"=>"guest",
    "Derick"=>"customer");

的[color=Red]private[/color] 去掉

class UserFactory {
    static $users = array("Andi"=>"admin","Stig"=>"guest",
    "Derick"=>"customer");

然后再

print_r(UserFactory::$users);

你看一下页面吧
能访问的

luzhou 发表于 2008-2-6 09:03

tukiz01 tukiz01

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.