设为首页收藏本站

就爱编程论坛

 找回密码
 注册

人人连接登陆

无需注册,直接登录

用新浪微博连接

一步搞定

QQ登录

只需一步,快速开始

查看: 414|回复: 0
打印 上一主题 下一主题

php面向对象编程 – 使用接口实现松散耦合 [复制链接]

Rank: 9Rank: 9Rank: 9

  • TA的每日心情
    无聊
    2025-5-27 03:37:20
  • 签到天数: 366 天

    [LV.9]以坛为家II

    论坛先锋 学习至圣 荣誉成员 论坛元老 活跃之星 终极领袖

    我玩的应用:

    跳转到指定楼层
    楼主
    发表于 2012-4-2 21:56:04 |只看该作者 |倒序浏览
    先来看一个紧密耦合的例子:
    <?phprequire_once "./AddressFormatters.php";class Address{    private $addressLine1;    private $addressLine2;    private $city;    private $state; // or province...    private $postalCode;    private $country;    public function setAddressLine1($line1)    {        $this->addressLine1 = $line1;    }                /* accessors, etc... */    public function getCountry()    {        return $this->country;    }    public function format($type)    {        if ($type == "inline") {            $formatter = new InlineAddressFormatter();        } else if ($type == "multiline") {            $formatter = new MultilineAddressFormatter();        } else {            $formatter = new NullAddressFormatter();        }        return $formatter->format($this->getAddressLine1(),            $this->getAddressLine2(),            $this->getCity(), $this->getState(), $this->getPostalCode(),            $this->getCountry());    }}$addr = new Address();$addr->setAddressLine1("123 Any St.");$addr->setAddressLine2("Ste 200");$addr->setCity("Anytown");$addr->setState("AY");$addr->setPostalCode("55555-0000");$addr->setCountry("US");echo($addr->format("multiline"));echo("\n");echo($addr->format("inline"));echo("\n");?>在 Address 对象上调用 format() 方法的代码可能看上去很棒 — 这段代码所做的是使用 Address 类,调用 format() 并完成。相反,Address 类就没那么幸运。它需要了解用于正确格式化的各种格式化方法,这可能使 Address 对象无法被其他人很好地重用,尤其是在其他人没有兴趣在 format() 方法中使用格式化方法类的情况下。虽然使用 Address 的代码没有许多依赖关系,但是 Address 类却有大量代码,而它可能只是一个简单的数据对象。
    在构建优秀的 OO 设计时,必须考虑称为关注点分离(Separation of Concerns,SoC)的概念。SoC 指尝试通过真正关注的内容分离对象,从而降低耦合度。在最初的 Address 类中,它必须关注如何进行格式化。这可能不是优秀的设计。然而,Address 类应当考虑 Address 的各部分,而某种格式化方法应当关注如何正确格式化地址。
    看一下如何通过使用接口来实现松散耦合:
    <?phpinterface AddressFormatter{    public function format($addressLine1, $addressLine2, $city, $state,        $postalCode, $country);}class MultiLineAddressFormatter implements AddressFormatter{    public function format($addressLine1, $addressLine2, $city, $state,        $postalCode, $country)    {        return sprintf("%s\n%s\n%s, %s %s\n%s",            $addressLine1, $addressLine2, $city, $state, $postalCode, $country);    }}class InlineAddressFormatter implements AddressFormatter{    public function format($addressLine1, $addressLine2, $city, $state,        $postalCode, $country)    {        return sprintf("%s %s, %s, %s %s %s",            $addressLine1, $addressLine2, $city, $state, $postalCode, $country);    }}class AddressFormatUtils{    public static function formatAddress($type, $address)    {        $formatter = AddressFormatUtils::createAddressFormatter($type);        return $formatter->format($address->getAddressLine1(),            $address->getAddressLine2(),            $address->getCity(), $address->getState(),            $address->getPostalCode(),            $address->getCountry());    }    private static function createAddressFormatter($type)    {        if ($type == "inline") {            $formatter = new InlineAddressFormatter();        } else if ($type == "multiline") {            $formatter = new MultilineAddressFormatter();        } else {            $formatter = new NullAddressFormatter();        }        return $formatter;    }}$addr = new Address();$addr->setAddressLine1("123 Any St.");$addr->setAddressLine2("Ste 200");$addr->setCity("Anytown");$addr->setState("AY");$addr->setPostalCode("55555-0000");$addr->setCountry("US");echo(AddressFormatUtils::formatAddress("multiline", $addr));echo("\n");echo(AddressFormatUtils::formatAddress("inline", $addr));echo("\n");?>在上面的代码中,省略了address的部分代码。关键部分展示了:格式化地址的代码被移到接口、实现类和工厂中 — 养成 “使用接口” 的习惯。现在,AddressFormatUtils 类负责创建格式化方法并格式化 Address。任何其他对象现在都可以使用 Address 而不必担心要求获得格式化方法的定义。
    当然,缺点是只要使用模式,通常就意味着工件(类、文件)的数量会增加。但是,通过减少每个类中的维护可以弥补这个缺点,甚至在获得正确的可重用性时反而可以减少工件量。


    该贴已经同步到 admin的微博
    分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    分享分享0 收藏收藏0 支持支持0 反对反对0 分享到人人 转发到微博
    [img=http://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=fRUcHhYWGAQ9GxIFEBwUEVMeEhA]http://rescdn.qqmail.com/zh_CN/htmledition/images/function/qm_open/ico_mailme_02.png[/img]

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册 人人连接登陆

    晴云孤魂's Blog|就爱编程搜帖|手机版|Archiver|就爱编程论坛     

    GMT+8, 2025-7-2 09:01 , Processed in 0.097492 second(s), 27 queries .

    Powered by Discuz! X2

    © 2001-2011 Comsenz Inc.

    回顶部