<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>潘锦的空间 &#187; 面向对象</title>
	<atom:link href="https://www.phppan.com/tag/%e9%9d%a2%e5%90%91%e5%af%b9%e8%b1%a1/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sat, 04 Apr 2026 01:19:58 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>PHP面向对象的历史</title>
		<link>https://www.phppan.com/2013/10/php-oop-history/</link>
		<comments>https://www.phppan.com/2013/10/php-oop-history/#comments</comments>
		<pubDate>Sun, 06 Oct 2013 02:27:09 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1861</guid>
		<description><![CDATA[PHP面向对象的历史 PHP最开始的perl脚本，到C语言版的PHP/FI，再到PHP/FI 2.0、PHP3 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h1>PHP面向对象的历史</h1>
<p>PHP最开始的perl脚本，到C语言版的PHP/FI，再到PHP/FI 2.0、PHP3.0，直到PHP4，引入Zend Engine使PHP更加的强大，并在PHP5引入新的Zend Engine2，重写PHP的面向对象模型，使PHP不仅可以快速开发，同时也可以实现更加复杂的架构，甚至满足企业应用。</p>
<p>PHP最开始并没有面向对象，直到PHP4才有一些面向对象的影子，到PHP5才真正实现面向对象模型。大概来说，PHP面向对象历史包括两个阶段：</p>
<h2 >PHP4-Zend Engine阶段  </h2>
<p>此时并没有真正的面向对象，因为PHP根本没有实现面向对象的三大特性，所有的成员方法和成员函数都是公有的，成员变量通过var声明。</p>
<p>此时的构造函数和类名一样，序列和反序列化时能调用魔术函数_sleep 和 __wakeup。嗯，这是是叫魔术函数而不是魔术方法，因为它本来就是独立出来的函数，当执行序列化时，PHP会判断当前变量是什么类型，如果是IS_OBJECT，则会自动调用__sleep函数。
</p>
<p>在4.0.2以后可以使用parent::调用父类的方法。这里的parent仅仅是函数调用时的一个特殊处理。</p>
<p>在PHP的内核实现中类和函数共用一个opcode（ZEND_DECLARE_FUNCTION_OR_CLASS），通过extended_value字段区分，类和函数的存储已经区分开。</p>
<p>总的来说，PHP4的面向对象有点脚手架的味道，各种定制后有了一些面向对象的形。</p>
<h2>PHP5-Zend Engine2阶段</h2>
<p>5.0.0引入Zend Engine2，至此PHP才真正引入了面向对象的机制。<br />
Zend Engine2重写了PHP的面向对象模型，其中包括对构建器和析构器的定义，增加的私有成员变量、静态成员变量、接口、重载等面向对象特性以及新增加了魔术方法实现。除了面向对象特性外，Zend Engine2引入了异常处理控制流。具体见： <a href="http://www.zend.com/engine2/ZendEngine-2.0.pdf" target="_blank">http://www.zend.com/engine2/ZendEngine-2.0.pdf</a></p>
<p>5.1.0 新增：__isset 和 __unset 方法。</p>
<p>5.3.0  新增： __invoke 方法、 后期静态绑定、 heredoc 和 nowdoc 支持类的常量和属性的定义、__callStatic 方法等</p>
<p>5.4.0 增加Traits，Trait 和类相似，但它的目的是用细粒度和一致的方式来组合功能。Trait 不能实例化。它为传统继承增加了水平特性的组合；也就是说，应用类的成员不需要继承。</p>
<p>总的来说，PHP5已经实现了面向对象模型，可以基于PHP5实现企业级应用。但是一些新的功能和特性，在实际的开发过程中使用得并不多，如Traits、命名空间等。很多时候，业务决定技术，需求决定实现。</p>
<p>然，此篇仅为整理之作，只为理自己对于PHP面向对象的思路。<br />
久不沾笔，些许生疏。</p>
<h2>参考资料</h2>
<ul>
<li>http://php.net/manual/zh/history.php.php</li>
<li>http://www.php.net/ChangeLog-4.php
</li>
<li>http://www.php.net/ChangeLog-5.php</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2013/10/php-oop-history/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>思考PHP之五：访问控制</title>
		<link>https://www.phppan.com/2011/05/thinkinphp-5-visibility/</link>
		<comments>https://www.phppan.com/2011/05/thinkinphp-5-visibility/#comments</comments>
		<pubDate>Mon, 23 May 2011 01:11:20 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[PHP语言]]></category>
		<category><![CDATA[思考PHP语言]]></category>
		<category><![CDATA[访问控制]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1377</guid>
		<description><![CDATA[面向对象三大特性：封装性、继承性和多态性。 封装隐藏了对象内部的细节和实现， 使对象能够集中而完整的描述并对应 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-indent: 2em;">面向对象三大特性：封装性、继承性和多态性。 封装隐藏了对象内部的细节和实现， 使对象能够集中而完整的描述并对应一个具体的事物。 它使对象只提供对外的访问接口，这样可以在不改变接口的前提下改变实现细节，而且能使对象自我完备。 除此之外，封装还可以增强安全性和简化编程。 继承的目的是为了实现代码复用，它是一种一般化与特殊化的关系，其中子类是父类的细化。 在实现继承时最需要考虑的问题是子类和父类是不是&#8221;IS-A&#8221;的关系。</p>
<p style="text-indent: 2em;">PHP（其它面向对象的语言也类似）对于封装和继承的一些特性是通过访问控制实现。访问控制的作用是控制成员变量，成员方法和基类。 曾经一直以为访问控制的作用仅仅是控制一个类的成员方法和成员变量，这把自己的思维局限于一类一对象了， 这两个方面的控制是PHP对面向对象中封装特性的支持。 把思维拉升到面向对象的体系之上，访问控制也控制了基类（或父类）的行为，或者说控制了继承特性的某些方面。</p>
<p style="text-indent: 2em;">PHP中关于访问控制的关键字和Java等其它面向对象语言一样，如下：</p>
<ul>
<li>public 所定义的类成员可以在任何地方被访问</li>
<li>protected 所定义的类成员则可以被其所在类、其所在类的子类和父类访问</li>
<li>private 定义的类成员则只能被其所在类访问。</li>
</ul>
<p style="text-indent: 2em;">以上的类成员包括成员变量和成员函数。不管是成员变量还是成员方法，PHP默认都是public。 在Java中访问控制默认为包可见，在C++中访问控制默认为私有(private)，而PHP则是公有的(public)，这比Java还要open。 笔者认为这是PHP的一个历史遗留问题。如果可以重新设计PHP，可能是另一个结果，并且这也是语言的对于访问的态度问题。</p>
<p style="text-indent: 2em;">前面介绍的各个访问控制是针对封装性，对于继承性，如下：</p>
<ul>
<li>public/protected 可以被继承</li>
<li>private 没有被继承</li>
</ul>
<blockquote style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-left: 60px; padding-right: 20px; background-image: url(http://localhost/git/blog/web/images/note.png); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #dfdfdf; border-top-width: 1px; border-bottom-width: 1px; border-top-style: solid; border-bottom-style: solid; border-top-color: #aaaaaa; border-bottom-color: #aaaaaa; border-left-width: 0px; border-left-style: initial; border-left-color: initial; border-right-width: 0px; border-right-style: initial; border-right-color: initial; background-position: 15px 8px; background-repeat: no-repeat no-repeat;">
<p style="text-indent: 0px;">实际上，在PHP中，私有方法也会被继承下来，只是其上下文没有改变（还是父类），从而在调用的时候出错。</p>
</blockquote>
<p style="text-indent: 2em;">一般来说，private定义的成员只能被内部调用，仅供当前类使用，这在PHP的源码中检查访问权限控制时， 以private的成员会检查是否属于当前类体现。public定义的成员则属于类或对象的外部接口， 声明的public成员最好是定义好后就不要再变更，这会影响到调用了类的这些方法的相关客户。 好的public和private的设计对于对象本身的自我完备的实际有重大的意义。</p>
<p style="text-indent: 2em;">但是public关键字有一些二义性。对于封装性，它是公有的，任何地方都可以访问的成员；对于继承性， 它允许子类继承此成员。同时兼顾这两个特性，当我们把它作为一个接口提供给外部使用时就会有一些歧义： 子类可以覆盖该成员方法，同时也可以调用访方法，如果子类覆盖了该成员方法并调用了该方法， 则它的实现就和你当初作为接口提供给外部时的含义有一些不同了。和public一样，protected也有类似的问题。 可以思考一下：各语言这样实现的目的是什么？是否有更好的方案？</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2011/05/thinkinphp-5-visibility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>思考PHP语言二：面向对象</title>
		<link>https://www.phppan.com/2010/12/thinkinphp-2-oop/</link>
		<comments>https://www.phppan.com/2010/12/thinkinphp-2-oop/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 01:00:32 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[思考PHP语言]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1190</guid>
		<description><![CDATA[思考PHP语言二：面向对象 【概述】 PHP是一门支持面向过程，也支持面向对象的动态语言。从PHP5开始，PH [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>思考PHP语言二：面向对象<br />
<strong>【概述】</strong><br />
PHP是一门支持面向过程，也支持面向对象的动态语言。从PHP5开始，PHP对于面向对象的支持好了很多。<br />
面向对象程序设计是抽象数据类型的抽象原理的一种应用。当我们使用类时，我们应该了解这是一种抽象数据类型，对象是属于所对应类的类型的。<br />
面向对象的三个特征：封装，继承，多态。这三个特征也可以用：抽象数据类型，继承和方法调用与方法间的动态绑定来说明。抽象是我们与程序复杂性抗争的一种方式，通过这种方式，我们可以关注并且仅关注主要的属性而忽略次要的属性。从语法的角度来说，抽象数据类型是一种封装，它不仅仅包括对于数据的封装，也包括其提供方法的封装。通过访问控制，从而实现数据或方法的隐藏和暴露，这就是我们经常所说的类，它的实例我们称之为对象。</p>
<p><strong>【PHP的抽象数据类型】</strong><br />
PHP以类的形式实现封装，类中所定义的数据称为成员变量；而类中所定义的函数称为成员函数或成员方法。成员函数和成员变量又分别有类属性和实例属性。<br />
<strong>类属性的成员函数和成员变量</strong><br />
PHP中的类属性成员都以静态的方式存在，为所有的实例共享（包括成员函数和成员变量），可以通过类名直接调用。但是其仅在一个PHP的生命周期内有效，这与java等有较大的差别。<br />
<strong>实例属性的成员函数和成员变量</strong><br />
对于实例属性的成员函数和成员变量，一个类的所有实例共享一套成员函数，而每个实例都有属于自己的一套成员变量，这也是我们在做面向对象的程序结构设计时将数据尽量向下移，将共用的方法尽量向上移的原因。<br />
<strong>信息隐藏</strong><br />
PHP中的信息隐藏通过访问控制实现，对于需要隐藏的数据将其以私有成员定义，在其声明前添加private关键字，对于需要公开的数据将其以公有成员定义，在其定义前添加public关键字，也可以不加任何关键字，因为PHP默认情况下是public。PHP的私有和公有访问权限与java相同，</p>
<p><strong>命名封装</strong><br />
在构建大型系统时，为解决不同团队对于函数或类等的命名冲突，我们需要引入命名封装，命名封装是一些逻辑上的封装。在PHP中使用命名空间实现，只是这在PHP５.3版本后才有相关支持。<br />
在PHP中，类，函数和常量这三种类型受命名空间的影响，命名空间通过关键字namespace 来声明，对于层次化的命名空间以反斜杠隔开，如：namespace com\toll\level;</p>
<p><strong>【PHP的继承】</strong><br />
继承是软件复用的一种形式，它不仅可以让程序人员以一个已有类为基础，设计一个修改了的后代类型，还可以定义相关的程序结构和关系。这种结构和关系在一定程度上反映了这些实体的上下代关系。从这里就产生了父类，子类等概念，并且在访问控制中也产生了protected，使用protected时，它的最大访问范围为其派生类。在子类中我们可以定义新的成员变量和新的成员函数，并且可以重载父类的成员函数，但是无法重载父类的构造函数，如果在实例化时需要调用父类的构造函数，我们需要手动调用父类的构造函数，PHP本身不会自动调用。<br />
另外，关于PHP的构造函数的一个历史遗留问题：以类名为构造函数和以__construct为构造函数，在之前写过一篇文章介绍二者在调用时的选择方式。<a href="http://www.phppan.com/2010/11/php-source-27-construct/">PHP源码阅读笔记二十七：PHP对构造方法的识别</a><br />
PHP没有多继承，只支持单继承，但是他拥有接口，它提供了一种多继承的方式。这点和java一样。<br />
接口的定义与类的定义类似，只是关键字变成了interface，接口可以包含常量和方法声明。它的作用仅仅是定义类的说明。类可以实现多个接口，但是类也必须实现接口中的所有方法。接口可以模拟实现多继承，也提供了另一种形式的多态，但是这对于PHP来说没有多大的意义，因为PHP的变量本身就是多态的。</p>
<p>继承是作为增加复用可能性的一种手段，但是它在继承层次中产生的类之间的相互依赖性，产生了一些强耦合。而这与之前的封装的优点刚好相反，封装就是为了保持类之间的相互独立性。所以在作设计时，我们如果使用继承就需要考虑是否真的需要，是否真的是is-a的关系。更多的时候我们会选择使用委托来实现。<br />
<strong>【PHP的动态绑定】</strong><br />
PHP本身就是动态绑定的。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/12/thinkinphp-2-oop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP设计模式笔记：使用PHP实现模板方法模式</title>
		<link>https://www.phppan.com/2010/09/php-design-pattern-16-template-method/</link>
		<comments>https://www.phppan.com/2010/09/php-design-pattern-16-template-method/#comments</comments>
		<pubDate>Sun, 12 Sep 2010 06:05:50 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[设计模式]]></category>
		<category><![CDATA[读书总结]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=984</guid>
		<description><![CDATA[PHP设计模式笔记：使用PHP实现模板方法模式 【意图】 定义一个操作中的算法的骨架，而将一些步骤延迟到子类中 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>PHP设计模式笔记：使用PHP实现模板方法模式</p>
<p><strong>【意图】</strong><br />
定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。Template Method 使得子类可以在不改变一个算法的结构的情况下重定义该算法的某些特定的步骤【GOF95】</p>
<p><strong>【模板方法模式结构图】</strong><br />
<div id="attachment_985" style="width: 316px" class="wp-caption aligncenter"><a href="http://www.phppan.com/wp-content/uploads/2010/09/Template.jpg"><img src="http://www.phppan.com/wp-content/uploads/2010/09/Template.jpg" alt="Template Method" title="Template Method" width="306" height="194" class="size-full wp-image-985" /></a><p class="wp-caption-text">Template Method</p></div></p>
<p><strong>【模板方法模式中主要角色】</strong><br />
抽象模板(AbstractClass)角色: 定义一个或多个抽象方法让子类实现。这些抽象方法叫做基本操作，它们是顶级逻辑的组成部分。<br />
定义一个模板方法。这个模板方法一般是一个具体方法，它给出顶级逻辑的骨架，而逻辑的组成步骤在对应的抽象操作中，这些操作将会推迟到子类中实现。同时，顶层逻辑也可以调用具体的实现方法</p>
<p>具体模板(ConcrteClass)角色：实现父类的一个或多个抽象方法，作为顶层逻辑的组成而存在。</p>
<p>每个抽象模板可以有多个具体模板与之对应，而每个具体模板有其自己对抽象方法（也就是顶层逻辑的组成部分）的实现，从而使得顶层逻辑的实现各不相同。</p>
<p><strong>【模板方法模式适用场景】</strong><br />
1、一次性实现一个算法的不变的部分，并将可变的行为留给子类来实现。<br />
2、各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。<br />
3、控制子类扩展。</p>
<p><strong>【模板方法模式与其它模式】</strong><br />
1、<a href="http://www.phppan.com/2010/07/php-design-pattern-12-strategy/">策略模式(strategy模式)</a>：模板方法使用继承来改变算法的部分，策略模式使用委托来改变整个算法。区别在于封闭的变化不同，一个变化的部分，一个变化的是整体。<br />
2、<a href="http://www.phppan.com/2010/07/php-design-pattern-9-factory-method/">工厂方法模式(factory method模式)</a>：Factory Method模式常被模板方法调用。<br />
<strong>【模板方法模式PHP示例】</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
 * 模板方法模式简单示例 2010-09-12 sz
 * @author phppan.p#gmail.com  http://www.phppan.com                                                       
 * 哥学社成员（http://www.blog-brother.com/）
 * @package design pattern
 */</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * 抽象模板角色
 * 定义抽象方法作为顶层逻辑的组成部分，由子类实现
 * 定义模板方法作为顶层逻辑的架子，调用基本方法组装顶层逻辑
 */</span>
<span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> AbstractClass <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * 模板方法 调用基本方法组装顶层逻辑
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> templateMethod<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'templateMethod begin.&lt;br /&gt;'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">primitiveOperation1</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">primitiveOperation2</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'templateMethod end.&lt;br /&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * 基本方法1
     */</span>
    <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> primitiveOperation1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
     <span style="color: #009933; font-style: italic;">/**
     * 基本方法2
     */</span>
    <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> primitiveOperation2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * 具体模板角色
 * 实现父类的抽象方法
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> ConcreteClass <span style="color: #000000; font-weight: bold;">extends</span> AbstractClass<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * 基本方法1
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> primitiveOperation1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'primitiveOperation1&lt;br /&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
     <span style="color: #009933; font-style: italic;">/**
     * 基本方法2
     */</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">function</span> primitiveOperation2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'primitiveOperation2&lt;br /&gt;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * 客户端
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> Client <span style="color: #009900;">&#123;</span>
&nbsp;
     <span style="color: #009933; font-style: italic;">/**
     * Main program.
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$class</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ConcreteClass<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$class</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">templateMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
Client<span style="color: #339933;">::</span><span style="color: #004000;">main</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p><strong>【模板方法模式】</strong><br />
模板方法是一种代码复用的基本技术，模板方法导致一种反射的控制结构，这指的是一个父类调用子类的操作。<br />
其实现过程：准备一个抽象类，将部分逻辑以具体方法以及具体构造子的形式实现，然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同子类可以以不同的方式实现这些抽象方法，从而对剩余的逻辑有不同的实现。</p>
<p><strong>【重构的原则】</strong><br />
重构时应当遵守的原则是：将行为以是移到结构的高端，而将状态尽量移动到结构的低端。<br />
Auer曾在文献【AUER95】中指出：<br />
1、应当要所行为而不是状态定义一个类。<br />
2、在实现行为是，是用抽象状态而不是用具体状态。<br />
3、给操作划分层次。<br />
4、将状态的确认推迟到子类中。在父类中，如果需要状态属性的话，可以调用抽象的取值方法，而将抽象的取值方法的实现放到具体子类中。<br />
如果可以遵守以上的而，那么就可以在等级结构中将接口与实现分离，将抽象与具体分离，从而保证代码可以最大限度的被复用。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/09/php-design-pattern-16-template-method/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP帮助手册拾遗三：类与对象</title>
		<link>https://www.phppan.com/2010/09/php-manual-3-class-and-object/</link>
		<comments>https://www.phppan.com/2010/09/php-manual-3-class-and-object/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 06:27:49 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP帮助手册]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=980</guid>
		<description><![CDATA[PHP帮助手册拾遗：类与对象 1、__autoload函数 __autoload函数定义时必须包含一个参数，否 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>PHP帮助手册拾遗：类与对象</p>
<p><strong>1、__autoload函数</strong><br />
__autoload函数定义时必须包含一个参数，否则会显示如下错误：<br />
Fatal error: __autoload() must take exactly 1 argument</p>
<p>在 __autoload 函数中抛出的异常不能被 catch 语句块捕获并导致致命错误。</p>
<p><strong>2、父类的构造方法调用 </strong><br />
如果子类中定义了构造函数则不会暗中调用其父类的构造函数。要执行父类的构造函数，需要在子类的构造函数中调用 parent::__construct()。这里python和php一样</p>
<p><strong>3、父类的析构方法调用 </strong><br />
和构造函数一样，父类的析构函数不会被引擎暗中调用。要执行父类的析构函数，必须在子类的析构函数体中显式调用 parent::__destruct()。<br />
<strong>析构函数在脚本关闭时调用，此时所有的头信息已经发出。</strong><br />
试图在析构函数中抛出一个异常会导致致命错误。</p>
<p><strong>4、访问限制 </strong><br />
var与public在类中的变量定义相同，但是在php5的php5.1.3会生成一个E_STRICT警告<br />
方法如果没有设置访问控制，则将默认设置为public</p>
<p><strong>5、构造方法</strong><br />
PHP提交两种构造方法，以类名和__construct，当类中没有__construct方法时，PHP会调用类名函数，但是如果存在__construct时，不管其访问控制是什么，都不会调用类名函数。<br />
如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Demo <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> Demo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Demo function'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'__construct function'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$demo</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Demo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>运行会报错：Fatal error: Call to private Demo::__construct() from invalid context<br />
ps:上面的这个问题是ben前辈提出的，感谢ben前辈昨天的指导</p>
<p><strong>6、静态变量</strong><br />
PHP5.3以后，可以使用变量引用类，但是这个变量不能是关键字（如self,parent,static等）。如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Demo <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000088;">$my_static</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Demo'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$classname</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Demo'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">print</span> <span style="color: #000088;">$classname</span><span style="color: #339933;">::</span><span style="color: #000088;">$my_static</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// As of PHP 5.3.0</span></pre></td></tr></table></div>

<p><strong>7、接口</strong><br />
接口可以有常量，不能有变量，并且常量在其子类中无法重载<br />
如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> Base <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">const</span> <span style="color: #990000;">constant</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'constant value'</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000088;">$var</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;test var&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> Foo implements Base <span style="color: #009900;">&#123;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> Base<span style="color: #339933;">::</span><span style="color: #990000;">constant</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> Base<span style="color: #339933;">::</span><span style="color: #000088;">$var</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>以上代码报错为：Fatal error: Interfaces may not include member variables<br />
注释掉对变量的操作后可以正常打印常量中存放的值。<br />
<strong>8、对象迭代</strong><br />
在PHP5中，使用foreach，遍历一个对象，可以访问这个对象的所有可以访问的属性<br />
如果要自定义迭代器，可以通过实现一个叫Iterator的接口来实现<br />
<strong>9、单例模式</strong><br />
<a href="http://www.phppan.com/2010/06/php-design-pattern-6-singleton/">单例模式(singleton模式)</a>在实现过程中，需要考虑__clone方法。<br />
<strong>10、对象与引用 </strong><br />
PHP5之后，对象在默认情况下是以引用的方式传递的。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/09/php-manual-3-class-and-object/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>妙解Hibernate 3.x——叩响面向对象思想之门 读书笔记</title>
		<link>https://www.phppan.com/2010/05/hibernate-3-x-ooad/</link>
		<comments>https://www.phppan.com/2010/05/hibernate-3-x-ooad/#comments</comments>
		<pubDate>Mon, 10 May 2010 03:14:22 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[程序相关]]></category>
		<category><![CDATA[设计模式]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=690</guid>
		<description><![CDATA[妙解Hibernate 3.x——叩响面向对象思想之门 读书笔记 在今年过生日的时候公司送了这本书给我，是部门 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>妙解Hibernate 3.x——叩响面向对象思想之门 读书笔记<br />
在今年过生日的时候公司送了这本书给我，是部门老大挑的<br />
找些时间看了下，由于在工作中并没有用到Hibernate，所有大部分内容没有看，<br />
只看了前面的几章，当看到第三章，觉得仅第三章，这本书都值得一看（后面的章节由于用不到hibernate，只是简单过一遍）<br />
第三章，看了不下三遍，觉得自己在某些地方还是看不懂，可能是对于面向对象的一些东西的理解还不够<br />
</p>
<p>使用继承、委托看待和拆解设计模式<br />
<br />
将对象做虚，做软，不要被“变因”硬邦邦地绑住<br />
    &#8212;-封装变化<br />
<br />
生成对象时，不直接new，才不会被具体对象绑死，此原则在学习面向对象中的创建模式有很好的指导作用<br />
   &#8212;-封装创建过程<br />
<br />
模板方法与策略都将算法提取出来，只不过模板方法使用的是继承，策略使用的是委托<br />
     &#8212;-其实就这种模式，其本质应该是在其封装的变化的不同，模板方法是封装部分算法，而策略是封装整个算法<br />
策略的重用性会高一些，只是需要付出一些额外的代价<br />
<br />
回归最根本的面向对象思想：封装、继承、多态、委托<br />
<br />
关于设计模式的学习：<br />
1、接口、抽象类、具体对象是软件“软性”的指标之一，可按照实际需要的稳定性加以调整<br />
2、研究模式三部曲：明确要解决的问题&#8211;>怎么解&#8211;>套用模式所带来的好处和副作用<br />
3、从代码级看设计模式：<br />
   去掉new<br />
   去掉if/switch&#8230;case.<br />
   去掉重复的代码<br />
4、开始接触一个新的设计模式，如果领导不到使用该模式的好处，不妨动手写一段程序，再来跟书中的实例进行比较<br />
5、不时和自己的心灵对话&#8212;用自己的话来诠释模式，哪怕是简短的一句话，一个口诀，一个比喻<br />
    Builder  单一制程，不同风格<br />
    Sigleton  just only one<br />
    Prototype 复制<br />
    Adapter  转换<br />
    Composite Tree<br />
    Decorator  Dynamic composing behavior<br />
    Facade 简化<br />
    Proxy   本体/分身相互成就<br />
    Momento  借尸还魂<br />
    Strategy 替换多变的内部行为<br />
6、不同的设计模式可能极其相似，搞不清是因为没有彻底掌握，这需要时间的积累<br />
7、设计模式老是记不住，无法突破，那就放弃，过段时间再来温故知新<br />
8、运用面向对象和设计模式，切忌矫枉过正，不要好处没得到，却被过度设计给弄复杂了<br />
<br />
从Think in Data 到Think in Object<br />
</p>
<p>&#8211;EOF&#8211;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/05/hibernate-3-x-ooad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP in Action Objects, Design, Agility读后总结</title>
		<link>https://www.phppan.com/2010/03/php-in-action-objects-design-agility/</link>
		<comments>https://www.phppan.com/2010/03/php-in-action-objects-design-agility/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 01:18:47 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[读书总结]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=612</guid>
		<description><![CDATA[PHP in Action Objects, Design, Agility读后总结 经过了一个月的辛苦，终于 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>PHP in Action Objects, Design, Agility读后总结</p>
<p>经过了一个月的辛苦，终于把这本书看完了，觉得受益良多！<br />
觉得自己对PHP5中的一些以前没有注意到的细节有了更多的了解，例如PHP4和php5中的对于对象复制的问题，PHP中的方法重载，访问控制，类方法，虚类和虚方法，类提示及接口等<br />
另外就PHP中面向对象的what,how,why有了更清楚的认识，特别是一些设计原则的应用有了更深刻的认识<br />
但是对于第二部分的测试和重构，觉得说得有些浅，至少我觉得有些用不上，<br />
特别需要提到的是第三部分，构建WEB页面，其中就模板引擎，表单验证，MVC模式，数据抽象进行了详细的说明<br />
这一章，让我对于那些框架性的东西有了更深层次的理解，<br />
比如，对于数据抽象，可以联想到yii框架中的数据库类，很好的做到了书中提到的几个观点；<br />
比如，模板引擎，让我对于正在使用的框架模板有了更清楚的认识。<br />
比如，表单验证，对比黑夜路人的TMPHP框架中的那些工具类等等<br />
特别是对于控制器的说明:让我明白自己正在使用的框架中对于控制器的错误使用；<br />
<strong>总体来说：这是一本好书，值得一看。应该不止看一遍。</strong><br />
<br />
第一章：PHP and modern software development（PHP与现代软件开发）<br />
    简单介绍了PHP的一些历史和特点，PHP 5中的面向对象，设计模式，重构、敏捷开发以及测试驱动开发等等<br />
第二章：Objects in PHP（PHP中的对象）<br />
   本章首先稍微详细的介绍了PHP中的面向对象，以及一些简单的DEMO，然后是PHP中的异常处理，以及PHP4和php5中的对于对象复制的问题和PHP中的方法重载，<br />
在这一章中对于PHP的面向对象知识有一些补充；<br />
第三章：Using PHP classes effectively（有效使用PHP类）<br />
   本章就PHP类的使用作了详细介绍，其中包括访问控制，类方法，虚类和虚方法，类提示及接口，<br />
在这里对PHP中的类和接口的相关知识作了详细介绍，如果基础不好，可以多看几遍<br />
第四章：Understanding objects and classes（理解对象和类）<br />
   本章就使用对象和类的 why,how,what作了介绍，其中说明了面向对象的优点，设计原则，以及使用的地方<br />
如果有时间希望可以再看一遍</p>
<p>
EOF</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/03/php-in-action-objects-design-agility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
