PHP 編程標(biāo)準(zhǔn)(English version)最后修改日期: 2000-11-16
目錄
介紹標(biāo)準(zhǔn)化的重要性標(biāo)準(zhǔn)化問題在某些方面上讓每個人頭痛,讓人人都覺得大家處于同樣的境地。這有助于讓這些建議在許多的項(xiàng)目中不斷演進(jìn),許多公司花費(fèi)了許多星期逐子字逐句的進(jìn)行爭論。標(biāo)準(zhǔn)化不是特殊 的個人風(fēng)格,它對本地改良是完全開放的。 優(yōu)點(diǎn)當(dāng)一個項(xiàng)目嘗試著遵守公用的標(biāo)準(zhǔn)時,會有以下好處:
缺點(diǎn)現(xiàn)在輪到壞處了:
討論許多項(xiàng)目的經(jīng)驗(yàn)?zāi)艿贸鲞@樣的結(jié)論:采用編程標(biāo)準(zhǔn)可以使項(xiàng)目更加順利地完成。標(biāo)準(zhǔn)是成功的關(guān) 解釋慣例在本文檔中使用“要”字所指的是使用本規(guī)范的所有項(xiàng)目需要遵守規(guī)定的標(biāo)準(zhǔn)。使用“應(yīng)該”一詞的作用是指導(dǎo)項(xiàng)目定制項(xiàng)目細(xì)節(jié)規(guī)范。因?yàn)轫?xiàng)目必須適當(dāng)?shù)陌?(include), 使用“可以”一詞的作用與“應(yīng)該”類似,因?yàn)樗该髁丝蛇x的需求。
標(biāo)準(zhǔn)實(shí)施首先應(yīng)該在開發(fā)小組的內(nèi)部找出所有的最重要的元素,也許標(biāo)準(zhǔn)對你的狀況還不夠恰當(dāng)。它可能已經(jīng)概括了 重要的問題,也可能還有人對其中的某些問題表示強(qiáng)烈的反對。 無論在什么情況下,只要最后順利的話,人們將成熟的明白到這個標(biāo)準(zhǔn)是合理的,然后其他的程序員們 也會發(fā)現(xiàn)它的合理性,并覺得帶著一些保留去遵循這一標(biāo)準(zhǔn)是值得的。 如果沒有自愿的合作,可以制定需求:標(biāo)準(zhǔn)一定要經(jīng)過代碼的檢驗(yàn)。 如果沒有檢驗(yàn)的話,這個解決方案僅僅是一個建立在不精確的基礎(chǔ)上的一大群可笑的人。 認(rèn)同觀點(diǎn)
出結(jié)論的方法就是你必須要能夠接受不同的思想。請您給自己一點(diǎn)時間去做到它。 項(xiàng)目的四個階段命名規(guī)則合適的命名命名是程序規(guī)劃的核心。古人相信只要知道一個人真正的名字就會獲得凌駕于那個人之上的不可思議的力
類命名
方法和函數(shù)命名
縮寫詞不要全部使用大寫字母
理由
例如class FluidOz // 不要寫成 FluidOZ class GetHtmlStatistic // 不要寫成 GetHTMLStatistic
類命名
理由
例如class NameOneTwo class Name
類庫命名
例如John Johnson的數(shù)據(jù)結(jié)構(gòu)類庫可以用Jj做為前綴,如下:class JjLinkList { }
方法命名
理由
例如class NameOneTwo { function DoIt() {}; function HandleError() {}; }
類屬性命名
理由
例如class NameOneTwo { function VarAbc() {}; function ErrorNumber() {};
方法中參數(shù)命名
理由
例如class NameOneTwo { function StartYourEngines( &$rSomeEngine, &$rAnotherEngine); }
變量命名
理由
例如function HandleError($errorNumber) { $error = OsErr(); $time_of_error = OsErr->getTimeOfError; $error_processor = OsErr->getErrorProcessor; }
引用變量和函數(shù)返回引用
理由
例如class Test { var mrStatus;
全局變量
理由
例如global $gLog; global &$grLog;
定義命名 / 全局常量
理由這是命名全局常量的傳統(tǒng)。你要注意不要與其它的定義相沖突。例如
靜態(tài)變量
理由
例如function test()
函數(shù)命名
理由
例如function some_bloody_function() { }
錯誤返回檢測規(guī)則
大括號 {} 規(guī)則在三種主要的大括號放置規(guī)則中,有兩種是可以接受的,如下的第一種是最好的:
理由
縮進(jìn)/制表符/空格 規(guī)則
理由
例如function func() { if (something bad) { if (another thing bad) { while (more input) { } } } }
小括號、關(guān)鍵詞和函數(shù) 規(guī)則
理由
例如if (condition) { } while (condition) { } strcmp($s, $s1); return 1;
RCS關(guān)鍵詞、更改記錄和歷史記錄規(guī)則直接使用RCS關(guān)鍵詞的規(guī)則必須改變,其中包括使用CVS等類似的支持RCS風(fēng)格關(guān)鍵詞的源代碼控制系統(tǒng):
理由
別在對象架構(gòu)期做實(shí)際的工作別在對象架構(gòu)期做真實(shí)的工作,在架構(gòu)期初始化變量和/或做任何不會有失誤的事情。當(dāng)完成對象架構(gòu)時,為該對象建立一個Open()方法,Open()方法應(yīng)該以對象實(shí)體命名。 理由
例如class Device { function Device() { /* initialize and other stuff */ } function Open() { return FAIL; } }; $dev = new Device; if (FAIL == $dev->Open()) exit(1);
If Then Else 格式布局這由程序員決定。不同的花括號樣式會產(chǎn)生些微不同的樣觀。一個通用方式是: if (條件1) // 注釋 { } else if (條件2) // 注釋 { } else // 注釋 { }如果你有用到else if 語句的話,通常最好有一個else塊以用于處理未處理到的其他情況?梢缘脑 放一個記錄信息注釋在else處,即使在else沒有任何的動作。
條件格式總是將恒量放在等號/不等號的左邊,例如:if ( 6 == $errorNum ) ... 一個原因是假如你在等式中漏了一個等號,語法檢查器會為你報(bào)錯。第二個原因是你能立刻找到數(shù)值
switch 格式
例如switch (...) { case 1: ... // FALL THROUGH case 2: { $v = get_week_number(); ... } break; default: }
continue,break 和 ? 的使用:Continue 和 BreakContinue 和 break 其實(shí)是變相的隱蔽的 goto方法。Continue 和 break 像 goto 一樣,它們在代碼中是有魔力的,所以要節(jié)儉(盡可能少)的使用它們。 Continue有兩個主要的問題:
看看下面的例子,考慮一下問題都在哪兒發(fā)生: while (TRUE) { ... // A lot of code ... if (/* some condition */) { continue; } ... // A lot of code ... if ( $i++ > STOP_VALUE) break; }注意:"A lot of code"是必須的,這是為了讓程序員們不能那么容易的找出錯誤。 通過以上的例子,我們可以得出更進(jìn)一步的規(guī)則:continue 和 break 混合使用是引起災(zāi)難的正確方法。
?:麻煩在于人民往往試著在 ? 和 : 之間塞滿了許多的代碼。以下的是一些清晰的連接規(guī)則:
例如(condition) ? funct1() : func2(); or (condition) ? long statement : another long statement;
聲明塊的定位
理由Justification
例如var $mDate var& $mrDate var& $mrName var $mName $mDate = 0; $mrDate = NULL; $mrName = 0; $mName = NULL;
每行一個語句除非這些語句有很密切的聯(lián)系,否則每行只寫一個語句。
短方法
理由
記錄所有的空語句總是記錄下for或者是while的空塊語句,以便清楚的知道該段代碼是漏掉了,還是故意不寫的。while ($dest++ = $src++) ; // VOID
不要采用缺省方法測試非零值不要采用缺省值測試非零值,也就是使用:if (FAIL != f())比下面的方法好: if (f())即使 FAIL 可以含有 0 值 ,也就是PHP認(rèn)為false的表示。在某人決定用-1代替0作為失敗返回值的時候, 一個顯式的測試就可以幫助你了。就算是比較值不會變化也應(yīng)該使用顯式的比較;例如:if (!($bufsize % strlen($str))) 應(yīng)該寫成:if (($bufsize % strlen($str)) == 0)以表示測試的數(shù)值(不是布爾)型。一個經(jīng)常出 問題的地方就是使用strcmp來測試一個字符等式,結(jié)果永遠(yuǎn)也不會等于缺省值。 非零測試采用基于缺省值的做法,那么其他函數(shù)或表達(dá)式就會受到以下的限制:
布爾邏輯類型大部分函數(shù)在FALSE的時候返回0,但是發(fā)揮非0值就代表TRUE,因而不要用1(TRUE,YES,諸如此類)等式檢測一個布爾值,應(yīng)該用0(FALSE,NO,諸如此類)的不等式來代替: if (TRUE == func()) { ...應(yīng)該寫成: if (FALSE != func()) { ...
通常避免嵌入式的賦值有時候在某些地方我們可以看到嵌入式賦值的語句,那些結(jié)構(gòu)不是一個比較好的少冗余,可讀性強(qiáng)的方法。while ($a != ($c = getchar())) { process the character } ++和--操作符類似于賦值語句。因此,出于許多的目的,在使用函數(shù)的時候會產(chǎn)生副作用。使用嵌入式賦值 a = b + c; d = a + r;不要寫成: d = (a = b + c) + r;雖然后者可以節(jié)省一個周期。但在長遠(yuǎn)來看,隨著程序的維護(hù)費(fèi)用漸漸增長,程序的編寫者對代碼漸漸遺忘, 就會減少在成熟期的最優(yōu)化所得。
重用您和其他人的艱苦工作跨工程的重用在沒有一個通用結(jié)構(gòu)的情況下幾乎是不可能的。對象符合他們現(xiàn)有的服務(wù)需求,不同的過程有著不同的服務(wù)需求環(huán)境,這使對象重用變得很困難。 開發(fā)一個通用結(jié)構(gòu)需要預(yù)先花費(fèi)許多的努力來設(shè)計(jì)。當(dāng)努力不成功的時候,無論出于什么原因,有幾種辦法推
請教!給群組發(fā)Email求助這個簡單的方法很少被使用。因?yàn)橛行┏绦騿T們覺得如果他向其他人求助,會顯得自己水平低,這多傻啊!做新的有趣的工作,不要一遍又一遍的做別人已經(jīng)做過的東西。 如果你需要某些事項(xiàng)的源代碼,如果已經(jīng)有某人做過的話,就向群組發(fā)email求助。結(jié)果會很驚喜哦! 在許多大的群組中,個人往往不知道其他人在干什么。你甚至可以發(fā)現(xiàn)某人在找一些東西做,并且自愿為你寫代 告訴!當(dāng)你在做事的時候,把它告訴所有人如果你做了什么可重用的東西的話,讓其他人知道。別害羞,也不要為了保護(hù)自豪感而把你的工作成果藏起來。一旦養(yǎng)成共享工作成果的習(xí)慣,每個人都會獲得更多。 Don't be Afraid of Small Libraries對于代碼重用,一個常見的問題就是人們不從他們做過的代碼中做庫。一個可重用的類可能正隱蔽在一個程序目錄并且決不會有被分享的激動,因?yàn)槌绦騿T不會把類分拆出來加入庫中。 這樣的其中一個原因就是人們不喜歡做一個小庫,對小庫有一些不正確感覺。把這樣的感覺克服掉吧,電腦才不 如果你有一些代碼可以重用,而且不能放入一個已經(jīng)存在的庫中,那么就做一個新的庫吧。如果人們真的考慮重 If you are afraid of having to update makefiles when libraries are recomposed or added then don't include libraries in your makefiles, include the idea of services. Base level makefiles define services that are each composed of a set of libraries. Higher level makefiles specify the services they want. When the libraries for a service change only the lower level makefiles will have to change.
Keep a RepositoryMost companies have no idea what code they have. And most programmers still don't communicate what they have done or ask for what currently exists. The solution is to keep a repository of what's available.In an ideal world a programmer could go to a web page, browse or search a list of packaged libraries, taking what they need. If you can set up such a system where programmers voluntarily maintain such a system, great. If you have a librarian in charge of detecting reusability, even better. Another approach is to automatically generate a repository from the source code. This is done by using common class, method, library, and subsystem headers that can double as man pages and repository entries.
評價(jià)注釋注釋應(yīng)該是講述一個故事Consider your comments a story describing the system. Expect your comments to be extracted by a robot and formed into a man page. Class comments are one part of the story, method signature comments are another part of the story, method arguments another part, and method implementation yet another part. All these parts should weave together and inform someone else at another point of time just exactly what you did and why.Document DecisionsComments should document decisions. At every point where you had a choice of what to do place a comment describing which choice you made and why. Archeologists will find this the most useful information.使用標(biāo)頭說明利用類似ccdoc的文檔抽取系統(tǒng)。在這一文檔的其他部分描述的是怎么利用ccdoc記錄一個類和方法。
注釋布局工程的每部分都有特定的注釋布局。 Make Gotchas ExplicitExplicitly comment variables changed out of the normal control flow or other code likely to break during maintenance. Embedded keywords are used to point out issues and potential problems. Consider a robot will parse your comments looking for keywords, stripping them out, and making a report so people can make a special effort where needed.
Gotcha Keywords
Gotcha Formatting
Example// :TODO: tmh 960810: possible performance problem // We should really use a hash table here but for now we'll // use a linear search. // :KLUDGE: tmh 960810: possible unsafe type cast // We need a cast here to recover the derived type. It should // probably use a virtual method or template. See AlsoSee Interface and Implementation Documentation for more details on how documentation should be laid out.
Interface and Implementation DocumentationThere are two main audiences for documentation:
Class UsersClass users need class interface information which when structured correctly can be extracted directly from a header file. When filling out the header comment blocks for a class, only include information needed by programmers who use the class. Don't delve into algorithm implementation details unless the details are needed by a user of the class. Consider comments in a header file a man page in waiting.Class ImplementorsClass implementors require in-depth knowledge of how a class is implemented. This comment type is found in the source file(s) implementing a class. Don't worry about interface issues. Header comment blocks in a source file should cover algorithm issues and other design decisions. Comment blocks within a method's implementation should explain even more.
目錄文檔所有的目錄下都需要具有README文檔,其中包括:
工程的源代碼目錄樹,閱讀說明文件,源文件的標(biāo)頭說明等等做為地圖,他應(yīng)該有能力穿越整個工程。
Use a Design Notation and ProcessProgrammers need to have a common language for talking about coding, designs, and the software process in general. This is critical to project success.Any project brings together people of widely varying skills, knowledge, and experience. Even if everyone on a project is a genius you will still fail because people will endlessly talk past each other because there is no common language and processes binding the project together. All you'll get is massive fights, burnout, and little progress. If you send your group to training they may not come back seasoned experts but at least your group will all be on the same page; a team. There are many popular methodologies out there. The point is to do some research, pick a method, train your people on it, and use it. Take a look at the top of this page for links to various methodologies. You may find the CRC (class responsibility cards) approach to teasing out a design useful. Many others have. It is an informal approach encouraging team cooperation and focusing on objects doing things rather than objects having attributes. There's even a whole book on it: Using CRC Cards by Nancy M. Wilkinson. Using Use CasesA use case is a generic description of an entire transaction involving several objects. A use case can also describe the behaviour of a set of objects, such as an organization. A use case model thus presents a collection of use cases and is typically used to specify the behavior of a whole application system together with one or more external actors that interact with the system.An individual use case may have a name (although it is typically not a simple name). Its meaning is often written as an informal text description of the external actors and the sequences of events between objects that make up the transaction. Use cases can include other use cases as part of their behaviour. Requirements CaptureUse cases attempt to capture the requirements for a system in an understandable form. The idea is by running through a set of use case we can verify that the system is doing what it should be doing.Have as many use cases as needed to describe what a system needs to accomplish. The Process
Open/Closed PrincipleThe Open/Closed principle states a class must be open and closed where:
In practice the Open/Closed principle simply means making good use of our old friends abstraction and polymorphism. Abstraction to factor out common processes and ideas. Inheritance to create an interface that must be adhered to by derived classes.
Design by ContractThe idea of design by contract is strongly related to LSP . A contract is a formal statement of what to expect from another party. In this case the contract is between pieces of code. An object and/or method states that it does X and you are supposed to believe it. For example, when you ask an object for its volume that's what you should get. And because volume is a verifiable attribute of a thing you could run a series of checks to verify volume is correct, that is, it satisfies its contract.The contract is enforced in languages like Eiffel by pre and post condition statements that are actually part of the language. In other languages a bit of faith is needed. Design by contract when coupled with language based verification mechanisms is a very powerful idea. It makes programming more like assembling spec'd parts.
其他雜項(xiàng)這一部分包含著各種各樣的該做的和不該做的。
使用if (0)來注釋外部代碼塊有時需要注釋大段的測試代碼,最簡單的方法就是使用if (0)塊:function example() { great looking code if (0) { lots of code } more code } 你不能使用/**/,因?yàn)樽⑨寖?nèi)部不能包含注釋,而大段的程序中可以包含注釋,不是么? Different Accessor StylesWhy Accessors?Access methods provide access to the physical or logical attributes of an object. We disallow direct access to attributes to break dependencies, the reason we do most things. Directly accessing an attribute exposes implementation details about the object.To see why ask yourself:
Implementing AccessorsThere are three major idioms for creating accessors.Get/Setclass X { function GetAge() { return $this->mAge; } function SetAge($age) { $mAge= $age; } var $mAge; } One Method Nameclass X { function Age() { return $mAge; } function Age($age) { $mAge= $age; } var $mAge; }Similar to Get/Set but cleaner. Use this approach when not using the Attributes as Objects approach. Attributes as Objectsclass X { function Age() { return $mAge; } function rAge() { return &$mAge; } function Name() { return mName; } function rName() { return &$mName; } var $mAge; var $mName; }The above two attribute examples shows the strength and weakness of the Attributes as Objects approach. When using rAge(), which is not a real object, the variable is set directly because rAge() returns a reference. The object can do no checking of the value or do any representation reformatting. For many simple attributes, however, these are not horrible restrictions. LayeringLayering is the primary technique for reducing complexity in a system. A system should be divided into layers. Layers should communicate between adjacent layers using well defined interfaces. When a layer uses a non-adjacent layer then a layering violation has occurred.A layering violation simply means we have dependency between layers that is not controlled by a well defined interface. When one of the layers changes code could break. We don't want code to break so we want layers to work only with other adjacent layers. Sometimes we need to jump layers for performance reasons. This is fine, but we should know we are doing it and document appropriately.
Code ReviewsIf you can make a formal code review work then my hat is off to you. Code reviews can be very useful. Unfortunately they often degrade into nit picking sessions and endless arguments about silly things. They also tend to take a lot of people's time for a questionable payback.My god he's questioning code reviews, he's not an engineer! Not really, it's the form of code reviews and how they fit into normally late chaotic projects is what is being questioned. First, code reviews are way too late to do much of anything useful. What needs reviewing are requirements and design. This is where you will get more bang for the buck. Get all relevant people in a room. Lock them in. Go over the class design and requirements until the former is good and the latter is being met. Having all the relevant people in the room makes this process a deep fruitful one as questions can be immediately answered and issues immediately explored. Usually only a couple of such meetings are necessary. If the above process is done well coding will take care of itself. If you find problems in the code review the best you can usually do is a rewrite after someone has sunk a ton of time and effort into making the code "work." You will still want to do a code review, just do it offline. Have a couple people you trust read the code in question and simply make comments to the programmer. Then the programmer and reviewers can discuss issues and work them out. Email and quick pointed discussions work well. This approach meets the goals and doesn't take the time of 6 people to do it.
Create a Source Code Control System Early and Not OftenA common build system and source code control system should be put in place as early as possible in a project's lifecycle, preferably before anyone starts coding. Source code control is the structural glue binding a project together. If programmers can't easily use each other's products then you'll never be able to make a good reproducible build and people will piss away a lot of time. It's also hell converting rogue build environments to a standard system. But it seems the right of passage for every project to build their own custom environment that never quite works right.Some issues to keep in mind:
SourcesIf you have the money many projects have found Clear Case a good system. Perfectly workable systems have been build on top of GNU make and CVS. CVS is a freeware build environment built on top of RCS. Its main difference from RCS is that is supports a shared file model to building software.
Create a Bug Tracking System Early and Not OftenThe earlier people get used to using a bug tracking system the better. If you are 3/4 through a project and then install a bug tracking system it won't be used. You need to install a bug tracking system early so people will use it.Programmers generally resist bug tracking, yet when used correctly it can really help a project:
FYI, it's not a good idea to reward people by the number of bugs they fix :-) Source code control should be linked to the bug tracking system. During the part of a project where source is frozen before a release only checkins accompanied by a valid bug ID should be accepted. And when code is changed to fix a bug the bug ID should be included in the checkin comments.
SourcesSeveral projects have found DDTS a workable system (I 've not verified this link for this PHP release, DDTS may not work for PHP). There is also a GNU bug tracking system available. Roll your own is a popular option but using an existing system seems more cost efficient.
Honor ResponsibilitiesResponsibility for software modules is scoped. Modules are either the responsibility of a particular person or are common. Honor this division of responsibility. Don't go changing things that aren't your responsibility to change. Only mistakes and hard feelings will result.Face it, if you don't own a piece of code you can't possibly be in a position to change it. There's too much context. Assumptions seemingly reasonable to you may be totally wrong. If you need a change simply ask the responsible person to change it. Or ask them if it is OK to make such-n-such a change. If they say OK then go ahead, otherwise holster your editor. Every rule has exceptions. If it's 3 in the morning and you need to make a change to make a deliverable then you have to do it. If someone is on vacation and no one has been assigned their module then you have to do it. If you make changes in other people's code try and use the same style they have adopted. Programmers need to mark with comments code that is particularly sensitive to change. If code in one area requires changes to code in an another area then say so. If changing data formats will cause conflicts with persistent stores or remote message sending then say so. If you are trying to minimize memory usage or achieve some other end then say so. Not everyone is as brilliant as you. The worst sin is to flit through the system changing bits of code to match your coding style. If someone isn't coding to the standards then ask them or ask your manager to ask them to code to the standards. Use common courtesy. Code with common responsibility should be treated with care. Resist making radical changes as the conflicts will be hard to resolve. Put comments in the file on how the file should be extended so everyone will follow the same rules. Try and use a common structure in all common files so people don't have to guess on where to find things and how to make changes. Checkin changes as soon as possible so conflicts don't build up. As an aside, module responsibilities must also be assigned for bug tracking purposes. PHP文件擴(kuò)展名我見過許多種PHP文件的擴(kuò)展名(.html, .php, .php3, .php4, .phtml, .inc, .class...)
理由
不要不可思議的數(shù)字一個在源代碼中使用了的赤裸裸的數(shù)字是不可思議的數(shù)字,因?yàn)榘ㄗ髡,在三個月內(nèi),沒人它的含義。例如:if (22 == $foo) { start_thermo_nuclear_war(); } else if (19 == $foo) { refund_lotso_money(); } else if (16 == $foo) { infinite_loop(); } else { cry_cause_im_lost(); }在上例中22和19的含義是什么呢?如果一個數(shù)字改變了,或者這些數(shù)字只是簡單的錯誤,你會怎么想? 使用不可思議的數(shù)字是該程序員是業(yè)余運(yùn)動員的重要標(biāo)志,這樣的程序員從來沒有在團(tuán)隊(duì)環(huán)境中工作過, 你應(yīng)該用define()來給你想表示某樣?xùn)|西的數(shù)值一個真正的名字,而不是采用赤裸裸的數(shù)字,例如: define("PRESIDENT_WENT_CRAZY", "22"); define("WE_GOOFED", "19"); define("THEY_DIDNT_PAY", "16"); if (PRESIDENT_WENT_CRAZY == $foo) { start_thermo_nuclear_war(); } else if (WE_GOOFED == $foo) { refund_lotso_money(); } else if (THEY_DIDNT_PAY == $foo) { infinite_loop(); } else { happy_days_i_know_why_im_here(); }現(xiàn)在不是變得更好了么? Promise of OOOO has been hyped to the extent you'd figure it would solve world hunger and usher in a new era of world peace. Not! OO is an approach, a philosophy, it's not a recipe which blindly followed yields quality.Robert Martin put OO in perspective:
Thin vs. Fat Class InterfacesHow many methods should an object have? The right answer of course is just the right amount, we'll call this the Goldilocks level. But what is the Goldilocks level? It doesn't exist. You need to make the right judgment for your situation, which is really what programmers are for :-)The two extremes are thin classes versus thick classes. Thin classes are minimalist classes. Thin classes have as few methods as possible. The expectation is users will derive their own class from the thin class adding any needed methods. While thin classes may seem "clean" they really aren't. You can't do much with a thin class. Its main purpose is setting up a type. Since thin classes have so little functionality many programmers in a project will create derived classes with everyone adding basically the same methods. This leads to code duplication and maintenance problems which is part of the reason we use objects in the first place. The obvious solution is to push methods up to the base class. Push enough methods up to the base class and you get thick classes. Thick classes have a lot of methods. If you can think of it a thick class will have it. Why is this a problem? It may not be. If the methods are directly related to the class then there's no real problem with the class containing them. The problem is people get lazy and start adding methods to a class that are related to the class in some willow wispy way, but would be better factored out into another class. Judgment comes into play again. Thick classes have other problems. As classes get larger they may become harder to understand. They also become harder to debug as interactions become less predictable. And when a method is changed that you don't use or care about your code will still have to be retested, and rereleased.
Recent Changes
|