views:

217

answers:

4
+7  Q: 

Writing for others

What are the main and most important rules (pros and cons) I have to apply when I write a class that will be inherited by third party.
Thank you.

+10  A: 

The basic rule is: Make Interfaces Easy to Use Correctly and Hard to Use Incorrectly. It's from the 3rd edition of Scott Meyers' excellent book Effective C++.

Here are a few more pretty good guidelines for class design.

sbi
John Dibling
It's a daily struggle, but it's worth it :)
Matthieu M.
+7  A: 

Rules:

  1. Don't. Avoid using inheritance wherever possible.

  2. The class must have at least one virtual function. specifically the destructor must be virtual.

  3. The class should probably be abstract.

anon
when you say virtual, you can't do without inheritance
Neeraj
I'm on the "Don't" side too. Many learned Object-Oriented Programming, but skipped Object Programming completely. Do not provide to 3rd parties classes to inherit - provide them with ready objects to use.
Dummy00001
@Dummy: What you refer to as "Object Programming" is more widely known as "Object-Based Programming". (And I completely agree with you.)
FredOverflow
DEFINITELY avoid inheritance when you can. The biggest roadblock I find to understanding code is figuring out what class things REALLY are when there's a deep inheritance tree in play.
Michael Kohne
+2  A: 

SOLID...

S    SRP    Single responsibility principle, the notion that an object
            should have only a single responsibility.
O    OCP    Open/closed principle, the notion that “software … should
            be open for extension, but closed for modification”.
L    LSP    Liskov substitution principle, see also design by contract.
I    ISP    Interface segregation principle, the notion that “many client
            specific interfaces are better than one general purpose interface.”
D    DIP    Dependency inversion principle, the notion that one should
            “Depend upon Abstractions. Do not depend upon concretions.”
            Dependency injection is one method of following this principle.

taken from http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29

(or whatever acronym's your flavour of the month;)

HTH

Andy

Andy
I've always disagreed with S, don't find O helpful, don't think L substitution has anything to do with design by contract, and don't think much of the last two. If I hadn't posted an answer myself, this would be a -1 from me.
anon
Yeah to each their own! I'm all for S personally. It's kinda similar to 'Prefer minimal classes to monolithic classes' and 'Give one entity one cohesive responsibility'. I find it aids clarity, reuse, and lets me be more agile in combination with 'Prefer composition to inheritance'. I find O quite easy. Whether L is design by contract is kinda irrelevant - it's perhaps an extreme form, but I feel it follows from 'Treat class design as type design'. I can imagine I being useful, but I've not written code that needs it myself. I think D is very important for large long-term systems. 0.02c
Andy
Would be interested in specific reasons/problems with the points. For the S - do you find it's too black and white, or do you think it's completely in the wrong direction?
Andy
@Andy I think its wrong. Take a bank account class for example I can think of at least three responsibilities without raising a sweat. Also, have you ever used CRC cards? You end up with a list of responsibilities on each card.
anon
@Neil When you say, 'Take a bank account class,' you've bypassed the class design step, which is what this is all about! Just because the bank account class that you study in 'OOP with Java 101' doesn't follow the principle of single responsibility, doesn't mean _a_ bank account class can't, or that it wouldn't benefit. (Not that I follow _any_ rules religiously, mind - I just find trying to focus on one responsibility helps me day-to-day.)
Andy
Interestingly, there was a discussion on a Ruby list recently about design, and it uses bank accounts as an example. It takes a bit of digestion (for me at least). It's James Coplien's idea of Data, Context and Interactions (DCI). Coplien's mails are http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/357461, http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/357539, http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/357705. An article is http://www.artima.com/articles/dci_vision.html.
Andy
@Andy I haven't bypassed anything. In fact I was responsible for writing a couple of OO design courses for a commercial training company. One of the designs the courses used was for - you've guessed it - a bank account. And I've never studied Java, 101 or otherwise. Please do not attempt to invent experiences for me - I've had quite enough of the real thing.
anon
quote: An account is a collection of use cases. ... the real objects are transaction logs and audit trails. They become re-configured in interactions on every use case, where the use cases are at the level of a Context object called an account. Except for its housekeeping references that set up the current role / instance binding at the audit trail and transaction level, the account is stateless. Your bank account is not a number sitting in memory or sitting on a disk somewhere, anymore than your money is sitting in a bag on a shelf in a bank somewhere. It is a computation: a use case.
Andy
@ Neil - Sorry, really meant no offence. I thought you chose bank account because it's a common starting place on OOP courses from what I gather, and that we'd both be imagining the same thing. You say 'Take a bank ... raising a sweat.' That seems a circular argument to me, because you're designing the class yourself (albeit tacitly, in your head) and then saying it doesn't follow a principle of design, ergo the principle's not sound. What I want to say is, just because it's possible to design an account class with many responsibilities, doesn't mean it's impossible to design one with only one
Andy
+1  A: 

I'm coming from a Java background, so the rules on inheritance are a little different, but here's my perspective:

  1. Don't be afraid of inheritance. Most languages have it in some form or another, it's a very powerful paradigm, and it only stays hard if you don't use it.
  2. Don't assume you know how future developers are going to use your classes later. I can't begin to count how many times I've had to copy an entire class just because some method or member was private. It's "O" in Andy's answer above - and it's a HUGE point.
Curtis
Actually, inheritance is easy if you don't use it.
John Dibling
Driving a car is easy if you don't do it. Learning something new is easy if you don't do it. Stagnating is the easiest thing to do.
Curtis