class Preferences { private static $instance; private function __construct(){ ... } public static function get_instance(){ if(empty(self::$instance)){ self::$instance = new Preferences(); } return self::$instance; } ... } //使用 $preferences = Preferences::get_instance();
3.2 工厂模式
通过一个父类,生产处多个不同功能的子类.
特点:产品方(新浪微博)和需求方(显示新浪微博)一一对应.
问题:印象笔记中,来源可能为新浪微博,或者开发者头条,在印象笔记显示的时候,两者的页眉和页尾是不一样的.
3.3 抽象模式
RLGL!!!.印象笔记不只要显示新浪微博内容!!!还要显示我的新浪账号,还要该微博啊!!卧槽~憋着急,吻我.
工厂模式主要用于生产一一对应的产品方和需求方,而抽象模式要做的是一个需求方(印象笔记_显示新浪微博),要多个工厂(把需求方抽象为多个需求方),例如提供新浪内容的工厂,提供新浪账号的工厂.提供微博内容的评论的工厂等.
代码:
abstract class Show_Evernote { abstract function get_header_text(); abstract function get_context(); abstract function get_footer_text(); abstract function get_user(); abstract function get_comment(); } class 显示新浪微博 extends Show_Evernote{ function get_header_text(){...}; function get_context(){new 新浪微博_内容;} function get_footer_text(){...}; function get_user(){new 新浪微博_账号 ;} function get_comment(){new 新浪微博_评论;} } //使用 印象笔记控件类->内容 = 显示新浪微博->get_context; 印象笔记控件类->账号 = 显示新浪微博->get_context; ...
3.4 平行模式
当使用工厂/抽象模式必须要制定具体的创建者(需求方).
平行模式和抽象模式的模型图一致,但代码实现不一样.
抽象模式中父类均为抽象类,而平行模式中,所以类都为普通类,方便父类的实例化.
在这里列出显示印象笔记类的实现代码
class Show_Evernote{ private $内容; private $账号; private $评论; function __construct(内容,账号,评论){ $this->内容 = 内容; $this->账号 = 账号; $this->评论 = 评论; } function get_内容(){ return clone $this->内容); } function get_账号(){ return clone $this->账号); } function get_评论(){ return clone $this->评论; } } //使用 $factory = new Show_Evernote( new 新浪微博内容(), new 新浪微博账号(), new 新浪微博评论() ); 印象笔记控件类->显示印象笔记 = $factory;
其实大家可以发现,原型模式只不过只在最顶层类中包装了一下各组件子类而已,然而这样可以轻松的组合他们,例如实现一个显示新浪微博内容,但要显示开发者头条账号的需求?
4 使用对象
4.1 组合模式
组合模式,可以理解为单一对象管理组合对象(聚合组件),最终组合体下的各个组合部件最好类型一致.不然特殊性越多,需要判断就越多.
假设捶背男,洗脚男,洗发男,用来服务一个人(妹子).
假设妹子的几个部位可用的服务男均为无限个.
//创建一个妹子 $妹子 = new 人(); //添加洗脚男、捶背男 $妹子->add_man(new 洗脚男); $妹子->add_man(new 捶背男); //循环所有男的给予舒服的方法. $妹子->计算舒服程度();
这是一个很理想的组合模式,在现实情况,我们使用组合模式,可能不得不创建多种类型的洗脚男,需要添加许多判断条件.
4.2 装饰模式
装饰模式,首先洗脚男,洗发男,捶背男都是人,但是如果,一个男的又捶背,又洗发,这怎么玩?.add_man两次?这不科学吧,来给这些男的装饰一下吧~