<?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/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>玄猫的窝-韩国峰的博客 &#187; 听小韩聊PHP项目开发</title>
	<atom:link href="http://www.hanguofeng.cn/tag/%e5%90%ac%e5%b0%8f%e9%9f%a9%e8%81%8aphp%e9%a1%b9%e7%9b%ae%e5%bc%80%e5%8f%91/feed" rel="self" type="application/rss+xml" />
	<link>http://www.hanguofeng.cn</link>
	<description>韩国峰的博客,关注Web技术与电子商务。</description>
	<lastBuildDate>Sat, 04 Sep 2010 14:39:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>听小韩聊PHP项目开发(3)–切分你的系统</title>
		<link>http://www.hanguofeng.cn/archives/web-server/php-project-development-3?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=php-project-development-3</link>
		<comments>http://www.hanguofeng.cn/archives/web-server/php-project-development-3#comments</comments>
		<pubDate>Mon, 12 Jul 2010 12:04:09 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[Web服务器端技术]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[听小韩聊PHP项目开发]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/?p=144</guid>
		<description><![CDATA[【写在前面的话：看看本文的时间，最后一次保存是去年的八月份，想想，还是先发表一下，然后待续，老规矩，在本文完成之前请不要转载。】 你是一个有控制欲的人么？你希望把控你的项目么？那么，切分他们吧。 1、为什么要切分你的项目 我们是邪恶的 -.-。我们希望把控我们的项目，所以，我们需要切分它。 想像一下，你有一个生日蛋糕，你想吃掉它，那么，按照惯例，作为寿星的你，应该先切分它，什么？你还要点蜡烛？OMG，你要在吹蜡烛时喷口水在蛋糕上吗？你的口味好重。 切分代码，大体上来说，在控制进度、应对变化、简化逻辑、代码复用、分工协作等方面，都有相当的好处。 1.1、控制进度 首先来说控制进度，当你开始开发一个大型站点时（当然，更多的时候是“你们”），作为项目经理的你来讲，你需要时不时的应对来自你的上级或者你的客户的询问&#8211;“小韩，做了多少了，还有多久能做完啊”。这个时候，你总不能说，“哦，我做了一些了，还有一段时间能做完。” 你的领导希望听到的是，系统一共有x个模块，我做完了x个，剩下x个模块，难度有些大，可能还需要x天的时间，等所有模块都完成了，再整体整合测试一下，就OK了。这样回答，我想你的表现会让你的领导觉得，你是一个思路清晰，能够把控的项目管理人员。这里再容我跑题一下，一般认为，管理职能分为“计划、组织、协调、控制”等。其中“计划”则首先依赖于对项目的切分，如果不能切分项目，则无从进行计划。 1.2、应对变化 我们都知道，项目，尤其是软件项目是多变的，这种变化可能来自于前期沟通的不完善，也可能来自于随着时间的发展，客户或软件使用者的需求随之发展而发生变化。如果项目中所有的部分都是互相缠绕的，那么则牵一发而动全身，你甚至无法对一个简单的变量名进行改变，而使得系统的其他部分不受到干扰。然而此时，如果对系统进行划分，将其分为若干层次、若干模块，层次与层次、模块与模块之间通过既定协议（如接口）进行通讯，则可以将原有的整体复杂系统切分为若干个子系统、子模块、子程序，各程序只要保持其输入、输出不变，则其内部的代码可以方便的更改而不怕会影响到外部。 我举个例子来讲，你可能用以下代码处理用户的登录以及其登录会话的持久化（Session）。 //登录代码 if&#40;$success_login&#41; //假设$success_login为上一步判断用户名密码正确与否的标记 &#123; $_SESSION&#91;'user_name'&#93; = $user_name; $_SESSION&#91;'password'&#93; = $password; &#125; 而使用如下代码判断是否登录 if&#40;isset&#40;$_SESSION&#91;'user_name'&#93;&#41;&#41; &#123; //do something &#125; 那么假设有一天，你想使用username作为保存用户名的Session变量名称，则你需要找出所有形如$_SESSION['user_name']的代码，并修改，一旦有遗漏，你的程序将会出现难以查找的bug。 这就是因为在代码中，把用户登录会话的部分耦合在了全部的系统当中。实际上，你应该专门有一个管理用户登录会话的模块，比如叫做SessionManager，你的代码则可能变为这样： /** * 设定登录会话 */ if&#40;$success_login&#41; //假设$success_login为上一步判断用户名密码正确与否的标记 &#123; SessionManager::SetLoginUser&#40;$user&#41;; &#125; &#160; /** * 判断登录状态 */ if&#40;SessionManager::IsLogined&#40;&#41;&#41; &#123; //do something &#125; 这样，你在系统中，无需过度关注用户会话保存的具体实现，只要去调用SessionManager这个管理器的相关方法就可以了，而一旦发生前面提到的变化，你可以在SessionManager的内部完成此修改，而不会将这个问题渲染到全部代码。 1.3、简化逻辑 也许大部分普通的Web站点并没有复杂的逻辑，但是，随着网络世界越来越精彩，Web站点也会逐渐面临处理复杂逻辑的任务。一旦你面临复杂的系统，其中可能难倒你的，大部分不会是技术问题，而是逻辑问题，我们应当承认我们人类中的大部分，思维的稳定性和思维长度，都是有限的，我举个例子来说，在下棋的时候，在头脑中演算下一步应该如何走，对手针对你的下一步如何走这样的逻辑，没有经过一定锻炼的人，是不可能演算很多步的。对于系统逻辑来说也是一样的，同时考虑过多的问题，以及这些问题之间的关系，会让你无法承受，然而此时将一个大的、复杂的问题切分为若干小问题，在同一时刻只关注一个小问题，则可以让自己轻松快乐的去进行程序的编写。再举个例子，比如我们要写一个MSN的客户端，那么实际上是有很多问题要考虑的，你的程序如何与服务器通讯，如何构造和发送数据，如何接受和处理数据，如何将数据显示在界面上……so many，这个时候你可以将你的系统切分为若干的模块，有的模块去处理网络通讯，有的去处理数据包的解析和构造，有的去处理界面显示，有的去处理各种事件的调度，等等等等，在各个模块中，你还可以进一步划分，直到单个类遵循单一职责原则，而一个模块间各个类都是聚合的……等等等等，这里有很多方法和技巧，我们稍后会详细讨论。 [...]]]></description>
			<content:encoded><![CDATA[<p>【写在前面的话：看看本文的时间，最后一次保存是去年的八月份，想想，还是先发表一下，然后待续，老规矩，在本文完成之前请不要转载。】</p>
<p>你是一个有控制欲的人么？你希望把控你的项目么？那么，切分他们吧。</p>
<h2>1、为什么要切分你的项目</h2>
<p>我们是邪恶的 -.-。我们希望把控我们的项目，所以，我们需要切分它。</p>
<p>想像一下，你有一个生日蛋糕，你想吃掉它，那么，按照惯例，作为寿星的你，应该先切分它，什么？你还要点蜡烛？OMG，你要在吹蜡烛时喷口水在蛋糕上吗？你的口味好重。</p>
<p>切分代码，大体上来说，在控制进度、应对变化、简化逻辑、代码复用、分工协作等方面，都有相当的好处。</p>
<h3>1.1、控制进度</h3>
<p>首先来说控制进度，当你开始开发一个大型站点时（当然，更多的时候是“你们”），作为项目经理的你来讲，你需要时不时的应对来自你的上级或者你的客户的询问&#8211;“小韩，做了多少了，还有多久能做完啊”。这个时候，你总不能说，“哦，我做了一些了，还有一段时间能做完。”</p>
<p>你的领导希望听到的是，系统一共有x个模块，我做完了x个，剩下x个模块，难度有些大，可能还需要x天的时间，等所有模块都完成了，再整体整合测试一下，就OK了。这样回答，我想你的表现会让你的领导觉得，你是一个思路清晰，能够把控的项目管理人员。这里再容我跑题一下，一般认为，管理职能分为“计划、组织、协调、控制”等。其中“计划”则首先依赖于对项目的切分，如果不能切分项目，则无从进行计划。</p>
<h3>1.2、应对变化</h3>
<p>我们都知道，项目，尤其是软件项目是多变的，这种变化可能来自于前期沟通的不完善，也可能来自于随着时间的发展，客户或软件使用者的需求随之发展而发生变化。如果项目中所有的部分都是互相缠绕的，那么则牵一发而动全身，你甚至无法对一个简单的变量名进行改变，而使得系统的其他部分不受到干扰。然而此时，如果对系统进行划分，将其分为若干层次、若干模块，层次与层次、模块与模块之间通过既定协议（如接口）进行通讯，则可以将原有的整体复杂系统切分为若干个子系统、子模块、子程序，各程序只要保持其输入、输出不变，则其内部的代码可以方便的更改而不怕会影响到外部。</p>
<p>我举个例子来讲，你可能用以下代码处理用户的登录以及其登录会话的持久化（Session）。</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//登录代码</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$success_login</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">//假设$success_login为上一步判断用户名密码正确与否的标记</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'user_name'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$user_name</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$password</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>而使用如下代码判断是否登录</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'user_name'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">//do something</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>那么假设有一天，你想使用username作为保存用户名的Session变量名称，则你需要找出所有形如$_SESSION['user_name']的代码，并修改，一旦有遗漏，你的程序将会出现难以查找的bug。</p>
<p>这就是因为在代码中，把用户登录会话的部分耦合在了全部的系统当中。实际上，你应该专门有一个管理用户登录会话的模块，比如叫做SessionManager，你的代码则可能变为这样：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
* 设定登录会话
*/</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$success_login</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">//假设$success_login为上一步判断用户名密码正确与否的标记</span>
<span style="color: #009900;">&#123;</span>
 SessionManager<span style="color: #339933;">::</span><span style="color: #004000;">SetLoginUser</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</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: #b1b100;">if</span><span style="color: #009900;">&#40;</span>SessionManager<span style="color: #339933;">::</span><span style="color: #004000;">IsLogined</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
 <span style="color: #666666; font-style: italic;">//do something</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>这样，你在系统中，无需过度关注用户会话保存的具体实现，只要去调用SessionManager这个管理器的相关方法就可以了，而一旦发生前面提到的变化，你可以在SessionManager的内部完成此修改，而不会将这个问题渲染到全部代码。</p>
<h3>1.3、简化逻辑</h3>
<p>也许大部分普通的Web站点并没有复杂的逻辑，但是，随着网络世界越来越精彩，Web站点也会逐渐面临处理复杂逻辑的任务。一旦你面临复杂的系统，其中可能难倒你的，大部分不会是技术问题，而是逻辑问题，我们应当承认我们人类中的大部分，思维的稳定性和思维长度，都是有限的，我举个例子来说，在下棋的时候，在头脑中演算下一步应该如何走，对手针对你的下一步如何走这样的逻辑，没有经过一定锻炼的人，是不可能演算很多步的。对于系统逻辑来说也是一样的，同时考虑过多的问题，以及这些问题之间的关系，会让你无法承受，然而此时将一个大的、复杂的问题切分为若干小问题，在同一时刻只关注一个小问题，则可以让自己轻松快乐的去进行程序的编写。再举个例子，比如我们要写一个MSN的客户端，那么实际上是有很多问题要考虑的，你的程序如何与服务器通讯，如何构造和发送数据，如何接受和处理数据，如何将数据显示在界面上……so many，这个时候你可以将你的系统切分为若干的模块，有的模块去处理网络通讯，有的去处理数据包的解析和构造，有的去处理界面显示，有的去处理各种事件的调度，等等等等，在各个模块中，你还可以进一步划分，直到单个类遵循单一职责原则，而一个模块间各个类都是聚合的……等等等等，这里有很多方法和技巧，我们稍后会详细讨论。</p>
<h3>1.4、代码复用</h3>
<p>代码复用的一个重要基础是分割变化与不变的部分，并分别进行编程。还以我们上面的MSN客户端的例子来说，其处理网络通讯的模块，在其他的程序中是不是也可以使用呢？答案是肯定的，但是……这要求你能够良好设计这个模块，权衡其边界，以使其具有普适性。这种基础类的实现，不应当关联具体项目的问题，比如说最简单的，你的方法名，不应当叫做send_msn_request，而只是send_request，这只是一个很简单的例子，但是却说明了，你要考虑你系统中的某些聚合功能，是不是可以在其他项目中使用的，如果是，请将其切分出来，并撰写并非是与当前项目紧密耦合的代码，你可以使用一个适配器将其配接到当前项目中，而不是将其直接为当前项目撰写。</p>
<p>关于代码复用的内容，您还可以查看<a href="http://www.ibm.com/developerworks/cn/java/reuse/">http://www.ibm.com/developerworks/cn/java/reuse/</a>获得更多信息。</p>
<h3>1.5、分工协作</h3>
<p>分工协作首先要求在“工”上有的可分，现代生产是要求详细分工，流水线方式作业的，试想，哪怕一个简单的MP3，有做芯片的机器，有开发嵌入式系统的工程师，还有利用模具生产的合作工厂，最后将各个部分拼接起来，成为你手中那个会发声、可以控制的小玩意。程序开发也是一样的。每一个系统，无论简单复杂，总是由若干个子系统组成的，这些子系统通常是功能内聚的，并通过某些特定方式与其他子系统进行协作。简单说，你所看到的这个WordPress的系统，有文章的子模块、有分类/Tag的子模块，那么我们是否可以让两个人分别去开发文章的子模块和分类/Tag的子模块呢，答案是肯定的，合作者首先坐在一起，定义各自的系统边界，开发分类/Tag子模块的工程师无需了解文章是由标题、内容，甚至图片组成的，他只了解，需要给特定的文章（通过文章的id来作为关键标记），进行分类，或者标记Tag，同理，开发文章子模块的工程师也无需了解Tag和分类的区别，只需要做他的文章模块的CURD就可以了，彼此之间不需要了解太多，是增强系统稳定性，在变化时可以敏捷修改而不担心影响其他部分的重要方式。这可以降低系统的开发和修改成本，工程师之间不必担心进行了重复的工作，因为子系统边界已经确定，每个人需要做什么是非常清晰的，同时，他们不必担心他们所完成的功能如何被调用，因为这些调用规则在切分系统时就明确了。他们也不必考虑其他子系统是否会影响他的系统，包括其他子系统的bug或者修改，因为各子系统是<a href="http://www.blogjava.net/realsmy/archive/2007/04/08/109245.html" target="_blank">高内聚、低耦合</a>的，子系统的具体实现方式不会过多影响其他系统。</p>
<h2>2、如何切分你的系统</h2>
<p>切分系统是一种艺术而不是一种技术。从不同的角度看某个物体，你会得到不同的投影，一个正方形的投影，那么其原物体一定是正方体吗，当然未必。从不同的角度看待系统，就会有不同的切分方式。而我们要做的就是，试图从各个角度来看待系统，避免盲人摸象，最终选择一种权衡的、折衷的，对于系统的发展方向最契合的方式来切分。不同的程序员有不同的切分习惯，而我们也无法武断的去说一定要按照某种方式切分。毕竟，我们不是为了切分系统而切分，而是要达成某种目的，这些目的我在上面笼统的谈过，比如说，针对分工协作，如果团队中程序员的水平有一定差距，那么可以将相对内核的复杂部分切出来，交由有经验的程序员来完成，即时它可能在其他方面并不能达到你的目的。</p>
<p>切分系统有几种角度，让我们由浅入深的聊一聊。</p>
<h3>2.1、横向切分</h3>
<p>对于系统的切分，横向切分是最常见的，例如<a title="MVC" href="http://zh.wikipedia.org/wiki/MVC" target="_blank">MVC</a>模式：<strong>MVC</strong>（Model-View-Controller，模型—视图—控制器模式）用于表示一种软件架构模式。它把软件系统分为三个基本部分：模型（Model），视图（View）和控制器（Controller）。</p>
<p>这种切分方式主要考虑了系统是由几个层次来完成的，各个层次之间的功能是内聚的，比如在MVC中，Model层负责数据交互，它永远不必理解数据在界面上是如何展示的，同理，View层也不必理解数据是从MySQL数据库还是SQL Server甚至是文件中的哪个取出的。</p>
<p>这种层次的划分，可以将系统功能划分为几个大部分，这几个大部分相对独立，然而又通过行为/数据被粘合在一起，从而使得其中某个部分发生变化时，其他部分不至于那么敏感，比如，网站的界面是会频繁改版的，然而你会发现，几乎大部分情况都是，界面上的元素摆放发生了变化，但是数据本身并没有任何变化，那么我们只需要改变View层就可以了，你的C和M层的代码一点都不用改动。</p>
<p>另一个名词叫做“三层架构”，实际上和MVC类似，也有人将MVC直接成为三层架构。其代表是微软的示例程序PetShop（<a title="PetShop的系统架构设计分析" href="http://www.cnblogs.com/wayfarer/archive/2006/04/14/375382.html" target="_self">架构详细分析看这里</a>）。其将系统大致分为DAL（Data Access Level，数据访问层）、BLL（Bussines Logic Level，业务逻辑层）以及界面表示层。</p>
<p>但是，我窃以为，仅有MVC是不够的。在MVC中，Model层的功能实际上是可以再分为数据逻辑和业务逻辑两个层次，即更倾向于三层架构。业务逻辑层可以复用多个数据逻辑层，这在仅有Model层的系统中是难以做到的，同时，业务逻辑是可能发生频繁变更的，此时简单的数据逻辑并没有发生任何变化，不需要花代价和承担风险进行修改。我举个例子来说，我们要设计一个用户系统，该系统有注册、登录、修改信息等功能，此时，我们可以根据需求制定出一个业务逻辑层，你可以将其叫做LogicOperation/UserOperation层（下文简称UserOper），在该层中切合需求进行功能的设计，即Login、Regist、ModifyInfo，那么，我们是否在这个层次中就开始撰写关于数据库操作的代码呢，答案是否定的，因为你会发现，在Login功能中，你需要去查询用户名是否存在这样的信息，在Regist中，你同样会查询该信息，此时，你应该继续抽象出一个功能相对原子化的数据操作层，即DataManager/UserManager，在UserManager中，实现标准的CURD（Create、Update、Read、Delete）功能，以及某些可能用到的其他功能，但是这些方法应该是原子化的，可以由UserOper组合调用，例如在Regist中，可能通过UserManager的IsAccountExist方法查询用户名是否存在，然后用CreateUser方法建立用户，而在Login中，首先通过IsAccountExist方法查询用户名是否存在，然后用ReadUserByAccount方法来获得用户信息，并继而比对密码，等等，你会发现，LogicOperation层是对DataManager层方法的组合调用，而其组合方式就是具体的业务逻辑。</p>
<h3>2.2、纵向切分</h3>
<h3>2.3、混合切分</h3>
<h3>2.4、切分粒度</h3>
<h2>3、切分案例</h2>
<h2>3.1、一个CMS系统的切分</h2>
<h3>3.2、一个博客系统的切分</h3>
<h3>3.3、一个校内网APP程序的切分</h3>
<h2>4、切分作业</h2>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/web-server/php-project-development-2" title="听小韩聊PHP项目开发(2)&#8211;观察你的项目">听小韩聊PHP项目开发(2)&#8211;观察你的项目</a></li><li><a href="http://www.hanguofeng.cn/archives/web-server/php-project-development-1" title="听小韩聊PHP项目开发(1)&#8211;开题的话">听小韩聊PHP项目开发(1)&#8211;开题的话</a></li><li><a href="http://www.hanguofeng.cn/archives/security/configure-fast-in-lamp-on-windows-with-xampp" title="Windows下AMP平台配置FastCGI方法（以xampp为基础）">Windows下AMP平台配置FastCGI方法（以xampp为基础）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/web-server/php-project-development-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<series:name><![CDATA[听小韩聊PHP项目开发]]></series:name>
	</item>
		<item>
		<title>听小韩聊PHP项目开发(2)&#8211;观察你的项目</title>
		<link>http://www.hanguofeng.cn/archives/web-server/php-project-development-2?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=php-project-development-2</link>
		<comments>http://www.hanguofeng.cn/archives/web-server/php-project-development-2#comments</comments>
		<pubDate>Sun, 28 Jun 2009 05:42:06 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[Web服务器端技术]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[听小韩聊PHP项目开发]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/?p=125</guid>
		<description><![CDATA[Hello，时隔半年，我终于继续了 =.= 1、为什么要观察你的项目&#8211;需求的重要性。 俗话说，磨刀不误砍柴工，当开始一个项目时，我希望你就像在街上看到了美女，你要先好好打量打量，然后再思考，“啊，我怎么去问她的电话呢~” So,same as our projects. 当开始一个项目时，你应当首先审视的是项目的需求，要注意了，除非是你自己为自己闲着没事做的东西，其他的项目，都是为别人做的，怎么理解呢，我的意思是说，你项目的目的就是满足别人的需求。软件实际上是一种商品。所谓商品，就是商品是为交换而生产（或用于交换）的对他人或社会有用的劳动产品[百度百科]。请注意“对他人或社会有用”，这就是在讲，我们所编写的软件是为了满足需求而存在的，如果不能满足需求，哪怕你用了再高的技术，软件做的再漂亮，运行效率再高，都不能被称之为一款合格的软件。 为什么突然要扯这么远呢，是因为，我曾经和很多人一样，在做开发的时候，开始的时候无时不刻的都在想，这个东西有什么技术创新点，什么地方的效率会很低，应该解决，后来我听到了一句话，叫做“过早优化是万恶之源（premature optimization is the root of all evil&#8211;Donald Knuth）”，可能的确有那样一些项目，他们要求很高的效率，或者，该项目的需求者一直在询问你关于效率的问题，但是无论如何，在你什么都没有的时候，你就什么都不能做，就像你并没有一个女儿，你却时刻想着如何去打扮她一样毫无意义。 请记住，我们所编写的软件，它的第一要务是满足需求，当然，运行效率、界面美化可能是需求的一部分（非功能性需求，我们稍后会谈到），但是请将其作为需求考虑，而不是贯穿软件的全部。 关于需求，这里有一幅漫画，来源未知（提示：你可以点击图片放大）： 另外还有此图片的中文版：http://picasaweb.google.com/lh/photo/ZK59I5p5-jfsc7kl213htQ?feat=directlink 2、我要观察到什么&#8211;什么是需求 “需求是产品必须完成的事以及必须具备的品质。需求存在的原因要么是该类型的产品要求一定的功能和品质，要么是客户希望需求成为交付的产品的一部分。” &#8211;《掌握需求过程》ISBN:9787115159830 从上面的漫画中，可以很有趣的发现，由于沟通方式，对目标的理解差异和技术水平的不同，都会让需求在传递中发生变化，这种变化有时可能是致命的，我们人类在沟通时多采用语言，然而语言，尤其是口头语言，极易发生变化。因此，就需要大家对需求有一个统一的认识，什么是需求，需求应该包括哪些内容，不应该包括哪些内容，应该如何去分析需求。 本节引言中的话，严格来讲不是对需求的定义，让我们来看IEEE软件工程标准词汇表(1997年)中“需求”的定义： (1)用户解决问题或达到目标所需的条件或权能(Capability)。 (2)系统或系统部件要满足合同、标准、规范或其它正式规定文档所需具有的条件或权能。 (3)一种反映上面(1)或(2)所描述的条件或权能的文档说明 软件需求包括三个不同的层次—业务需求、用户需求和功能需求—也包括非功能需求。业务需求( business requirement)反映了组织机构或客户对系统、产品高层次的目标要求，它们在项目视图与范围文档中予以说明。用户需求(user requirement) 文档描述了用户使用产品必须要完成的任务，这在使用实例(use case)文档或方案脚本(scenario)说明中予以说明。功能需求(functional requirement)定义了开发人员必须实现的软件功能，使得用户能完成他们的任务，从而满足了业务需求。所谓特性(feature)是指逻辑上相关 的功能需求的集合，给用户提供处理能力并满足业务需求。 简单来说，需求就是说明你软件将要满足的用户需要，需求是你软件的功能列表，这里的功能可能包括看得见的功能和看不见的功能。同时需要注意实际用户（用户是重要的需求分析参与者，难以想象一个只有开发者而没有用户参与的需求分析，所得出的是什么）可能对需求的理解有误，有时他们甚至不了解活无法向你描述出他的需求，也有时，他会“啰啰嗦嗦”的向你讲一堆不是需求的东西。 同时，需求还包括非功能的部分，例如，“单次搜索查询必须在0.1秒内完成”、“用户传输文件的速度不应低于其网络最高可用带宽的50%”，这些内容并非软件的功能性要求，但是实际上是软件的使用者使用软件体验、感受的重要感受点甚至是其是否能完成功能性需求的制约。 3、我没有马王爷的第三只眼&#8211;那么我如何分析需求呢 哦，这很麻烦，是的，好吧，我们退一步，作为开发人员，你可以让你的产品经理去和客户打交道，但是你必须和你的产品经理打交道，同时，你还必须和你的代码打交道。 与产品经理打交道和与代码打交道是两码事，八杆子打不到一块，你不能和产品经理讲if(xxx)  {} ，也不能去问你的代码，这里是让用户操作的，还是你丫自动操作的。 在与产品人员打交道时，你有责任用他们的语言来描述问题，这并不是单纯为了对方能够听懂你说什么，更重要的是，这会大大减少你们在交流沟通中的误解。所以，熟知你所在的行业，熟悉他们的业务，如果你要开发财务系统，请去阅读财会相关书籍，如果你要开发ERP系统，请去和工人师傅、基层管理人员多聊聊，在拓展你领域的同时，也会让你对你的编程思想有新的看法。 在与代码打交道的时候，你需要是一个好的建筑师，你应当构建严谨、运行健壮、可扩展性强的代码，这要求你在充分理解需求的情况下，看到需求的发展方向以及需求中可能发生变动的情况，甚至你需要和产品经理、客户去沟通，提出你的想法，当你问道“我觉得这里这样做的话，系统可能存在不稳定的因素，如果怎么怎么样做，不仅系统稳定了，您的操作也会更方便”，客户恍然大悟，你又减轻了工作量，何乐不为呢。 在理解需求、分析系统时，我建议你首先这样做： 将系统中存在的活动者都列出来，然后依次列出他们的操作功能和反应。 比如，一个简单的文章系统，我们可能这样去描述它 普通用户：注册、登录、找回密码、修改个人信息、查看类别、查看文章、查看某个类别下的文章、输入关键字搜索文章、发表评论、当别人发表对自己评论的回复时收到邮件。 管理员：查看用户信息、CURD（Create-Update-Read-Delete）类别、CURD文章 在上面的需求描述中，涉及了两个活动者，分别是“普通用户”和“管理员”，同时两个活动者都有若干功能，其中“普通用户”的“当别人发表对自己评论的回复时收到邮件”实际上不是用户的主动操作，而是用户对某个操作的反应，需要注意的是，这样的信息也需要在需求分析中体现。 需求分析可以体现为UML用例图，其好处是更直观，同时由于是统一化的表达，更有助于沟通，其他程序员可以更方便的理解你的意思，而不容易出现理解误差。 关于UML用例图方面的内容，可以到http://hi.baidu.com/jyangstu/blog/item/5d2f89131ef270c6c3fd7833.html查看一份简介。 我的需求方法实际上是用例图的一个超级简版，这个方法不能体现活动者与活动者、用例与用例（就是活动者所做的那些事情）之间的关系，一般适用于小型项目或大中型项目的模块级需求分析，对大中型项目的整体需求分析，实际上是一个非常复杂、有机结合的多个过程的系统，以后有机会我们再探讨。 [...]]]></description>
			<content:encoded><![CDATA[<p>Hello，时隔半年，我终于继续了 =.=</p>
<h2>1、为什么要观察你的项目&#8211;需求的重要性。</h2>
<p>俗话说，磨刀不误砍柴工，当开始一个项目时，我希望你就像在街上看到了美女，你要先好好打量打量，然后再思考，“啊，我怎么去问她的电话呢~”</p>
<p>So,same as our projects.</p>
<p>当开始一个项目时，你应当首先审视的是项目的需求，要注意了，除非是你自己为自己闲着没事做的东西，其他的项目，都是为别人做的，怎么理解呢，我的意思是说，你项目的目的就是满足别人的需求。软件实际上是一种商品。所谓商品，就是商品是为交换而生产（或用于交换）的对他人或社会有用的劳动产品[<a href="http://baike.baidu.com/view/68843.htm" target="_blank">百度百科</a>]。请注意“对他人或社会有用”，这就是在讲，我们所编写的软件是为了满足需求而存在的，如果不能满足需求，哪怕你用了再高的技术，软件做的再漂亮，运行效率再高，都不能被称之为一款合格的软件。</p>
<p>为什么突然要扯这么远呢，是因为，我曾经和很多人一样，在做开发的时候，开始的时候无时不刻的都在想，这个东西有什么技术创新点，什么地方的效率会很低，应该解决，后来我听到了一句话，叫做“过早优化是万恶之源（premature optimization is the root of all evil&#8211;<a href="http://en.wikipedia.org/wiki/Donald_Knuth" target="_blank">Donald Knuth</a>）”，可能的确有那样一些项目，他们要求很高的效率，或者，该项目的需求者一直在询问你关于效率的问题，但是无论如何，在你什么都没有的时候，你就什么都不能做，就像你并没有一个女儿，你却时刻想着如何去打扮她一样毫无意义。</p>
<p>请记住，我们所编写的软件，它的第一要务是满足需求，当然，运行效率、界面美化可能是需求的一部分（非功能性需求，我们稍后会谈到），但是请将其作为需求考虑，而不是贯穿软件的全部。</p>
<p>关于需求，这里有一幅漫画，来源未知（提示：你可以点击图片放大）：<br />
<a href="http://picasaweb.google.com/lh/photo/TDuCZ-g51Jx6Bry-m9D6vQ?feat=embedwebsite"><img src="http://lh3.ggpht.com/_OkD473b7axo/Si08GNdByVI/AAAAAAAAAic/mqkDFXeLXsg/s400/8bdbce98-4d20-3784-891b-a3d4f0970df3.jpg" alt="" /></a></p>
<p>另外还有此图片的中文版：http://picasaweb.google.com/lh/photo/ZK59I5p5-jfsc7kl213htQ?feat=directlink</p>
<h2>2、我要观察到什么&#8211;什么是需求</h2>
<p><em>“需求是产品必须完成的事以及必须具备的品质。需求存在的原因要么是该类型的产品要求一定的功能和品质，要么是客户希望需求成为交付的产品的一部分。”</em></p>
<p style="text-align: right;"><em>&#8211;《掌握需求过程》ISBN:9787115159830</em></p>
<p style="text-align: left;">从上面的漫画中，可以很有趣的发现，由于沟通方式，对目标的理解差异和技术水平的不同，都会让需求在传递中发生变化，这种变化有时可能是致命的，我们人类在沟通时多采用语言，然而语言，尤其是口头语言，极易发生变化。因此，就需要大家对需求有一个统一的认识，什么是需求，需求应该包括哪些内容，不应该包括哪些内容，应该如何去分析需求。</p>
<p style="text-align: left;">本节引言中的话，严格来讲不是对需求的定义，让我们来看IEEE软件工程标准词汇表(1997年)中“需求”的定义：</p>
<p>(1)用户解决问题或达到目标所需的条件或权能(Capability)。</p>
<p>(2)系统或系统部件要满足合同、标准、规范或其它正式规定文档所需具有的条件或权能。</p>
<p>(3)一种反映上面(1)或(2)所描述的条件或权能的文档说明</p>
<p>软件需求包括三个不同的层次—业务需求、用户需求和功能需求—也包括非功能需求。业务需求( business requirement)反映了组织机构或客户对系统、产品高层次的目标要求，它们在项目视图与范围文档中予以说明。用户需求(user requirement) 文档描述了用户使用产品必须要完成的任务，这在使用实例(use case)文档或方案脚本(scenario)说明中予以说明。功能需求(functional requirement)定义了开发人员必须实现的软件功能，使得用户能完成他们的任务，从而满足了业务需求。所谓特性(feature)是指逻辑上相关 的功能需求的集合，给用户提供处理能力并满足业务需求。</p>
<p>简单来说，需求就是说明你软件将要满足的用户需要，需求是你软件的功能列表，这里的功能可能包括看得见的功能和看不见的功能。同时需要注意实际用户（用户是重要的需求分析参与者，难以想象一个只有开发者而没有用户参与的需求分析，所得出的是什么）可能对需求的理解有误，有时他们甚至不了解活无法向你描述出他的需求，也有时，他会“啰啰嗦嗦”的向你讲一堆不是需求的东西。</p>
<p>同时，需求还包括非功能的部分，例如，“单次搜索查询必须在0.1秒内完成”、“用户传输文件的速度不应低于其网络最高可用带宽的50%”，这些内容并非软件的功能性要求，但是实际上是软件的使用者使用软件体验、感受的重要感受点甚至是其是否能完成功能性需求的制约。</p>
<h2>3、我没有马王爷的第三只眼&#8211;那么我如何分析需求呢</h2>
<p>哦，这很麻烦，是的，好吧，我们退一步，作为开发人员，你可以让你的产品经理去和客户打交道，但是你必须和你的产品经理打交道，同时，你还必须和你的代码打交道。</p>
<p>与产品经理打交道和与代码打交道是两码事，八杆子打不到一块，你不能和产品经理讲if(xxx)  {} ，也不能去问你的代码，这里是让用户操作的，还是你丫自动操作的。</p>
<p>在与产品人员打交道时，你有责任用他们的语言来描述问题，这并不是单纯为了对方能够听懂你说什么，更重要的是，这会大大减少你们在交流沟通中的误解。所以，熟知你所在的行业，熟悉他们的业务，如果你要开发财务系统，请去阅读财会相关书籍，如果你要开发ERP系统，请去和工人师傅、基层管理人员多聊聊，在拓展你领域的同时，也会让你对你的编程思想有新的看法。</p>
<p>在与代码打交道的时候，你需要是一个好的建筑师，你应当构建严谨、运行健壮、可扩展性强的代码，这要求你在充分理解需求的情况下，看到需求的发展方向以及需求中可能发生变动的情况，甚至你需要和产品经理、客户去沟通，提出你的想法，当你问道“我觉得这里这样做的话，系统可能存在不稳定的因素，如果怎么怎么样做，不仅系统稳定了，您的操作也会更方便”，客户恍然大悟，你又减轻了工作量，何乐不为呢。</p>
<p>在理解需求、分析系统时，我建议你首先这样做：</p>
<p><strong>将系统中存在的活动者都列出来，然后依次列出他们的操作功能和反应。</strong></p>
<p>比如，一个简单的文章系统，我们可能这样去描述它</p>
<div style="background:#EEE">普通用户：注册、登录、找回密码、修改个人信息、查看类别、查看文章、查看某个类别下的文章、输入关键字搜索文章、发表评论、当别人发表对自己评论的回复时收到邮件。<br />
管理员：查看用户信息、CURD（Create-Update-Read-Delete）类别、CURD文章</div>
<p>在上面的需求描述中，涉及了两个活动者，分别是“普通用户”和“管理员”，同时两个活动者都有若干功能，其中“普通用户”的“当别人发表对自己评论的回复时收到邮件”实际上不是用户的主动操作，而是用户对某个操作的反应，需要注意的是，这样的信息也需要在需求分析中体现。</p>
<p>需求分析可以体现为UML用例图，其好处是更直观，同时由于是统一化的表达，更有助于沟通，其他程序员可以更方便的理解你的意思，而不容易出现理解误差。</p>
<p>关于UML用例图方面的内容，可以到http://hi.baidu.com/jyangstu/blog/item/5d2f89131ef270c6c3fd7833.html查看一份简介。</p>
<p>我的需求方法实际上是用例图的一个超级简版，这个方法不能体现活动者与活动者、用例与用例（就是活动者所做的那些事情）之间的关系，一般适用于小型项目或大中型项目的模块级需求分析，对大中型项目的整体需求分析，实际上是一个非常复杂、有机结合的多个过程的系统，以后有机会我们再探讨。</p>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/web-server/php-project-development-3" title="听小韩聊PHP项目开发(3)–切分你的系统">听小韩聊PHP项目开发(3)–切分你的系统</a></li><li><a href="http://www.hanguofeng.cn/archives/web-server/php-project-development-1" title="听小韩聊PHP项目开发(1)&#8211;开题的话">听小韩聊PHP项目开发(1)&#8211;开题的话</a></li><li><a href="http://www.hanguofeng.cn/archives/security/configure-fast-in-lamp-on-windows-with-xampp" title="Windows下AMP平台配置FastCGI方法（以xampp为基础）">Windows下AMP平台配置FastCGI方法（以xampp为基础）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/web-server/php-project-development-2/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<series:name><![CDATA[听小韩聊PHP项目开发]]></series:name>
	</item>
		<item>
		<title>听小韩聊PHP项目开发(1)&#8211;开题的话</title>
		<link>http://www.hanguofeng.cn/archives/web-server/php-project-development-1?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=php-project-development-1</link>
		<comments>http://www.hanguofeng.cn/archives/web-server/php-project-development-1#comments</comments>
		<pubDate>Sun, 28 Dec 2008 13:30:12 +0000</pubDate>
		<dc:creator>hanguofeng</dc:creator>
				<category><![CDATA[Web服务器端技术]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[听小韩聊PHP项目开发]]></category>

		<guid isPermaLink="false">http://www.hanguofeng.cn/?p=88</guid>
		<description><![CDATA[PHP是一个轻盈的、快捷的和强大的网站程序解决方案，它良好的完成了分析请求并对服务器资源进行调用的工作。 PHP是目前网上最流行的Web开发语言之一，据TIBOE的世界编程语言统计来看，从2001年到2008年，PHP的排行最低为10名，人数比例为1.37%，最高为第4名，比例为11.45%，你可以点击这里链接来查看此信息。 同时，PHP也在快速的发展中，从最早期的处理表单的CGI程序，逐渐增加特性，它已经成长为一个完善的面向对象的编程语言，同时内置和扩展库提供了大量的使用函数集，你可以使用这些函数集完成大量的常见工作。PHP有基本完善的面向对象语法，你可以使用大部分面向对象的概念，来实现各种设计模式和代码组织，以帮助你完成大型项目。 基于这样一些原因，在一段时间之前，我开始尝试使用PHP进行Web开发，然而最早开发的不是常见的网站，而是B/S的应用程序，继而又开发了一些网站，在这个过程中，我尝试了各种框架，也学着去评估效率，可维护性和可扩展性等多个因素，并予以实现在各个项目中。 我在进行PHP项目的开发中，逐渐总结了一些心得，包括PHP语言本身，但更多的是在项目中来看待PHP的开发，项目开发是一个很有趣的事情，在此，我们不仅要考虑功能的实现，还要考虑更多的诸如可扩展性、健壮性、与团队的合作等事情，这些经验会逐步和你们探讨和交流，这个专题正是基于此而撰写的。 这个专题，我的计划是总体由浅入深，而在具体的文章排序上不拘泥于顺序，而更像我的笔记，连载长度和时间也没有约束，所以建议您能够订阅我的RSS来获得最近的更新。 韩国峰 2008-12-28 相关内容听小韩聊PHP项目开发(3)–切分你的系统听小韩聊PHP项目开发(2)&#8211;观察你的项目Windows下AMP平台配置FastCGI方法（以xampp为基础）]]></description>
			<content:encoded><![CDATA[<p>PHP是一个轻盈的、快捷的和强大的网站程序解决方案，它良好的完成了分析请求并对服务器资源进行调用的工作。</p>
<p>PHP是目前网上最流行的Web开发语言之一，据TIBOE的世界编程语言统计来看，从2001年到2008年，PHP的排行最低为10名，人数比例为1.37%，最高为第4名，比例为11.45%，你可以<a href="http://www.tiobe.com/index.php/paperinfo/tpci/PHP.html" target="_blank">点击这里</a>链接来查看此信息。</p>
<p>同时，PHP也在快速的发展中，从最早期的处理表单的CGI程序，逐渐增加特性，它已经成长为一个完善的面向对象的编程语言，同时内置和扩展库提供了大量的使用函数集，你可以使用这些函数集完成大量的常见工作。PHP有基本完善的面向对象语法，你可以使用大部分面向对象的概念，来实现各种设计模式和代码组织，以帮助你完成大型项目。</p>
<p>基于这样一些原因，在一段时间之前，我开始尝试使用PHP进行Web开发，然而最早开发的不是常见的网站，而是B/S的应用程序，继而又开发了一些网站，在这个过程中，我尝试了各种框架，也学着去评估效率，可维护性和可扩展性等多个因素，并予以实现在各个项目中。</p>
<p>我在进行PHP项目的开发中，逐渐总结了一些心得，包括PHP语言本身，但更多的是在项目中来看待PHP的开发，项目开发是一个很有趣的事情，在此，我们不仅要考虑功能的实现，还要考虑更多的诸如可扩展性、健壮性、与团队的合作等事情，这些经验会逐步和你们探讨和交流，这个专题正是基于此而撰写的。</p>
<p>这个专题，我的计划是总体由浅入深，而在具体的文章排序上不拘泥于顺序，而更像我的笔记，连载长度和时间也没有约束，所以建议您能够订阅我的RSS来获得最近的更新。</p>
<p style="text-align: right;">韩国峰<br />
2008-12-28</p>
<h3  class="related_post_title">相关内容</h3><ul class="related_post"><li><a href="http://www.hanguofeng.cn/archives/web-server/php-project-development-3" title="听小韩聊PHP项目开发(3)–切分你的系统">听小韩聊PHP项目开发(3)–切分你的系统</a></li><li><a href="http://www.hanguofeng.cn/archives/web-server/php-project-development-2" title="听小韩聊PHP项目开发(2)&#8211;观察你的项目">听小韩聊PHP项目开发(2)&#8211;观察你的项目</a></li><li><a href="http://www.hanguofeng.cn/archives/security/configure-fast-in-lamp-on-windows-with-xampp" title="Windows下AMP平台配置FastCGI方法（以xampp为基础）">Windows下AMP平台配置FastCGI方法（以xampp为基础）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.hanguofeng.cn/archives/web-server/php-project-development-1/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<series:name><![CDATA[听小韩聊PHP项目开发]]></series:name>
	</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->