<?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>奋斗足迹&#124;崔玉松 &#187; Programming</title>
	<atom:link href="http://fendou.org/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://fendou.org</link>
	<description>为家人，为自己，为生活~~</description>
	<lastBuildDate>Wed, 18 Aug 2010 14:34:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>超级简单Python Socket Server一例</title>
		<link>http://fendou.org/2010/08/05/python-socket-server-simple-example/</link>
		<comments>http://fendou.org/2010/08/05/python-socket-server-simple-example/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 05:23:56 +0000</pubDate>
		<dc:creator>崔玉松</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://fendou.org/?p=711</guid>
		<description><![CDATA[中午，公司太吵，闲着无聊，用python自己跟自己说话，算是YY吧，hoho server端代码： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # -*- coding: utf-8 -*- from socket import * import sys, time, encodings &#160; if __name__ == '__main__': if len&#40;sys.argv&#41; &#60; 2: print u'请输入端口号' else: sockobj = socket&#40;AF_INET, SOCK_STREAM&#41; sockobj.bind&#40; &#40;'', [...]]]></description>
			<content:encoded><![CDATA[<p>中午，公司太吵，闲着无聊，用python自己跟自己说话，算是YY吧，hoho</p>
<p>server端代码：</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
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span> 
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">time</span>, <span style="color: #dc143c;">encodings</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">2</span>:
		<span style="color: #ff7700;font-weight:bold;">print</span> u<span style="color: #483d8b;">'请输入端口号'</span>
	<span style="color: #ff7700;font-weight:bold;">else</span>:
		sockobj = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
		sockobj.<span style="color: black;">bind</span><span style="color: black;">&#40;</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>, <span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
		sockobj.<span style="color: black;">listen</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
			connection,address = sockobj.<span style="color: black;">accept</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
			rcvd = connection.<span style="color: black;">recv</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> rcvd :
				<span style="color: #ff7700;font-weight:bold;">pass</span>
			<span style="color: #ff7700;font-weight:bold;">else</span>:
				<span style="color: #ff7700;font-weight:bold;">print</span> u<span style="color: #483d8b;">'收到:'</span>, rcvd.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'utf-8'</span><span style="color: black;">&#41;</span>.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'gb2312'</span><span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">print</span> u<span style="color: #483d8b;">'发送：能'</span>
				connection.<span style="color: black;">send</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;能&quot;</span><span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">break</span>
			connection.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Client端代码:</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
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#coding: utf-8</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">socket</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span> 
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
	sockobj = <span style="color: #dc143c;">socket</span><span style="color: black;">&#40;</span>AF_INET, SOCK_STREAM<span style="color: black;">&#41;</span>
	sockobj.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'localhost'</span>, <span style="color: #ff4500;">2828</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
	send_info = <span style="color: #483d8b;">&quot;能收到信息吗？&quot;</span>
	<span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">print</span> u<span style="color: #483d8b;">&quot;发送:&quot;</span>, send_info.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;gbk&quot;</span><span style="color: black;">&#41;</span>
	sockobj.<span style="color: black;">send</span><span style="color: black;">&#40;</span>send_info<span style="color: black;">&#41;</span>
	rcvd = sockobj.<span style="color: black;">recv</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1024</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">print</span> u<span style="color: #483d8b;">&quot;收到：&quot;</span>, rcvd.<span style="color: black;">decode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'utf-8'</span><span style="color: black;">&#41;</span>.<span style="color: black;">encode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'gb2312'</span><span style="color: black;">&#41;</span>
	sockobj.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">print</span> u<span style="color: #483d8b;">&quot;完成&quot;</span></pre></td></tr></table></div>

<p><img class="alignnone" src="http://pic.yupoo.com/cuimuxi/003709bdc0a2/medium.jpg" alt="" width="500" height="89" /></p>
<p>特别说明一下，我是在Windows下面搞的，CMD默认只能显示GBK编码，所以在print的时候转来转去，如果在Linux终端，直接显示就行了<br />
<h3>相关文章</h3>
<ul class="related_post">
<li>2010年06月20日 &#8212; <a href="http://fendou.org/2010/06/20/django-1-2-1-csrf-verification-failed-request-aborted/" title="Django 1.2.1  CSRF verification failed. Request aborted.">Django 1.2.1  CSRF verification failed. Request aborted.</a></li>
<li>2010年06月17日 &#8212; <a href="http://fendou.org/2010/06/17/install-python26-mysql-python-on-windows/" title="Windows平台安装Python2.6 和 MySQL-Python">Windows平台安装Python2.6 和 MySQL-Python</a></li>
<li>2010年03月5日 &#8212; <a href="http://fendou.org/2010/03/05/django-settings-cannot-be-imported/" title="django Settings cannot be imported 错误解决">django Settings cannot be imported 错误解决</a></li>
<li>2009年12月15日 &#8212; <a href="http://fendou.org/2009/12/15/google-appengine-launcher-problem/" title="Google AppEngine Launcher不能启动的解决方法">Google AppEngine Launcher不能启动的解决方法</a></li>
<li>2009年03月30日 &#8212; <a href="http://fendou.org/2009/03/30/install-mod-wsgi-in-linux-two/" title="在Linux上安装mod_wsgi文档中文翻译（二）">在Linux上安装mod_wsgi文档中文翻译（二）</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://fendou.org/2010/08/05/python-socket-server-simple-example/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Django 1.2.1  CSRF verification failed. Request aborted.</title>
		<link>http://fendou.org/2010/06/20/django-1-2-1-csrf-verification-failed-request-aborted/</link>
		<comments>http://fendou.org/2010/06/20/django-1-2-1-csrf-verification-failed-request-aborted/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 16:24:14 +0000</pubDate>
		<dc:creator>崔玉松</dc:creator>
				<category><![CDATA[Excellence Article]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://fendou.org/?p=704</guid>
		<description><![CDATA[I was getting this 403 error today while attempting to make a POST request to a view: 403 Forbidden CSRF verification failed. Request aborted. Help Reason given for failure: CSRF cookie not set. Hopefully this saves you some time because I sure wasted a lot of mine solving it.  I ended up having to add [...]]]></description>
			<content:encoded><![CDATA[<p>I was getting this 403 error today while attempting to make a POST request to a view:<br />
<code>403 Forbidden</code></p>
<p><code>CSRF verification failed. Request aborted.<br />
Help</code></p>
<p><code>Reason given for failure:</code></p>
<p><code>CSRF cookie not set.<br />
</code><br />
Hopefully this saves you some time because I sure wasted a lot of mine solving it.  I ended up having to add ‘django.middleware.csrf.CsrfViewMiddleware’, and  ‘django.middleware.csrf.CsrfResponseMiddleware’ to my MIDDLEWARE_CLASSES in settings.py and my problems were solved.  All I had to say was mutha eff.  Django also was no help with their debug.  My MIDDLEWARE_CLASSES now looks like:</p>
<p><code>MIDDLEWARE_CLASSES = (<br />
'django.middleware.common.CommonMiddleware',<br />
'django.contrib.sessions.middleware.SessionMiddleware',<br />
<span style="color: #ff0000;">'django.middleware.csrf.CsrfViewMiddleware',<br />
'django.middleware.csrf.CsrfResponseMiddleware',</span><br />
'django.contrib.auth.middleware.AuthenticationMiddleware',<br />
'django.contrib.messages.middleware.MessageMiddleware',<br />
)</code></p>
<p>Hope this helps.<br />
<h3>相关文章</h3>
<ul class="related_post">
<li>2010年08月5日 &#8212; <a href="http://fendou.org/2010/08/05/python-socket-server-simple-example/" title="超级简单Python Socket Server一例">超级简单Python Socket Server一例</a></li>
<li>2010年06月17日 &#8212; <a href="http://fendou.org/2010/06/17/install-python26-mysql-python-on-windows/" title="Windows平台安装Python2.6 和 MySQL-Python">Windows平台安装Python2.6 和 MySQL-Python</a></li>
<li>2010年03月5日 &#8212; <a href="http://fendou.org/2010/03/05/django-settings-cannot-be-imported/" title="django Settings cannot be imported 错误解决">django Settings cannot be imported 错误解决</a></li>
<li>2009年12月15日 &#8212; <a href="http://fendou.org/2009/12/15/google-appengine-launcher-problem/" title="Google AppEngine Launcher不能启动的解决方法">Google AppEngine Launcher不能启动的解决方法</a></li>
<li>2009年03月30日 &#8212; <a href="http://fendou.org/2009/03/30/install-mod-wsgi-in-linux-two/" title="在Linux上安装mod_wsgi文档中文翻译（二）">在Linux上安装mod_wsgi文档中文翻译（二）</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://fendou.org/2010/06/20/django-1-2-1-csrf-verification-failed-request-aborted/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Windows平台安装Python2.6 和 MySQL-Python</title>
		<link>http://fendou.org/2010/06/17/install-python26-mysql-python-on-windows/</link>
		<comments>http://fendou.org/2010/06/17/install-python26-mysql-python-on-windows/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 08:32:45 +0000</pubDate>
		<dc:creator>崔玉松</dc:creator>
				<category><![CDATA[Excellence Article]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://fendou.org/?p=700</guid>
		<description><![CDATA[Python 版本：2.6 下载地址：http://www.python.org/download/releases/2.6.1/ 下载msi文件并安装 MySQLdb版本： MySQL-python-1.2.2.win32-py2.6.exe 下载地址：http://home.netimperia.com/files/misc/MySQL-python-1.2.2.win32-py2.6.exe 参见：http://sourceforge.net/forum/forum.php?thread_id=2316047&#38;forum_id=70460 常见问题： 1.ImportError: DLL load failed: 找不到指定的模块。 —————————————————————————————————- D:\Program Files\Python2.6&#62;python Python 2.6.1 (r261:67517, Dec  4 2008, 16:51:00) [MSC v.1500 32 bit (Intel)] on win32 Type “help”, “copyright”, “credits” or “license” for more information. &#62;&#62;&#62; import MySQLdb Traceback (most recent call last): File “&#60;stdin&#62;”, line 1, in &#60;module&#62; File [...]]]></description>
			<content:encoded><![CDATA[<p>Python 版本：2.6<br />
下载地址：<a href="http://www.python.org/download/releases/2.6.1/">http://www.python.org/download/releases/2.6.1/</a><br />
下载msi文件并安装</p>
<p>MySQLdb版本： MySQL-python-1.2.2.win32-py2.6.exe<br />
下载地址：<a href="http://home.netimperia.com/files/misc/MySQL-python-1.2.2.win32-py2.6.exe">http://home.netimperia.com/files/misc/MySQL-python-1.2.2.win32-py2.6.exe</a><br />
参见：<a href="http://sourceforge.net/forum/forum.php?thread_id=2316047&amp;forum_id=70460">http://sourceforge.net/forum/forum.php?thread_id=2316047&amp;forum_id=70460</a></p>
<blockquote><p>常见问题：<br />
1.ImportError: DLL load failed: 找不到指定的模块。<br />
—————————————————————————————————-<br />
D:\Program Files\Python2.6&gt;python<br />
Python 2.6.1 (r261:67517, Dec  4 2008, 16:51:00) [MSC v.1500 32 bit (Intel)] on win32<br />
Type “help”, “copyright”, “credits” or “license” for more information.<br />
&gt;&gt;&gt; import MySQLdb<br />
Traceback (most recent call last):<br />
File “&lt;stdin&gt;”, line 1, in &lt;module&gt;<br />
File “D:\Program Files\Python2.6\Lib\site-packages\MySQLdb\__init__.py”, line 19, in &lt;module&gt;</p>
<p>import _mysql<br />
ImportError: DLL load failed: 找不到指定的模块。<br />
—————————————————————————————————-<br />
解决方法：下载libmmd.dll(附件)和libguide40.dll(附件)两个dll文件并复制到python安装目录的Lib\site-packages下。<br />
参见：<a href="http://sourceforge.net/forum/message.php?msg_id=5613887">http://sourceforge.net/forum/message.php?msg_id=5613887</a></p></blockquote>
<p>2.ImportError: DLL load failed: 找不到指定的模块。<br />
—————————————————————————————————-<br />
D:\Program Files\Python2.6&gt;python<br />
Python 2.6 (r26:66721, Oct  2 2008, 11:35:03) [MSC v.1500 32 bit (Intel)] on win32<br />
Type “help”, “copyright”, “credits” or “license” for more information.<br />
&gt;&gt;&gt; import MySQLdb<br />
D:\Program Files\Python2.6\lib\site-packages\MySQLdb\__init__.py:34: DeprecationWarning: the sets module is deprecated<br />
from sets import ImmutableSet<br />
—————————————————————————————————-<br />
解决方法：<br />
1) file “__init__”, replace:</p>
<p>from sets import ImmutableSet<br />
class DBAPISet(ImmutableSet):</p>
<p>with</p>
<p>class DBAPISet(frozenset)</p>
<p>2) file “converters.py”, remove:</p>
<p>from sets import BaseSet, Set</p>
<p>3) file “converters.py”, change “Set” by “set” (IMPORTANT: only two places):</p>
<p>line 45: return set([ i for i in s.split(',') if i ])<br />
line 128: set: Set2Str,<br />
参见：<a href="http://sourceforge.net/forum/message.php?msg_id=5808948">http://sourceforge.net/forum/message.php?msg_id=5808948</a></p>
<p>附件:<br />
<a href="http://www.3gmatrix.cn/batch.download.php?aid=13881" target="_blank">libguide40.dll.zip(77.3 KB)</a><br />
<a href="http://www.3gmatrix.cn/batch.download.php?aid=13882" target="_blank">libmmd.dll.zip(169 KB)</a><br />
<a href="http://www.3gmatrix.cn/batch.download.php?aid=13883" target="_blank">libmySQL.dll.zip(861 KB)</a><br />
原文: <a href="http://www.3gmatrix.cn/4/viewspace-16757.html">http://www.3gmatrix.cn/4/viewspace-16757.html</a><br />
<h3>相关文章</h3>
<ul class="related_post">
<li>2010年08月5日 &#8212; <a href="http://fendou.org/2010/08/05/python-socket-server-simple-example/" title="超级简单Python Socket Server一例">超级简单Python Socket Server一例</a></li>
<li>2010年06月20日 &#8212; <a href="http://fendou.org/2010/06/20/django-1-2-1-csrf-verification-failed-request-aborted/" title="Django 1.2.1  CSRF verification failed. Request aborted.">Django 1.2.1  CSRF verification failed. Request aborted.</a></li>
<li>2010年03月5日 &#8212; <a href="http://fendou.org/2010/03/05/django-settings-cannot-be-imported/" title="django Settings cannot be imported 错误解决">django Settings cannot be imported 错误解决</a></li>
<li>2009年12月15日 &#8212; <a href="http://fendou.org/2009/12/15/google-appengine-launcher-problem/" title="Google AppEngine Launcher不能启动的解决方法">Google AppEngine Launcher不能启动的解决方法</a></li>
<li>2009年03月30日 &#8212; <a href="http://fendou.org/2009/03/30/install-mod-wsgi-in-linux-two/" title="在Linux上安装mod_wsgi文档中文翻译（二）">在Linux上安装mod_wsgi文档中文翻译（二）</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://fendou.org/2010/06/17/install-python26-mysql-python-on-windows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>类设计</title>
		<link>http://fendou.org/2010/04/18/class-design/</link>
		<comments>http://fendou.org/2010/04/18/class-design/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 13:30:49 +0000</pubDate>
		<dc:creator>崔玉松</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PhpWind]]></category>
		<category><![CDATA[编程技术]]></category>

		<guid isPermaLink="false">http://fendou.org/?p=680</guid>
		<description><![CDATA[最近几乎天天加班，周末依然加班，好久没有更新博客了，非常累。不过此累非彼类。 在现有的很多面向过程开发的代码中，对我这个涉世不深的玩家来说，简直就是灾难，或许很多代码连面向过程都算不上，连函数都没有包装。一个函数可能会超过500行代码，语义不名，名称更不名。我曾经试图改造这些代码，并非技术上不可行，而是实现需要太多的时间，一个不可能完成的任务。 让一个缺乏面向对象的团队掌握面向对象很困难的，也许是我智商低，当年我花了两个月才能意会什么是对象，什么是面向对象编程，到现在也不会言传。 如果不能转向到面向对象，那么我们先转成类吧，或许技术上更能解决一点。类的最基本功能就是封装，如果我们撇去面向对象的东西，那么类就是把具有相似性的东西做一个集合，外部在使用这些功能的时候不需要知道具体实现，只要给类中的方法确需要的参数值，如果非要理解成一堆具有相似属性函数的集合，那也是可以的，毕竟这个比一个文件中的几千行代码，连个function都没有的代码好得多。 如果我们想得到更好的类，需要遵循一些基本的原则， 其中之一就是类应该短小，短小并不是说不完整，这和很多人学C的时候，老师告诉我们，函数要尽可能短小一样，到底多短小的类算是合适呢？我觉得根本无法用代码行数来描述，这取决于这个类所完成的功能，比如你要封装一个操作文章的类，那么至少需要，增删改查四个函数，也许还有基于这四个函数的别名和封装，以及必要的公共属性。 第二个重要原则就是单一权责（SRP），这个原则要做到非常 不容易，因为比第一条更难衡量，一般认为，衡量单一权责的标准是：类或者模块应该有且只有一条加以修改的理由。SRP实际上能给出控制类长度的指导方针。简单的理解就是一个类只有一个功能，假如你修改博客标题或者设置的时候，都要改动文章类，显然违背了单一权责的原则。 第三个原则&#8211;内聚。类应该只有少量实体变量。类中的每个方法都应该操作一个或者多个这种变量。通常而言，方法操作的变量越多，就越内聚到类上，如果一个类中的米一个变量都被每个方法所使用，则该类具有最大的内聚性。通常，创建一个这样极大化的内聚类是非常不容易的，也是不可取的，因为类的内聚性过高也就意味着类中的方法和变量相互依赖，互相结合成一个逻辑的整体，当修改类中的变量或者方法时，可能影响或者需要修改其他的方法或者属性。一般认为，类的内聚应该保持在较高的位置，但不是最高的位置，这样有利于降低维护成本。 前面提到在我目前的项目中，我碰到很多超过500行代码的函数，假如把数字降低到300，那么符合标准的函数将会增加十倍以上，在一个面向对象的团队中，一个单纯函数或者方法超过100行几乎都是不可接受的，因为这意味着这个函数可能包含过多的权责。其实我们如果真的遵循类的内聚和单一权责的原则，就会导致很多短小的类的产生。 一般程序员在拆解过大的函数的时候实际上就是将原来的代码复制出来，放到新建的函数中去，然后把需要的参数传递过去，实际上导致超大函数的产生的动机常常是因为有很多变量在这个函数的中被使用到，看似这个函数似乎是一个整体，因为拆分会导致新建的函数参数很多。为啥他们不想用一下类呢，假如拆解函数导致需要传递很多的参数，那么这个函数其实就是一个类，需要传递的函数需要提升为实体变量，这样就可以将函数拆成很小的小块，这样看起来似乎丧失了内聚性，因为堆积了越来越多的只为允许少量函数共享而存在的实体变量。如果这些函数想要公司向某些变量，为什么不让它拥有自己的类呢？当类丧失了内聚性，就应该拆了它。所以，将大的函数拆分为小函数，旺旺也是将类拆分为多个小类的时机，程序会更加有组织，更为透明的结构。 实际上很多时候，当你完成所有的功能的时候，产品经理会跑过来跟你说，我们不能把这个功能改成这样，这样用户体验更好，很可能你需要改动很多的代码很逻辑，甚至数据结构，所以如果我们能在设计的类的时候，注意一下可能的需求改动，我们可以借助接口或者抽象类来隔离修改细节对原来代码产生的破坏性更改。 相关文章 2009年11月16日 &#8212; 会话状态模式 2010年08月18日 &#8212; 代码调优法则&#8211;编程珠玑笔记 2010年01月18日 &#8212; 程序语言评估标准 2010年01月13日 &#8212; 软件构建中的理想设计特征 2009年12月14日 &#8212; 找人，招人~~]]></description>
			<content:encoded><![CDATA[<p>最近几乎天天加班，周末依然加班，好久没有更新博客了，非常累。不过此累非彼类。</p>
<p>在现有的很多面向过程开发的代码中，对我这个涉世不深的玩家来说，简直就是灾难，或许很多代码连面向过程都算不上，连函数都没有包装。一个函数可能会超过500行代码，语义不名，名称更不名。我曾经试图改造这些代码，并非技术上不可行，而是实现需要太多的时间，一个不可能完成的任务。</p>
<p>让一个缺乏面向对象的团队掌握面向对象很困难的，也许是我智商低，当年我花了两个月才能意会什么是对象，什么是面向对象编程，到现在也不会言传。</p>
<p>如果不能转向到面向对象，那么我们先转成类吧，或许技术上更能解决一点。类的最基本功能就是封装，如果我们撇去面向对象的东西，那么类就是把具有相似性的东西做一个集合，外部在使用这些功能的时候不需要知道具体实现，只要给类中的方法确需要的参数值，如果非要理解成一堆具有相似属性函数的集合，那也是可以的，毕竟这个比一个文件中的几千行代码，连个function都没有的代码好得多。</p>
<p>如果我们想得到更好的类，需要遵循一些基本的原则， 其中之一就是类应该短小，短小并不是说不完整，这和很多人学C的时候，老师告诉我们，函数要尽可能短小一样，到底多短小的类算是合适呢？我觉得根本无法用代码行数来描述，这取决于这个类所完成的功能，比如你要封装一个操作文章的类，那么至少需要，增删改查四个函数，也许还有基于这四个函数的别名和封装，以及必要的公共属性。</p>
<p>第二个重要原则就是单一权责（SRP），这个原则要做到非常 不容易，因为比第一条更难衡量，一般认为，衡量单一权责的标准是：类或者模块应该有且只有一条加以修改的理由。SRP实际上能给出控制类长度的指导方针。简单的理解就是一个类只有一个功能，假如你修改博客标题或者设置的时候，都要改动文章类，显然违背了单一权责的原则。</p>
<p>第三个原则&#8211;内聚。类应该只有少量实体变量。类中的每个方法都应该操作一个或者多个这种变量。通常而言，方法操作的变量越多，就越内聚到类上，如果一个类中的米一个变量都被每个方法所使用，则该类具有最大的内聚性。通常，创建一个这样极大化的内聚类是非常不容易的，也是不可取的，因为类的内聚性过高也就意味着类中的方法和变量相互依赖，互相结合成一个逻辑的整体，当修改类中的变量或者方法时，可能影响或者需要修改其他的方法或者属性。一般认为，类的内聚应该保持在较高的位置，但不是最高的位置，这样有利于降低维护成本。</p>
<p>前面提到在我目前的项目中，我碰到很多超过500行代码的函数，假如把数字降低到300，那么符合标准的函数将会增加十倍以上，在一个面向对象的团队中，一个单纯函数或者方法超过100行几乎都是不可接受的，因为这意味着这个函数可能包含过多的权责。其实我们如果真的遵循类的内聚和单一权责的原则，就会导致很多短小的类的产生。</p>
<p>一般程序员在拆解过大的函数的时候实际上就是将原来的代码复制出来，放到新建的函数中去，然后把需要的参数传递过去，实际上导致超大函数的产生的动机常常是因为有很多变量在这个函数的中被使用到，看似这个函数似乎是一个整体，因为拆分会导致新建的函数参数很多。为啥他们不想用一下类呢，假如拆解函数导致需要传递很多的参数，那么这个函数其实就是一个类，需要传递的函数需要提升为实体变量，这样就可以将函数拆成很小的小块，这样看起来似乎丧失了内聚性，因为堆积了越来越多的只为允许少量函数共享而存在的实体变量。如果这些函数想要公司向某些变量，为什么不让它拥有自己的类呢？当类丧失了内聚性，就应该拆了它。所以，将大的函数拆分为小函数，旺旺也是将类拆分为多个小类的时机，程序会更加有组织，更为透明的结构。</p>
<p>实际上很多时候，当你完成所有的功能的时候，产品经理会跑过来跟你说，我们不能把这个功能改成这样，这样用户体验更好，很可能你需要改动很多的代码很逻辑，甚至数据结构，所以如果我们能在设计的类的时候，注意一下可能的需求改动，我们可以借助接口或者抽象类来隔离修改细节对原来代码产生的破坏性更改。<br />
<h3>相关文章</h3>
<ul class="related_post">
<li>2009年11月16日 &#8212; <a href="http://fendou.org/2009/11/16/%e4%bc%9a%e8%af%9d%e7%8a%b6%e6%80%81%e6%a8%a1%e5%bc%8f/" title="会话状态模式">会话状态模式</a></li>
<li>2010年08月18日 &#8212; <a href="http://fendou.org/2010/08/18/programming-pearls/" title="代码调优法则&#8211;编程珠玑笔记">代码调优法则&#8211;编程珠玑笔记</a></li>
<li>2010年01月18日 &#8212; <a href="http://fendou.org/2010/01/18/programming-language-baseline/" title="程序语言评估标准">程序语言评估标准</a></li>
<li>2010年01月13日 &#8212; <a href="http://fendou.org/2010/01/13/desireable-characteristics-design/" title="软件构建中的理想设计特征">软件构建中的理想设计特征</a></li>
<li>2009年12月14日 &#8212; <a href="http://fendou.org/2009/12/14/recruit/" title="找人，招人~~">找人，招人~~</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://fendou.org/2010/04/18/class-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>django Settings cannot be imported 错误解决</title>
		<link>http://fendou.org/2010/03/05/django-settings-cannot-be-imported/</link>
		<comments>http://fendou.org/2010/03/05/django-settings-cannot-be-imported/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 05:58:05 +0000</pubDate>
		<dc:creator>崔玉松</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://fendou.org/?p=658</guid>
		<description><![CDATA[在命令行中直接敲入Python命令进入交互模式，然后使用 from django.template import  Template ,Context t  = Template(&#8220;Test is {{test}}&#8221;) 会导致：ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.原因是django的配置信息没有初始化 有两种解决方法， 一种是切换到你项目或者APP所在的目录使用manage.py shell命令启动交互窗口 还有一种是手动将django的配置初始化： &#62;&#62;&#62; from django.conf import settings &#62;&#62;&#62; settings.configure() 相关文章 2010年08月5日 &#8212; 超级简单Python Socket Server一例 2010年06月20日 &#8212; Django 1.2.1 CSRF verification failed. Request aborted. 2010年06月17日 &#8212; Windows平台安装Python2.6 和 MySQL-Python 2010年05月13日 &#8212; [...]]]></description>
			<content:encoded><![CDATA[<p>在命令行中直接敲入Python命令进入交互模式，然后使用</p>
<blockquote><p>from django.template import  Template ,Context<br />
t  = Template(&#8220;Test is {{test}}&#8221;)</p>
</blockquote>
<p>会导致：I<strong>mportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.</strong>原因是django的配置信息没有初始化<br />
有两种解决方法，</p>
<p>一种是切换到你项目或者APP所在的目录使用manage.py shell命令启动交互窗口</p>
<p>还有一种是手动将django的配置初始化：</p>
<blockquote><p>&gt;&gt;&gt; <strong><span style="color: #ff0000;">from django.conf import settings<br />
&gt;&gt;&gt; settings.configure()<br />
</span></strong></p>
</blockquote>
<h3>相关文章</h3>
<ul class="related_post">
<li>2010年08月5日 &#8212; <a href="http://fendou.org/2010/08/05/python-socket-server-simple-example/" title="超级简单Python Socket Server一例">超级简单Python Socket Server一例</a></li>
<li>2010年06月20日 &#8212; <a href="http://fendou.org/2010/06/20/django-1-2-1-csrf-verification-failed-request-aborted/" title="Django 1.2.1  CSRF verification failed. Request aborted.">Django 1.2.1  CSRF verification failed. Request aborted.</a></li>
<li>2010年06月17日 &#8212; <a href="http://fendou.org/2010/06/17/install-python26-mysql-python-on-windows/" title="Windows平台安装Python2.6 和 MySQL-Python">Windows平台安装Python2.6 和 MySQL-Python</a></li>
<li>2010年05月13日 &#8212; <a href="http://fendou.org/2010/05/13/google-app-engine-colloction/" title="Google App Engine项目收集">Google App Engine项目收集</a></li>
<li>2009年12月15日 &#8212; <a href="http://fendou.org/2009/12/15/google-appengine-launcher-problem/" title="Google AppEngine Launcher不能启动的解决方法">Google AppEngine Launcher不能启动的解决方法</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://fendou.org/2010/03/05/django-settings-cannot-be-imported/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
