PHP设计模式之:原型模式学习笔记
原型模式其实和工厂模式比较类似,都是用来创建对象的,只不过与工厂模式的实现不同。原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象。这样就免去了类创建时重复的初始化操作了。原型模式适用于大对象的创建,因为在创建一个大对象时,需要很大的开销。如果每次都去new就会消耗很大,原型模式仅需从内存拷贝既可。
还是继续通过实例来向大家演示一下
<?php /** * 抽象原型角色 */ interface Prototype { public function clone_obj(); } /** * 具体原型角色 */ class Concrete implements Prototype{ private $data; public function __construct($data) { $this->data = $data; } public function get_data() { return $this->data; } public function clone_obj() { /* * 深拷贝实现 */ /*$serialize_obj = serialize($this); // 序列化 $clone_obj = unserialize($serialize_obj); // 反序列化 return $clone_obj;*/ return clone $this; // 浅拷贝 } } /** * 测试深拷贝用的引用类 */ class Demo { public $arr; } $demo = new Demo(); $demo->arr = array(1, 2); $concrete = new Concrete($demo); $object1 = $concrete->clone_obj(); var_dump($concrete->get_data()); echo '<br />'; var_dump($object1->get_data()); echo '<br />'; //测试深拷贝 $demo->arr = array(3, 4); var_dump($concrete->get_data()); echo '<br />'; var_dump($object1->get_data()); echo '<br />'; ?>
更多的详细说明和实例
设计模式中的观察者模式我相信很多php开发者都不是很了解了,下面一聚教程小编来为各位整理了一篇相关的文章供各位参考。
一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力。当对象们连接在一起时,它们就可以相互提供服务和信息。这个模式对于大型系统项目来说应该是挺挺有用的,通俗的讲,这种模式允许某个类去观察另一个类。当一个类被改变时,观察类就会收到通知并且做出相应的动作。
在平时的项目中还是挺有用的,比如一个用户下了一笔订单,下单成功后,就需要去发送短信/邮件的通知,库存的修改,账户余额的修改等等很多操作。
在之后的PHP5.0起,内置的SPL标准库中就提供了这种设计模式接口供大家使用,接下了就通过实例来学习一下。
SPL 提供了 SplSubject 和 SplObserver 接口。
SplSubject 接口提供了attach()、detach()、notify() 三个方法。而 SplObserver 接口则提供了 update()方法。
<?php /** * 这一模式的概念是SplSubject类维护了一个特定状态,当这个状态发生变化时,它就会调用notify()方法。 * 调用notify()方法时,所有之前使用attach()方法注册的SplObserver实例的update方法都会被调用。 * */ interface SplSubject{ public function attach(SplObserver $observer);//注册观察者 public function detach(SplObserver $observer);//释放观察者 public function notify();//通知所有注册的观察者 } interface SplObserver{ public function update(SplSubject $subject);//观察者进行更新状态 } ?>
使用所提供的接口,来实现观察者模式
<?php /** *具体目标 */ class Salary implements SplSubject { private $observers, $money; public function __construct() { $this->observers = array(); } public function attach(SplObserver $observer) { //注册观察者 $this->observers[] = $observer; } public function detach(SplObserver $observer) { //释放观察者 if($idx = array_search($observer,$this->observers,true)) { unset($this->observers[$idx]); } } public function notify() { //通知所有观察者 foreach($this->observers as $observer) { $observer->update($this); } } public function payoff($money) { //发工资方法 $this->money = $money; $this->notify(); //通知观察者 } } /** * 具体观察者 */ class Programmer1 implements SplObserver { public function update(SplSubject $subject) { echo 'Programmer1 发工资了!<br/>'; } } class Programmer2 implements SplObserver { public function update(SplSubject $subject) { echo 'Programmer2 也发工资了!<br/>'; } } $subject = new Salary(); $observer1 = new Programmer1(); $observer2 = new Programmer2(); //注册观察者 $subject->attach($observer1); $subject->attach($observer2); //发工资操作,发起通知 $subject->payoff('20K'); ?>
通过Observer模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放-封闭原则。东西是不错,如何能够更好的去使用它,仍需要多加实践、联系。
php面向对象的设计模式中有很多种模式了,今天我们为各位介绍的是装饰器模式的一个学习笔记了,有需要了解php装饰器模式的朋友可以和小编来看看。
我们在使用面向对象的日常开发过程中,或许会碰见需要对某个方法或者某个对象,添加新的行为。然而常见的做法是,写一个子类继承需要改写的类,然后去重新实现类的方法。
但是装饰器模式(Decorator),可以动态地添加修改类的功能,在使用装饰器模式,仅需在运行时添加一个装饰器对象既可实现,相对与生成子类更加的灵活。
在我们需要改写一个类的时候通常的做法是采用继承的方式来重新方法,如下代码
/* * 比如我们需要改写一串字符串的样式,采用继承的写法。 */ class Canvas { function draw($width = 20, $height = 10) { for($i = 0; $i < $height; $i++) { for($j = 0; $j < $width; $j++) { echo '*'; } echo '<br/>'; } } } class Canvas2 extends Canvas { function draw($width = 20, $height = 10) { echo "<div style='color: red;'>"; parent::draw($width, $height); echo "</div>"; } } $Canvas2 = new Canvas2(); $Canvas2->draw();
对于上面的这种写法,假如我们需要多增加一个一种样式就需要多一个继承。接下来使用装饰器模式(Decorator)就会方便很多。
/* * 首先声明一个装饰器的接口 */ interface DrawDecorator { function beforeDraw(); function afterDraw(); }
接下来再分别添加两个装饰类,来继承接口,实现接口中的方法
/* * 颜色装饰 */ class ColorDrawDecorator implements DrawDecorator { protected $color; function __construct($color = 'red') { $this->color = $color; } function beforeDraw() { echo "<div style='color: {$this->color};'>"; } function afterDraw() { echo "</div>"; } } /* * 字体大小装饰 */ class SizeDrawDecorator implements DrawDecorator { protected $size; function __construct($size = '14px') { $this->size = $size; } function beforeDraw() { echo "<div style='font-size: {$this->size};'>"; } function afterDraw() { echo "</div>"; } }
接下来就是使用我们前面所创建的装饰类
/* * 创建一个画布类 */ class Canvas { protected $decorators = array(); //用来存放装饰的数组 function draw($width = 20, $height = 10) { $this->beforeDraw(); for($i = 0; $i < $height; $i++) { for($j = 0; $j < $width; $j++) { echo '*'; } echo '<br/>'; } $this->afterDraw(); } //添加装饰器的方法 function addDecorator(DrawDecorator $decorator) { $this->decorators[] = $decorator; } function beforeDraw() { foreach($this->decorators as $decorator) { $decorator->beforeDraw(); } } function afterDraw() { $decorators = array_reverse($this->decorators); foreach($decorators as $decorator) { $decorator->afterDraw(); } } } $Canvas = new Canvas(); $Canvas->addDecorator(new ColorDrawDecorator('red')); $Canvas->addDecorator(new SizeDrawDecorator('9px')); $Canvas->draw(20, 10);Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,下面我们就一起来看一篇简单的solr从数据库导入数据的例子
1. 先在本地的solr_db库下建一张solr_tb表(字段:id,name,price,desc),添加了5条数据,如下图。
建立数据表
2. 还记得上篇中安装solr的目录结构吗?打开D:\phpServer\solr\solr1\home\collection1\conf目录,暂且称这个目录为“配置文件目录”了。打开配置文件目录下的solrconfig.xml文件,在此文件的<config></config>标签之间的任一地方(最好是前面)添加如下代码:
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
配置dataimport
3. 在当前目录下新建一个名为data-config.xml的文件,在文件中添加如下配置信息,此信息为你要连接的mysql库的信息,请如实填写(数据库为solr_db,数据表为solr_tb)。
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1/solr_db"
user="root"
password="root" />
<document>
<entity name="solr_tb" transformer="DateFormatTransformer"
query="select id,name FROM solr_tb where id >= ${dataimporter.request.id}">
</entity>
</document>
</dataConfig>
4. 找到同级目录下面的schema.xml(字段配置)文件,先将此文件备份一下,然后打开schema.xml,全选->删除,再将下面这段粘贴到schema.xml文件中。因为我们暂时用不到那么多参数,所以为了便于初学和理解,简化了一下。
<?xml version="1.0" encoding="UTF-8" ?>
<schema name="example" version="1.5">
<!-- 要建立的索引,_version_这个不能省略 -->
<fields>
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="name" type="text_general" indexed="true" stored="true" />
<field name="_version_" type="long" indexed="true" stored="true"/>
</fields>
<!-- 字段类型,配置上面字段<field>中出现的类型即可 -->
<types>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" />
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
<!-- text_general能对中文分词 -->
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
</types>
<!-- 唯一字段 -->
<uniqueKey>id</uniqueKey>
<!-- 设置默认查询字段,设置此处为name后,还要在solrconfig.xml中设置name="/select"中为<str name="df">name</str>。-->
<defaultSearchField>name</defaultSearchField>
<!-- 查询转换模式,是并且还是或者(and/or) -->
<solrQueryParser defaultOperator="OR"/>
</schema>
说明一下:“<fields>”标签,就是配置你要建立索引的字段。我现在需要建立id,name两个字段,
即 <field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/> 和 <field name="name" type="text_general" indexed="true" stored="true" /> 也就是对应第3步中select id,name FROM solr_tb这里的字段。了解一下fields标签。
5.在D:\phpServer\solr\dist目录中复制solr-dataimporthandler-4.7.0.jar、solr-dataimporthandler-extras-4.7.0.jar和mysql-connector-java-5.1.7-bin.jar(这个没有?点击下载)复制到D:\phpServer\solr\solr1\tomcat\webapps\solr\WEB-INF\lib目录中。
6.重启tomcat服务,访问http://localhost:8080/solr/,在左侧的菜单中的下拉选择collection1,然后再载入的菜单中选择Dataimport选项,是不是已经出现了如下图所示的界面呢。如果出现则表示成功了。接着按如下图的指示,现在开始导入数据吧!
Clean选项表示是否删除未匹配到的数据,也就是在数据库select结果中没有,而solr索引库中存在的时候,则删除。
1.定义
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
2.解决的问题/使用场景
在数据库应用方面,使用单例模式,可以避免大量的new操作消耗的资源。
如果在系统中需要一个类来全局控制某些配置信息,那么使用单例模式可以很方便的实现。
3.实现单例模式的要点
需要一个保存类的唯一实例的静态成员变量。
构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义。
需要提供一个访问这个实例的静态方法(一般为getInstance方法),返回实例的引用。
4.实现代码示例
<?php class Singleton { private static $instance; private $conn; private function __construct() { $this->conn = mysql_connect(...); } private function __clone() { } public static function GetInstance() { if (!(self::$instance instanceof self)) { slef::$instance = new self(); } return self::$instance; } public function GetDbConnect() { return $this->conn; } public function selectData($sql) { // $result mysql_query($sql,$this->conn); // while mysql_fetch_array($result).... } } $db = Singleton::GetInstance(); $db->selectData("select * from user");
相关文章
- 这篇文章主要为大家介绍了JavaScript设计模式中的装饰者模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
- 神马是“解释器模式”?先翻开《GOF》看看Definition:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。在开篇之前还是要科普几个概念: 抽象语法树: 解释器模式并未解释如...2014-06-07
- 这篇文章主要介绍了JavaScript设计模式之职责链模式,对设计模式感兴趣的同学,可以参考下...2021-04-25
- 我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
- 1、简介Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目...2014-05-31
- 这篇文章主要介绍了JavaScript设计模式之命令模式,对设计模式感兴趣的同学,可以参考下...2021-04-25
- 这篇文章主要为大家介绍了JavaScript设计模式中的状态模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-12
- 当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了...2016-11-25
- 这篇文章主要为大家介绍了JavaScript设计模式中的单例模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
- 这篇文章主要为大家介绍了JavaScript设计模式中的状态模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-14
- 举一个简单的date例子 我将使用echo命令把内容输出到我们的客户端(浏览器)。我将使用下面的代码做为基础代码。 代码如下 复制代码 <!DOCTY...2016-11-25
- 这篇文章主要为大家介绍了JavaScript设计模式中的观察者模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
- 这篇文章主要为大家介绍了JavaScript设计模式中的责任链模式,对JavaScript设计模式感兴趣的小伙伴们可以参考一下...2016-01-21
- 一篇Android学习笔记之多界面切换实例,希望对各位朋友有所帮助。 用过VB 、 VC#的朋友都知道,在VB或VC#里要进行窗口(界面)切换很容易 例如在VB、C#里: 有 Fom1、...2016-09-20
- 这篇文章主要给大家介绍的是JavaScript中的单例模式,设计模式代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案,需要的朋友可以参考一下...2021-09-25
- 引用:意思是将原始对象在内存中的地址传递给目标对象,就相当于原始对象和目标对象指向的是同一个内存地址。此时,如果对目标对象或者原始对象进行修改,内存中的数据也会改...2016-11-25
- cURL是php中一个很强大的功能,可以模仿各种用户请求,如模仿用户登录,发送php cookie等等操作,下面我来整理一些相关的方法与各位同学看看 备注:使用curl_init函数,必须...2016-11-25
- 组合模式可以使客户端调用简单,它可以一致使用组合结构或是其中单个对象,简化了客户端代码。...2020-06-25
- 那些年学了ASP.NET后,才开始学习C#,说来也怪,怎么学了ASP.NET才来学习C#,其实没有什么的...2020-06-25
- CWidget是所有Widget的基类。CWidget是自包含组件,可以看出是MVC的简略版,CWidget相比Controller,既没有actions,也没有filters widget,英文意思为小工具,小挂件,在程序...2016-11-25