Page 9 of 10
Re: Namespaces and abstract class names
Posted: Fri Feb 11, 2011 5:02 pm
by Christopher
josh wrote:Sure, but what's not suggestive is that "1 reason to change" and "1 responsibility" mean roughly the same thing.
No, my point was that what one programmer might consider 2 reasons to change 2 responsibilities another might consider to only be 1 change/responsibility. It is like the DB Adapter discussed above. Jenk might consider things as multiple responsibilities where as I might consider them all part of the Adapters core responsibility.
Re: Namespaces and abstract class names
Posted: Fri Feb 11, 2011 7:33 pm
by Jenk
Christopher wrote:Jenk wrote:Ok, but it's also the opinion of the GoF, Martin Fowler, Michael Feathers, Bob Martin, Jason Gorman, Kent Beck, Nat Price, Steve Freeman.. etc. Every "good code" book out there will tell you this. I'm not going to ignore all those collective years of development experience, just because I think it is "not bad"
For
one object to have
more than one responsibility is possibly the most basic of code smells

This is an interesting point, although not all those guys and every book will say exactly what you are saying. Maybe the Responsibility Driven Development guy Bob Martin would say something close to what you are saying. I recall that his point was that a class should only have one reason to be changed. I kind of get his idea but I do get the sense that the definition of what a "responsibility" and a "change" are is a little subjective. Still I do think your point gets to the general goal of high cohesion and low coupling.
Jenk wrote:Already in the post asking What to do with different DBs you've listed a number of roles that, in your example, should be maintained by a single object - this is wrong. Each of those roles should be maintained by separate objects, and kept in a composite.
You switched from responsibilities to roles somewhere in there. Those are different concepts. I think an object might have a single responsibility but have several roles -- especially if its functionality is basic/generic. I think we should stick with responsibilities.
And again this gets back to the question of whether a class can use inheritance and have a single responsibility and reason to be changed?
I consider roles and responsibilities to be a 1:1 relationship. A role is for a responsibility. The role of a controller is to control. The role of a repository is to store objects. The role of a factory is to manufacture an object, etc.
Hope that clears up my definitions of the two words
Usually I find that if I had to describe what a class does in one sentence, that if the words "and" or "or" appear anywhere within, there is a very good chance it could (and thus in my opinion should) be split.
Oh and just to clarify, the role of a composite is to compose/collaborate the dependent objects :p A Car is only a car when it has its dependencies, otherwise it is a pile of car parts.

Re: Namespaces and abstract class names
Posted: Fri Feb 11, 2011 10:44 pm
by Eran
As for GoF using inheritance.. which patterns? The only ones I can think of were patterns for dealing with problems that inheritance created in the first place.
First of all, all patterns are aimed at solving common problems with code structure, obviously that includes inheritance. There are also patterns for composition.
I'm quoting the wikipedia page that summaries the book -
Favor 'object composition' over 'class inheritance'
Using inheritance is recommended mainly when adding to the functionality of existing components, reusing most of the old code and adding relatively small amounts of new code.
"Favors" and "using is recommended when" does not imply "never use inheritance". At any rate, even it were, this is not a religion, you should use what's most appropriate for your situation.
Among patterns that use inheritance are the structural patterns group - Adapter, Bridge (sometimes), Decorator and so forth. Those sometimes don't need inheritance and sometimes do, depending on circumstances.
Again, I'm all for composition when the situation lends itself, but lets not get too religious about it and use the right tool for the job.
Re: Namespaces and abstract class names
Posted: Sat Feb 12, 2011 6:35 am
by Jenk
I don't think anyone has said otherwise, except perhaps with more emphasis on the "favour composition".
It may also be worth noting that a lot of the patterns mentioned are the first stage of a refactoring. I don't think anyone would advocate having a decorator or bridge as the finished article

