Last modified date:
2000-11-16
The PHP programming standard is based on Todd Hoff, based on "C Programming Standard" for PHP, the author is Fredrik Kristiansen,
table of Contents
Introduction
Standardization importance
Explanation
Identity view
Four stages of the project
Naming rule
Suitable name
Necklement words don't use uppercase letters
Class name
Class library name
Method naming
Class properties named
Name in the method
Variable name
Reference variables and functions return reference
Global variable
Define naming / global constant
Static variable
Function name
PHP file extension
Document rules
Comment
Comments SHOULD TELL A Story
Document Decisions
Use header description
Make Gotchas Explicit
Interface and Implementation Documentation
Directory document
Complexity management rules
Layering
Open / closed PrinciPle
Design by Contract
Class rules
Different Accessor Styles
Don't do actual work in the object architecture
Thin vs. Fat Class Interfaces
Short method
Process rule
Use a design notation and process
USING USE CASES
Code Reviews
Create a Source Code Control System Early and Not Off
Create a bug tracking system early and not offten
RCS keyword, change record and history rules
Honor Responsibilities
format
Big bracket {} rules
Ind retaining / tab / space rules
Brand, keyword and function rules
IF THEN ELSE format
Switch format
Use of Continue, Break, and?
One statement per line
Declaration block
Pop myth
Promise of oo
Miscellaneous
Don't be incredible
Error return detection rules
Do not test non-zero values with default values
Boolean logical type
Usually avoid embedded assignments
Reuse your hard work
Use IF (0) to comment external code block
Other miscellaneous
Introduction
Standardization importance
Standardization issues make everyone headache in some respects, let people feel that everyone is in the same situation. This helps these recommendations continue to evolve in many projects, and many companies have spent many weeks to compete with the words. Standardization is not a special personal style, which is completely open to local improvement.
advantage
When a project tries to comply with the public standard, there will be the following benefits:
Programmers can understand any code and clarify the status of the program
Newcomers can adapt quickly
Prevent people from contacting the PHP from saving time, homemade style and developing a life habit
Prevent new contacts from PHP, the same mistake
In a consistent environment, people can reduce the chance to make mistakes
The programmers have a consistent enemy
Disadvantage
It is now in the bad place:
Because the standard is made by some people who don't know PHP, the standard usually looks very stupid.
Because the standard is different from me, the standard usually looks very stupid.
Standard reduces creativity
Standards are not necessary in people who cooperate for a long time.
Standard forces too many formats
In short, people neglect the standard
discuss
The experience of many projects can be concluded that the programming standard can make the project more smoothly. Is the standard of success? of course not. But they can help us, and we need all the help we can get! Honestly, most of the arguments for a detail standard are mainly derived from their own ideas. A little decision to a reasonable standard can be said to be a lack of technical, that is just the reason for the taste. Therefore, to be flexible to control your own mind, remember, any project depends on the efforts of teamwork.
Explanation
Convention
The use of "To" words in this document is that all items using this specification require compliance with the specified criteria. The role of using "should" is to guide the details of the project custom project. Because the project must be appropriately included, Exclude or Tailor requirement. The role of using "can" is similar to "should" because it indicates optional requirements. Standard implementation
First, all the most important elements should be found inside the development team, maybe the standard is not appropriate to your situation. It may have already summarized an important issue, or some people have a strong opposition to some of them. No matter what circumstances, as long as the final is smooth, people understand that this standard is reasonable, then other programmers will find its rationality and feel that it is worthwhile to follow this standard. of. If there is no voluntary cooperation, you can make a demand: standard must pass the test. If there is no test, this solution is just a large group of funny people built on an inaccurate basis.
Identity view
This line is not available;
Maybe it is possible, but it is neither practical and bored;
This is true, and I also told you;
This is what I thought first;
It should be like this.
If you look at things about things with your negative, please keep an open idea. You can still make it a nonsense conclusion, but how to conclude is that you have to be able to accept different ideas. Please give yourself a little time to do it.
Four stages of the project
Database structure
design
Data layer
HTML layer
Naming rule
Suitable name
Name is the core of program planning. The ancients believe that just know that a real name will get an incredible force over the individual. As long as you think of the right name for things, you will bring you and later people to stronger than the code. Do not laugh! The name is a long and far-reaching result in the ecological environment it. Overall, only the programmer of the system can take the most appropriate name for the system. If all namings are suitable for nature, the relationship is clear, and the meaning can be derived, and the average person's idea can also be unexpected. If you find that your name is only a small amount that matches its corresponding things, it is best to look at your design.
Class name
Let's first know what it is for class (Class) naming. If you can't afford this class through the clues of the class name, you still can't do this, then your design is not good enough.
More than three words consisting of mixed names are easy to confuse the system's individual entities, then look at your design, try to use (CRC SSION CARD) to see if the entity corresponding to the naming has so much function.
The name of the derived class should avoid temptation to bring his parent class name, and a class name is only related to itself, and it is independent of its parent class.
Sometimes it is useful, for example, if your system uses a proxy (agent), then name the part name "Download Agent" to real transmission information.
Method and function name
Usually, each method and function performs an action, so what they are naming should clearly explain what they do: instead of ErrorCheck () with DumpDataTOfile (), with DumpDataTOfile () instead of DataFile (). This can also make functions and data into a more distinctive object.
Sometimes the suffix name is useful:
MAX - Meaning the maximum value that can be given to an entity.
CNT - The current value of a count variable in a run.
Key - key value.
For example: Retrymax represents the maximum number of retries, Retrycnt represents the current number of retries.
Sometimes the preamble name is useful:
IS - meaning to ask a question about a sample. Whenever you see IS, you will know that this is a problem.
GET - meaning is a value.
Set - meaning to set a value
For example: IshitRetrylimit.
Necklement words don't use uppercase letters
In any case, when you encounter the following, you can use the surplus letter lowercase to replace all the usual-write letters. Use: gethtmlstatistic. Not used: gethtmlstatistic.
reason
People seem to have a very different intuition when naming an acrony word. The unified provisions are the best, so that the meaning of naming is completely predicted.
For an example of NetWorkabcKey, note that C should be C. C is still in Key in the ABC, which is very puzzled. Some people don't care about these, others are very annoying. So you will see different rules in different codes, making you don't know how to call it.
E.g
Class Fluidoz / / Don't write into Fluidoz
Class gethtmlstatianship / / Don't write into gethtmlstatians
Class name
Use uppercase letters as the word separation, other letters use lowercase
The name of the name is capitalized
Don't use underscores ('_')
reason
Based on a lot of naming methods, most people think this is the best way.
E.g
Class Nameonetwo
Class name
Class library name
The current naming space is increasingly adopted to avoid conflicts between different manufacturers and group libraries.
When you have not used namespace, in order to avoid class conflicts, the general approach is to add a unique prefix before the class name, and two characters can be better. Of course, some will be better.
E.g
John Johnson's data class library can be prefixed by JJ as follows:
Class JjlinkList
{
}
Method naming
Using the rules identified with class named
reason
Most people who use all different rules have found this is the best compromise.
E.g
Class Nameonetwo
{
Function Doot () {};
Function HandleError () {};
}
Class properties named
Attribute naming should prefix with character 'm'.
The prefix 'm' is used in the rules of the class named.
'M' always modifies the beginning of the name, just like the beginning of 'R'.
reason
Prefix 'M' prevents class properties and method names any conflicts. Your method name and attribute name are often similar, especially accessing elements.
E.g
Class Nameonetwo
{
Function varAbc () {};
Function ErrorNumber () {};
Var mvarabc;
Var MerrorNumber;
Var mrname;
}
Name in the method
The first character uses lowercase letters.
All words after the first character are capitalized in accordance with the class naming rules.
reason
You can always know that variable corresponding to that variable.
You can use the name similar to the class name and not to produce a researcher.
E.g
Class Nameonetwo
{
Function Startyouregines
& $ rsomeengine,
& $ RANOTHERENGINE);
}
Variable name
All letters use lowercase
Use '_' as the boundary of each word.
reason
With this way, the scope of the variable in the code is clear.
All variables look different in the code, easy to identify.
E.g
Function HandleError ($ ErrorNumber)
{
$ error = oserr ();
$ TIME_OF_ERROR = Osterr-> GetTimeOfError;
$ error_processor = oserr-> getErrorProcessor;
}
Reference variables and functions return reference
Quote must be with 'r' prefix
reason
Make different variables that have different types of variables are easy to identify
It can determine which method returns to change objects, which method returns to not change objects.
E.g
Class test
{
Var mrstatus;
Function DOSMETHING (& $ RSTATUS) {};
Function & RSTATUS () {};
}
Global variable
The global variable should have a prefix 'g'.
reason
It is very important to know the role of a variable.
E.g
Global $ GLOG;
Global & $ GRLOG;
Define naming / global constant
The global constant separated each word with '_'.
reason
This is a tradition of naming global constants. Be careful not to conflict with other definitions.
E.g
Define ("a_global_constant", "Hello World!");
Static variable
Static variables should have a prefix 's'.
reason
It is very important to know the role of a variable.
E.g
Function test () {static $ msstatus = 0;
}
Function name
The function name uses C GNU practices, all letters use lowercase letters, use the '_' segmentation words.
reason
This makes it easier to distinguish between associated class names.
E.g
Function Some_bloody_function ()
{
}
Error return detection rules
Check the error message for all system calls unless you want to ignore the error.
Define system error text for each system error message so that INCLUDE.
Big bracket {} rules
In the three major braces placement rules, there are two kinds of acceptable, the first one is the best:
Place the braces in the same column below the keyword:
· IF ($ condition) While ($ condition)
{{
· ...
}}
Traditional UNIX parentheses rules are, main brackets and keywords, tail brackets and keywords:
· IF ($ condition) {while ($ condition) {
· ...
}}
reason
The issue of non-principled discrimination can be solved by compromise, and any of two ways can be accepted, but for most people like the first one. The reason is something that psychologically study study areas.
There are more reasons for more like the first kind. If you use the character editor to support parentheses (for example, VI), the most important thing is to have a good style. why? We said that when you have a large piece of program and want to know where this big program is over. You first move to the starting parentheses, press the button editor to find the corresponding end parentheses, for example:
IF ($ VERY_LONG_CONDIS & $ SECOND_VERY_LONG_CONDITION)
{
...
}
ELSE IF (...)
{
...
}
Move from a block to another, you only need to match the cursor and your parentheses match button, you don't need to move back to the end to the line to find the matching parentheses.
Ind retaining / tab / space rules
Use the tab to vent.
Use three to four spaces to indent every level.
It is no longer used as long as a method of replacing it is required. In the maximum number of indented layers, there is no fixed rule, if the number of indenges is greater than four or five layers, you can consider the factoring out code. reason
Many programmers support tab.
Tabs Was Invented for a rason
When people use the tabular standards for the difference, the reading code will become very laborious.
Such a number is willing to limit the maximum number of indented layers, which usually has never been seen as a work. We believe that programmers will be wise to select the nesting depth.
E.g
Function func ()
{
IF (Something Bad)
{
IF (ANOTHER Thing Bad)
{
While (more input)
{
}
}
}
}
Brand, keyword and function rules
Don't close the small brackets and keywords, you have to separate them with spaces.
Don't close the parentheses and function names.
Do not use parentheses in return returns in Return returns unless necessary.
reason
Keywords are not functions. If parentheses close to function names and keywords, both are easy to be considered one.
E.g
IF (condition)
{
}
WHILE (CONDition)
{
}
STRCMP ($ S, $ S1);
Return 1;
RCS keyword, change record and history rules
The rules that directly use the RCS keyword must be changed, including a source code control system that supports RCS style keywords using CVS:
Don't use RCS keywords within your documents.
Don't save history modifications records in your file.
Don't save authors in your document.
reason
The Reasoning is your source control system alleady keeps all this information. There is no reference to clutter Up Source Files with duplicate information That:
Makes The Files Larger
Makes Doing Diffs Difficult As Non Source Code Lines Change
Makes The Entry Into The File Dozens of Lines Lower In The File Which Makes a Search or Jump Necessary for Each File
Is Easily Available from The Source Code Control System and Does Not NEED Embedding In The File
.
Don't do actual work in the object architecture
Don't do real work in the object architecture, initialization variables and / or do things that will not have errors in the architecture period.
When the object architecture is completed, an OPEN () method is established for the object, and the open () method should be named in an object entity.
reason
The construct cannot return an error.
E.g
Class Device
{
Function device () {/ * Initialize and other stuff * /}
Function open () {returnif;
}
$ dev = new device;
IF (fail == $ dev-> open ()) exit (1);
IF THEN ELSE format
layout
This is determined by the programmer. Different curly parenthesis patterns will have some different samples. A common way is:
IF (Condition 1) // Note {
}
ELSE IF (Condition 2) // Note
{
}
ELSE // Note
{
}
If you use it to the else if statement, it usually has an else block for processing unprocessed. If you can put a record information comment at else, even in Else doesn't have any action.
Conditional Formatting
Always put the constant to the left side of the equal number / do not equal sign, for example:
IF (6 == $ ErrorNum) ...
One reason is that if you are leaking a equal sign in the equation, the syntax checkter will report an error. The second reason is that you can find a value immediately instead of finding it at the end of your expression. It takes a little time to habits this format, but it is really useful.
Switch format
Falling Through a Case Statement Into The Next Case Statement Shall Be Permitted as long as a comment is incn.
Default Case should always exist, it should not arrive, but if it arrives, it will trigger an error.
If you want to create a variable, put all the code in the block.
E.g
Switch (...)
{
Case 1:
...
// Fall Through
Case 2:
{
$ V = get_week_number ();
...
}
Break;
DEFAULT:
}
Use of Continue, Break, and?
Continue and Break
Continue and Break are actually a hidden GOTO method.
Continue and Break are like goto, they have magic in the code, so you have to use them with you (as little as possible). This simple magic is used, and the reader will be oriented to only God know because of some undisclosed reasons.
Continue has two main issues:
It can bypass test conditions.
It can bypass the like / unequal expressions.
Take a look at the example below, think about where the problem occurs:
While (True)
{
...
// a LOT OF C
...
IF (/ * some condition * /) {
CONTINUE;
}
...
// a LOT OF C
...
IF ($ I > Stop_Value) Break;
}
Note: "a lot of code" is required, this is to make programmers can't find errors so easy.
Through the above example, we can draw a further rule: Continue and Break mixing are the correct way to cause disasters.
?:
Trouble is that the people often try it? And: Many code is filled between them. The following is some clear connection rules:
Place the condition in parentheses to separate it from other code.
If possible, the action can use a simple function.
Place the action, "?", ":" In different rows, unless they can be clearly placed in the same line.
E.g
(CONDition)? Funct1 (): func2 ();
oral
(Condition)
? Long Statement
: another long stat;
Declaration block
The declaration code block needs to be aligned.
Justification
Clear.
A variable initialized similar code block should list.
The ?? token will be adjacent to the type, not the name.
E.g
Var $ mdate
VAR & $ MRDATEVAR & $ mRName
Var $ mname
$ MDATE = 0;
$ mrdate = NULL;
$ mRNAME = 0;
$ mname = null;
One statement per line
Each line will only write only one statement unless these statements have a close relationship.
Short method
Method code should be limited to one page.
reason
This idea is that each method represents a technology that completes a separate purpose.
In the long run, excessive invalid parameters are wrong.
The calling function is slower than the call, but this requires a decision to make a decision (see Premature Optimization is not perfect).
Record all empty statements
Always record the empty block statement of for or while, so that this code is missing, or not to write.
While ($ DEST = $ SRC )
; // void
Do not test non-zero values with default methods
Do not test a non-zero value by default, that is, use:
IF (fail! = f ()))
Good than the following method:
IF (f ())
Even if the FAIL can contain 0 values, it is PHP that the representation of false. When someone decides to use -1 instead of 0 as a failure return value, an explicit test can help you. Even if the value does not change, it should also use an explicit comparison; for example: if (! ($ Bufsize% strlen))) should be written: IF (($ bufsize% strlen) == 0) Taking the value (not a Boolean) type tested. A regular problem is to use strcmp to test a character equation, and the result will never be equal to the default.
Non-zero testing uses default-to-value practices, then other functions or expressions are subject to the following limitations:
Can only return 0 to fail, and cannot be / other values.
Naming so that a true return value is absolutely obtable, calling a function isvalid () instead of Checkvalid ().
Boolean logical type
Most functions returned to 0 at FALSE, but the non-0 value represents True, so do not use 1 (True, Yes, such as this), etc., should be used to detect a boolean value, should be used in inequality of 0 (False, NO, etc.) instead:
IF (true == func ()) {...
Should be written:
IF (false! = func ()) {...
Usually avoid embedded assignments
Sometimes we can see an embedded assignment statement, those structures are not a relatively good redundancy, a high readability method.
While ($ a! = ($ c = getchar ())))))
{
Process the character
}
and - operators are similar to assignment statements. Therefore, for many purposes, side effects are generated when using functions. It is possible to use embedded assignments to improve runtime performance. In any case, programmers need to consider weighing between growth and reduced maintainability when using embedded assignment statements. E.g:
A = B C;
D = a r;
Don't write:
D = (a = b c) R;
Although the latter can save a cycle. However, in the long run, as the maintenance cost of the program grows, the writer of the program gradually forgotten the code, and will reduce the optimization of maturity. Reuse your hard work
Cross-engineering reuse is almost impossible without a universal structure. Objects meet their existing service needs, different processes have different service demand environment, which makes object reuse difficult.
Developing a general structure requires a lot of effort to design. When the effort is unsuccessful, there are several ways to recommend using:
consult! Send EMAIL for groups
This simple method is rarely used. Because some of the programmers feel that if he helps others, it will look low level, this is more stupid! Do a new and interesting job, don't make someone else have done it over again.
If you need some of the source code for some matter, if you already have someone else, email helps to the group. The result will be very surprised!
In many large groups, individuals often don't know what others are doing. You can even find someone to do something, and voluntarily write code, if people work together, there is always a gold mine.
tell! Tell everyone when you do things
If you have done anything that can be reused, let others know. Don't be shy, don't hide your work in order to protect your pride. Once the habit of sharing the results of sharing work, everyone will get more.
Don't Be Afraid of Small Libraries
For code reuse, a common problem is that people don't do the library from their code. A reusable class may be hidden in a program directory and will never have shared excitement, because the programmer does not split the class into the library.
One of this reason is that people don't like to be a small library, and there are some incorrect feelings for the small library. Overcome such a feeling, the computer doesn't care how many libraries do you have.
If you have some code to be reused, and you can't put it in an existing library, you will be a new library. If people really consider reuse, the library will not be so small in a long time.
If you are afraid of having to update makefiles when libraries are recomposed or added then do not 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 The Lower Level Makefiles Will Have To change.
Keep a repository
Most Companies Have No IDea What Code The Have. And Most Programmers Still Don't 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.
Comment
Note should tell a story
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 .
Document Decisions
Comments. 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.
Use header description
Use a document extraction system similar to CCDOC. Other parts of this document describe how to use CCDOC to record a class and method. These header descriptions can be extracted and analyzed in such a way that they are not useless as in the general header. So spend time to fill in him.
Note layout
Each part of the project has a specific annotation layout.
Make Gotchas Explicit
Explicitly 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
: Todo: Topicmeans there's more to do here, don't forget.:bug: [bugid] Topicmeans There's a known bug here, the explain it and optionally give a bug ID.
: Kludge: when You've done Something Ugly Soy So and Explain How you would do it diffreently next time if you have had more time.
: Tricky: Tells Somebody That The Following Code Is Very Tricky So n't Go Changing It WITHOUT Thinking.
: Warning: BEWARE OF Something.
: Pharser: Sometimes You NEED To Work Around a Pharser Problem. Document It. The questionM May Go Away Eventually.
: Attribute: valuethe general form of an attribute embedded in a comment. You can make Up Your Own attributes and they'll be extracted.
Gotcha Formatting
Make The Gotcha Keyword The First Symbol in The Comment.
Comments May Consist of Multiple Lines, But The First Line Should Be a self-containing, meaningful summary.
The writer's name and the date of the remark should be part of the comment. This information is in the source repository, but it can take a quite a while to find out when and by whom it was added. Often gotchas stick around longer than they SHOULD. Embedding Date Information Allows Other Programmer To make this decision. Embedding WHO INFORMATION Lets US Know Who To ask.
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 Also
See Interface and Implementation Documentation for More Details On How Documentation Should Be Laid Out.
Interface and Implementation Documentation
There Are Two Main Audiences for Documentation: Class Users
Class Implementors
With a little forethought we can Extract Both Types of Documentation Directly from Source Code.
Class user
Class 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. Do not delve into algorithm implementation details unless .................. ..
Class Implementors
Class implementors require in-depth knowledge of how a class is implemented. This comment type is found in the source file (s) implementing a class. Do not worry about interface issues. Header comment blocks in a source file should cover algorithm issues and Other Design Decisions. Comment Blocks Withnin a Method's Implementation Should Explain Even More.
Directory document
There is a readme document in all directories, including:
The function of this directory and its containment
A online instructions for each file (with link), each of which typically should also extract some of the property names of the file header.
Including settings, instructions
How to connect the people to connect the resources:
Source file index
Online document
Papermark document
Design documentation
Other things that are helpful to readers
Consider it, when each original engineering is gone, a newcomer from 6 months, the lonely scared explorer through the entire project's source code directory tree, reading instruction file, source file header Description, etc. As a map, he should have the ability to cross the entire project.
Use a design notation and process
PROGRAMERS NEED TO HAVE A Common Language for Talking About Coding, Designs, And The Software Process In General. This is critical to project surcess.
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 methodology.
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 CASES
A 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 WILE 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 carated as part of their behaviour.
Requirements Capture
Use 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 neseds to accomplish.
The process
START by understanding the system you are trying to build.
Create a set of use copy describing how the system is to be used by all but its Different Audiences.
Create a class and Object Model for the system.
..
Open / closed PrinciPle
The open / closed PrinciPle States a class must be open and close:::
Open means a class has the ability to be extended.
closed means a class is closed for modifications other than extension. The idea is once a class has been approved for use having gone through code reviews, unit tests, and other qualifying procedures, you do not want to change the class very much, just Extend it.
The Open / Closed principle is a pitch for stability. A system is extended by adding new code not by changing already working code. Programmers often do not feel comfortable changing old code because it works! This principle just gives you an academic sounding justification for Your fears :-)
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 Contract
The 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 CONDENTS THATE 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 makess programming more like assembly spec'd parts.
Other miscellaneous
This part contains a variety of what should be done and should not do.
Do not use floating point variables in need to use discrete values. The cyclic counter is not distressed to the foot of your foot. You always use <= or => when you test the floating point number, never use = or =>.
Don't use the program automatic beautifier, the main person who benefits from a good program style is the programmer himself, especially the programmer who just opened the code, the algorithm design, using the program automatic beautifier can only be corrected according to the syntax, so It is impossible when there is a big need for gap and indent attention. Normal carefully payment details can use a clear and intuitive style to complete a function or document (in other words, some intuitive style is intentional instead of the intelligence of the program automatic beautifier can read ). Majoo programmers should learn detailed programmers, do not rely on program automatic beautifiers to increase program readability. The initial beautifier is a program that must analyze source code. The complex beautifier is not worthy of this benefit, the beautifier is best used to generate the total machine establishment (Machine-generated) format code.
The second = accidentally ignored logical expression is a problem, and the following is chaotic and more like an error:
· IF ($ abool = $ bbool) {...}
Is the programmer really to assign a value? Generally, it is usually not the case. This avoids causing such confusion? The solution is not to do this, use explicit and implicit judgment tests, the recommended method is to assign a value before doing tests:
$ abool = $ bBOOL;
IF ($ abool) {...}
Use IF (0) to comment external code block
Sometimes you need to note the test code of the large section, the simplest method is to use if (0):
Function example ()
{
Great looking codeif (0) {
LOTS of CODE
}
More code
}
You can't use / ** / because the notes cannot contain comments inside, while the large segment can contain comments, isn't it?
Different Accessor Styles
Why 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:
What if The Object Decided TO PROVIDE THETRIBUTE IN A WAY OTHER THAN PHYSICAL Containment?
What if it had to do a database lookup for the attribute?
What if A Different Object Now Contained The Attribute?
If any of the above changed code would break An object makes a contract with the user to provide access to a particular attribute;.. It should not promise how it gets those attributes Accessing a physical attribute makes such a promise.
Implementing Accessors
There Are Three Major IDioms for Creating Accessors.
Get / set
Class X
{
Function Getage () {Return $ this-> Mage;}
Function Setage {$ Mage = $ AGE;
VAR $ MAGE;
}
One Method Name
Class X
{
Function Age () {return $ Mage;}
Function Age ($ AGE) {$ Mage = $ AGE;
VAR $ MAGE;
}
SIMILAR TO GET / SET But Clearator. Uses Approach When Not Using The Attributes As Objects Approach.
Attributes as Objects
Class X
{
Function Age () {return $ Mage;}
Function Rage () {Return & $ MAGE;
Function name () {return mname;}
Function RName () {RETURN & $ MNAME;
VAR $ MAGE;
Var $ MNAME;
}
X $ x;
$ x-> rname () = "TEST";
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 is not horrible restrictions.
Layering
Layering 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 do not want code to break so we want layers to work only with other adjacent layers.
Sometimes We need to jump layers for perform, but we shop know we are doing it and document appropriately.
Code Reviews
If 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 the fit insto normally late chaotic projects is what is being quintioned.
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 Off
A 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 not 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:
Shared Source Environments Like CVS Usually Work Best in Largish Projects.
If you use CVS use a reference tree approach. With this approach a master build tree is kept of various builds. Programmers checkout source against the build they are working on. They only checkout what they need because the make system uses the build for anything not found locally. Using the -I and -L flags makes this system easy to setup. Search locally for any files and libraries then search in the reference build. This approach saves on disk space and build time.Get a lot of disk space. With Disk space as cheap it is there is no reference.
Make Simple Things Simple. It Should Be Dead Simple and Well Document On How To:
Check Out Modules To Build
How to change Files
How To Add New Modules Into The System
How to delete Modules and Files
How To Check in Changes
What Are The Available Libraries and Include Files
How To Get The Build Environment Including All Compilers and Other Tools
.
On CHECKINS LOG Comments Should Be Useful. These Comments Should Be Collected Every Night and Sent To Interested Parties.
Sources
If 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 offten
The 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 will not 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:
Problems Aren't Dropped on the floor.
Problems Are Automatically Routed to Responsible Individuals.
The Lifecycle of a Problem is tracked so people.
Managers can make the big schedule and staffing decisions based on the number of onepes of bugs in the system.
Configuration Management Has A Hope of Matching Patches Back to The Problems They FIX.
Qa and Technical Support Have a Communication Medium with developers.
NOT SEXY Things, Just Good Solid Project Improvements.
Fyi, it's not a good idea to reason the name by the number of bugs theif :-)
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 include in the checkin commerss.
Sources
Several 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 effect.
Honor Responsibilities
Responsibility for software modules is scoped. Modules are either the responsibility of a particular person or are common. Honor this division of responsibility. Do not go changing things that are not your responsibility to change. Only mistakes and hard feelings will result.Face it, if you do not own a piece of code you can not 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....................... ..
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 theh has 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. NOT EVERYONE IS BRILLIANT AS you.
The worst sin is to flit through the system changing bits of code to match your coding style. If someone is not 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 do not have to guess on where to find things and how to make changes. Checkin changes as soon as possible so conflicts do not build up.As an aside, module responsibilities must also be assigned for bug tracking purposes .
PHP file extension
I have seen many extensions of PHP files (.html, .php, .php3, .php4, .phtml, .inc, .class ...)
All viewers can be used to use .html
All classes, library files use .php
reason
The extension describes that data is that the user will receive. PHP is explained to HTML.
Don't be incredible
A naked number used in the source code is an incredible number, because including the author, within three months, no one has its meaning. E.g:
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 ();
What is the meaning of 22 and 19 in the previous example? If a number changes, or these numbers are just simple errors, what do you think?
Using an incredible number is an important sign of the programmer is an amateur athlete. Such a programmer has never worked in a team environment, or to maintain code, otherwise they will never do such a thing.
You should use define () to show you a real name, rather than adopting naked numbers, for example:
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 (the_didnt_pay == $ foo) {infinite_loop ();
Else {happy_days_i_know_why_im_here ();
Isn't it better now?
Promise of oo
OO 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:
OO, when properly employed, does enhance the reusability of software. But it does so at the cost of complexity and design time. Reusable code is more complex and takes longer to design and implement. Furthermore, it often takes two or more tries to create Something That Is Even Marginally Reusable.
OO, when properly employed, does enhance the software's resilience to change. But it does so at the cost of complexity and design time. This trade off is almost always a win, but it is hard to swallow sometimes.
OO does not necessarily make anything easier to understand. There is no magical mapping between the software concepts and every human's map of the real world. Every person is different. What one person percieves to be a simple and elegant design, another will perceive as convoluted And opaque.
If A Team Has Been Able, by Applying Point 1 Above, To Create A Repository of Reusable Items, The Development Times Can Begin To Shrink Significantly Due To Reuse.
IF A Team Has Been Able, by Applying Point 2 Above, To Create Software That Is Resilient To Change, The Maintenance of That Software Will Be Much Simpler and Much Less Error Prone.
Thin vs. Fat Class Interfaces
How 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 does not exist. You need to make the right judgment for your Situation, Which is real 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 are not. You can not 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 do not use or care about your code will still have to Be rasted, and recreleased.
Recent Changes
2000-11-16
RELEASE
© CopyRight 1995-2000. Todd Hoff and Fredrik Kristiansen. All Rights Reserved.