The distinction between association, aggregation and composition as you describe it is a legacy going back to the old times of manual memory management. For example in C++ the memory used by objects has to be manually released and it is thus paramount to carefully design the lifecycle of composed objects. While the distinction between aggregation and composition is still being taught by many text books, it is essentially irrelevant when programming in environments with automatic memory management. If you have garbage collection all of them are just composition, period.
Encapsulation on the other hand is a much more general principle than what you describe. It is foremost the idea of bundling data and the functions that operate on this data in one module. One way to implement this is by keeping the state of the module private and expose changes to that state through public services. So client cannot access the state on their own but have to tell the module their intend by sending messages. So encapsulation is not limited to objects but applies to services as well. Actually, one way of looking at objects is to look at them as services.
Here's an example of encapsulation
public class Counter {
private int n = 0;
public int inc() { return n++; }
}
or the same using lambda functions
var counter = (function() {
var n = 0;
var inc = function() { return n++; }
return inc;
})();
In both cases the data, that is the variable n
, is bundled together with the function inc
that operates on it. And there is no way any other function could ever access n
, thus we have an encapsulated module that provides counting as a service.
NB: exposing all of an object's inner state through accessors is actually a violation of encapsulation. Alas, it is such a common violation that many will confuse it with good object-oriented design.
Your question is a little vague so I'll try my best.
There's one good question to ask when you're trying to choose between creating a static or an instance method.
Do you need to persistent state between method calls?
Static methods are no different than traditional procedural functions. You give it an input and it should consistently product an output based on the input that is completely side-effect free.
Basically, you could use a traditional function declaration in it's place with no difference. The only benefit is that static methods are attached to a namespace where traditional functions are defined in the global namespace.
They don't matter so much in PHP because the language mixes both procedural and OOP styles but in languages that are pure OOP (ex C#/Java) there is no way to define functions so static methods are used in their place.
Static methods are perfectly acceptable to use when you're defining helper methods that act in a stateless manner. If you need data persistence between calls and/or find yourself relying on global variables, don't; use objects/instances instead.
Update:
Tom B made a very good point about unit testing. That static methods (like procedural functions) are inherently decoupled from the classes that they're attached to. So, if a static method fails, it may also cause any other instance method it's called in to also fail. It's a classic example of a side-effect.
That explains why I have encountered so many people parroting 'static methods are bad, mmmkay' in the TDD community. They have a completely valid point.
There are ways this could be improved. In the language, throwing an implicit exception when static methods fail. Technically, it wouldn't be any messier than doing type conversions. Assume it's going to break something if it fails. Of course, that assumes a higher degree of understanding to implement.
Either way, it comes down to the simple question.
Do you limit the language you use, or limit the ability to test your code's consistency?
My personal bias is toward expressiveness, the TDD school of thought's bias is toward consistency. YMMV.
I look forward to many years of religious wars over this topic.
Best Answer
No, you do not need to delete an object after its use in PHP. Let PHP's garbage collection take care of it for you.
There may be some obscure performance reasons to unset an object after you are done with it in very specific situations. But such cases are not everyday events, and they will be clear when you see them.