[note] PHP OOP - Objects and Design
Chapter 6 - “PHP Objects, Patterns, and Practice - 2nd”
- Design Basics: how object-oriented design differs from procedural code.
- Class scope: How to decide what to include in a class
- Encapsulation: Hiding implementation and data behind a class’s interface.
- Polymorphism: Using a common super-type to allow transparent substitution of specialised subtypes at runtime.
Defining code design: on low level, design can be taken to mean the process by which you define the participants of your system, and organise their relationships. (participants: class, method, interface)
Object-Oriented and Procedural Programing
One core difference is in the way responsibility is distributed (not that the OO code has objects in it)
Responsibility may be a task or a control (for making decision). While the procedural code busies itself about details, the OO codes works only with interfaces. Because responsibility for implementation lies with the objects, and not with the client code, it would be easy to support for new implementations transparently.
Cohesion is the extent to which a proximate method is related to one another. Ideally, you should create components that share a clear responsibility. If your code spreads related routines widely, you will find them harder to maintain as you have to hunt around to make changes.
Tightly coupling occurs when discrete parts of a system’s code are tightly bound up with one another so that change in one path necessities changes in the others.
The killer combination in components of tightly defined responsibilities together with independence from the wider system is sometime referred to as orthogonality (loose coupling and hight cohesion). Orthogonality promotes reuse in that components can be plugged into new systems without any needing configuration. Orthogonality code is safer, the effect of bugs should be limited in scope.
Choosing your class: The best approach is to think of class as having a
primary responsibility and to make that responsibility as singular and focused as possible. Put the responsibility into words. It has been said that you should be able to describe a class’s responsibility in 25 words or less and rarely using the words “and” or “or”. If your sentence gets too long or mired in clauses, it is probably time to defining new classes along the lines of some responsibilities you have defined.
Polymorphism is the maintenance of multiple implementations behind a common interface. The need for polymorphism is often signalled by the presence of extensive conditional statements in your code. Polymorphism doesn’t banish conditionals, it tend to centralise the conditionals in to one place.
Encapsulation simply means the hiding of data and functionality from a client.
Polymorphism illustrates another kind of encapsulation. By placing different implementations behind a common interface, we hide these underlying strategies from the client. This means that any changes that are made behind this interface is transparent to the wider system.
Our objective should be to make each part as independent as possible from its peers. Classes and methods should be received as much information as necessary to perform their allotted tasks, which should be limited in scope and clearly identified.
Encapsulation helps you to create orthogonal codes.
————————————————————————-
Very few people get it absolutely right at the design stage. When designing class and interface, think only about the key participants in your system: the types it needs and its interface. Let the structures and relationships in your code lead you.
Four signposts you should watch out for as you code.
Code duplication: Duplication is one of the most evils in code. If you get a strange sense of “old experience” as you write a routine, chance are you have a problem. Duplication generally means tightly coupling.
The class who knew too much: It can be a pain passing parameters around from method to method. Why not simple the pain by using a global variable, so that everyone can get at the data. However, by using global variables, or by giving a class any kind of knowledge about its wider domain, making it less reusable and dependent on code beyond its control. So, remember, you want to decouple your classes and routines and not to create interdependent.
The jack of all trades: when your class has too much responsibilities, you should create some new small classes sharing the responsibilities of old class.