How to avoid SRP chaos?
By applying the SRP principle you are bound to have a lot of classes. If this works fine for a small project how can you handle and organize the amount of classes on a large project ?
- how do you organize the folder structure ?开发者_开发知识库
- how do you remember what you build ?
- how do you know if others didn't build the same functionally in other class ?
This applies across all types of libraries. Not just SRP.
Organization of classes/functions can be a headache, but really there are only a few things you need to bear in mind.
- Plan.
- Define and keep a proper naming convention for files, classes, folders, methods/functions and variables.
- Break your classes into name spaces or at least into sub-folders by the major muscle groups of the system.
- Document: internally (good comments, file headings, and public method lists) and externally (wiki, readmes, excel, something)
By 2 I mean: /library/muscleGroup/useType_nameOfClass.php
for files/folders where useType is something like "factory" "abstract" "data / dto" or whatever patterns you are using. Then, in each file the class should be the exact same thing as nameOfClass and each method name should strictly follow a pattern. [Action][on what][with what conditions]
and keep a list of actions and 'on whats' and stick to them RELIGIOUSLY.
Do that, and you can't duplicate functionality, since you can easily find the right classes and methods for the things you want. Since they have logical names like Get_User_ById
and Get_Transactions_ByNewest
or Combine_Ingredients_FromRecipes
.
That last one might have a comment above it like:
// Combines many recipes into one ingredient list
// $recipes = an array of recipe objects
// returns an array of ingredient objects with their correct quantities
List of sample Actions: (should be pretty generic and apply to any application)
- Get
- Set
- Delete
- Move
- Merge
- Combine
List of sample "On What"s: (should be application specific)
- User
- Ingredient
- Recipe
- Measurement
- Permission
- Brand
- Ad
Depends on the project, but if it was something that has a lot of CRUD without much actual business rules, I would go for a structure that is simple, with script files to support that decision. I have done this in the past, and it is super fast, but slow to change. Typically called the Smart UI anti-pattern by Eric Evans:
"Put all the business logic into the user interface. Chop the application into small functions and implement them as separate user interfaces, embedding the business rules into them. Use a relational database as a shared repository of the data. Use the most automated UI building and visual programming tools available [Evans p.77]."
If you are making something with lots of real business rules and have more time, or you expect it to have a long life:
- Figure out the tasks of the system, and try to implement those tasks as higher level commands.
- Have those higher level commands manipulate low level core classes, and are called from the ui. I have been using the Zend Framework, and I have the controllers call these high level commands, but that is really overkill in most places. I have these classes stored in an Application folder, divided by module (accounting, email, etc).
- The lower level classes are held in a Domain folder, which is also split into those same modules as the Application folder. The Domain classes represent the objects being worked on (Email, ClassCredit). These are small, and only do tasks that make sense for that concept.
As for resources to help you further, check out Clean Code by Bob Martin, and Domain-Driven Design (can't post the other link) by Eric Evans. Both books are brilliant, and offer tactical and strategic steps, respectively, to tackling that chaos.
Folder Structure
Zend Framework organizes their classes by functionality and names them as such. For example the class Zend_Controller_Action_Helper_AjaxContext
is located at /library/Zend/Controller/Action/Helper/AjaxContext.php
.
This serves two purposes: Folder organization and logical separation of functionality. You'll always run into the problem of 'remembering what you build` but by applying SRP and placing functionality where it is logically 'most correct' you can cut down on confusion.
IDE
When dealing with a lot of classes an intelligent IDE is essential. Shortcuts that allow a developer to quickly lookup classes, filenames, and methods anywhere in the project make dealing with thousands of classes almost trivial.
Using the same example as above one should be able to find the class in a variety of ways:
- Looking up the class name. In EclipsePDT it's as easy as
ctrl+shift+T
to lookup classes (types). (note: I honestly don't know if this is a feature of eclipse or an addition by the PDT plugins). - Similarly, you can lookup by filename using
ctrl+shift+R
(resource). - Or by method within the class
ctrl+shift+m
精彩评论