Re: Namespaces and abstract class names
Posted: Sun Feb 13, 2011 1:45 am
by Christopher
Jenk wrote:I consider roles and responsibilities to be a 1:1 relationship. A role is for a responsibility. The role of a controller is to control. The role of a repository is to store objects. The role of a factory is to manufacture an object, etc.
Hope that clears up my definitions of the two words
Usually I find that if I had to describe what a class does in one sentence, that if the words "and" or "or" appear anywhere within, there is a very good chance it could (and thus in my opinion should) be split.
It clears up your definition, but my problem is that you say "a role is
for a responsibility" but I don't quite know what that means. Ok ... you say that a controller and repository and a factory have roles. Then when you say
describe a class in a
sentence then if you say 'and" or "or" then maybe is should be
split. So you have a bunch of words talking about lots of general things which I generally agree with. You also have your own constraints with you think describe means, your arbitrary limit of a sentence, etc..
But you have wandered away from some specifics about what a "responsibility" or a "reason for change." And you brought Bob Martin and Responsibility Driven Development into the conversation. And I can certainly describe a controller and repository and a factory and use "and" or "or". because there is some complexity in those patterns. But, as I said before, you might describe them at a higher level and not have "and" or "or". So whose "responsibility" or a "reason for change" do we go with -- yours or mine?
And none if this really gets to any specifics about whether all this good things you describe cannot be done with inheritance. Or for that matter whether there are limits to the power of composition as well. I am a little leery of magic bullets. These are tools for our use that have different features and functionality.
Re: Namespaces and abstract class names
Posted: Sun Feb 13, 2011 7:49 pm
by Jenk
I didn't bring RDD into the discussion per se, I name dropped Bob Martin as someone who thinks classes should only have one role and one responsibility, as he wrote in his Clean Code book (The Single Responsibility Principle).
Classes should be small, they should only have one responsibility (and thus role) and .. I can't make it any clearer than that, you'll have to read the book for yourself.
So why stop at classes? Why not have objects that are small, have one responsibility? Inheritance leads us away from this. Instead of inheriting that class, why not use it as a dependency?
We've already listed the benefits provided by composition over inheritance, how about someone try listing the benefits of inheritance over composition? We're going round and round in circles, the same questions being answered with the same answers that are apparently not satisfying some. So why not flip the conversation? Why should anyone favour Inheritance?
Re: Namespaces and abstract class names
Posted: Mon Feb 14, 2011 1:55 am
by Christopher
Jenk wrote:Classes should be small, they should only have one responsibility (and thus role) and .. I can't make it any clearer than that, you'll have to read the book for yourself.
Ok ... but then you say small is 100 lines and I say small is 300 lines. Whose small is the right small. You say a class as two responsibilities and to me they are the functionality of a single responsibility.
Jenk wrote:So why stop at classes? Why not have objects that are small, have one responsibility? Inheritance leads us away from this.
Why does inheritance lead us away from having one responsibility? I don't see how it has to. They seem like separate issues. Simply inheriting code does not add responsibilities.
Jenk wrote:We've already listed the benefits provided by composition over inheritance, how about someone try listing the benefits of inheritance over composition? We're going round and round in circles, the same questions being answered with the same answers that are apparently not satisfying some. So why not flip the conversation? Why should anyone favour Inheritance?
Well an obvious one is that methods can shared class properties with an inherited class. I also mentioned the syntactical simplicity of inheritance. Another is that you simple add "extends Foo" and the language takes care of the wiring that you need to do with composition.
My question was not whether we should favor inheritance in all cases. My thesis was that there are common cases where I don't see a advantage to composition or inheritance - but inheritance is a simpler solution. I guess I am asking whether it makes sense to take an Occam's Razor approach. In those cases, certainly you could use composition if you prefer. But can you say inheritance is bad in those cases for other than preference reasons?
Re: Namespaces and abstract class names
Posted: Mon Feb 14, 2011 6:41 am
by Jenk
er.. ok, I did post a reply that took nearly 20mins to think out and write, but now it has gone. It was definitely here earlier.

Re: Namespaces and abstract class names
Posted: Mon Feb 14, 2011 6:53 am
by Weirdan
Jenk wrote:er.. ok, I did post a reply that took nearly 20mins to think out and write, but now it has gone. It was definitely here earlier.

Logs indicate the only edit/delete in this thread was my edit to Josh's post (fixed some tags as far as I remember).
Re: Namespaces and abstract class names
Posted: Mon Feb 14, 2011 7:19 am
by Jenk
Odd.. will see if I can fish it from history/cache.
Re: Namespaces and abstract class names
Posted: Tue Feb 15, 2011 5:08 am
by Jenk
Ok, we'll couldn't retrieve from history/cache. Maybe I never actually submitted but thought I had.
Anyway, the crux of it was this:
If class A extends class B, we can never instantiate A without the behaviour associated with B.
But if we were to use B as a dependency, we are no longer tightly coupled to it - we are only coupled to the interface.
Code: Select all
class A {
private $b;
public function __construct($b) {
$this->b = $b;
}
/* ... */
}
So whilst it is obvious that "extends B" is less typing than the alternative (which is something I wouldn't consider a factor anyway) I feel it to be much more beneficial to use it as a dependency. I could, for instance, now instantiate two object of type A with differing implementations of B - I couldn't do this if inheriting.
Re: Namespaces and abstract class names
Posted: Tue Feb 15, 2011 7:43 am
by Eran
On the other hand, you now need to instantiate b to instantiate a. You can no longer just instantiate a.
A counter example of using inheritance over composition - extending classes share the scope of their parents when instantiated. On the other hand, composed classes must use a public interface always to communicate, and must pass data as parameters since they do not share the same scope. I know you don't believe in the private/protected keywords, but those of us who think they give useful syntactic addition, will find sharing scope between extended classes useful.
Re: Namespaces and abstract class names
Posted: Tue Feb 15, 2011 3:10 pm
by Jenk
I've since been "converted" about the public/private scope. Though I'm firmly in the "it's public, or private" camp. Probably because of .NET's stupid implementation of virtual/override where by a method
must be marked as virtual in order to override it. Also worth noting is that private methods are only born from refactoring/extracting - never "designed"
And having to instantiate B everytime I want to use A is perfect. I don't care much for hidden couplings.

Re: Namespaces and abstract class names
Posted: Tue Feb 15, 2011 3:21 pm
by John Cartwright
Jenk wrote:I've since been "converted" about the public/private scope. Though I'm firmly in the "it's public, or private" camp. Probably because of .NET's stupid implementation of virtual/override where by a method
must be marked as virtual in order to override it. Also worth noting is that private methods are only born from refactoring/extracting - never "designed"
And having to instantiate B everytime I want to use A is perfect. I don't care much for hidden couplings.

Oh no, I can feel this discussion moving to protected vs. private now.
//never uses private..
Re: Namespaces and abstract class names
Posted: Tue Feb 15, 2011 7:13 pm
by Eran
Yeah, I never use private either - but on the other hand, I can understand how for someone who doesn't use inheritance it shouldn't make much of a difference.
What about the shared scope, Jenk? how do you resolve abstracted / black-box code dependencies using composition, where you can't share the scope / state of the objects without passing it explicitly between the composed classes? and when you do that, you are also violating your "one role / responsibility" rule