2

I dont have enough of a grip on OO design to determine whether I am designing application well or not.

Here is a simple Idea:

I want to code a application for travelling on Metro.

I started of definining the following:

Trainline Interface which defines some methods. Then I create a concrete class called Lines. Lines class does nothing much at all. It has methods like getNumberOfStations() but it has no idea about any number of stations so just returns null.

Then I have a CentralLine class which does the real work and this extends Lines and this provides the real implementation.

enter image description here

Questions:

  1. Do I need "Lines" concrete class ? Should I just not have CentralLine and CircleLine implement TrainLines (these are both train lines on the London underground)?
  2. Or should I remove TrainLines interface and just have the Lines concrete class ?
  3. Or should TrainLines be an abstract class ?
  4. Does the interface or the Lines superclass provide any value at all apart from a pretty class map diagram ... see above :)
  5. What things can OO do for me that would be cool ? What things should I be looking to do with OO design ?

Thanks !!!!

Adam Gent
  • 47,843
  • 23
  • 153
  • 203
drlobo
  • 2,139
  • 5
  • 32
  • 42
  • I am not sure, but I ask myself a question about this design: What is the difference in behaviour and structure between CentralLine and CircleLine. Isn't this maybe the same? – Markus Mar 31 '13 at 16:20
  • yes you are right ! both central and circle are instances of Lines ! They are theoretically the same but they can contain different stations. – drlobo Mar 31 '13 at 16:23
  • But for this difference you would not need different subclasses. Both classes have the capability to manage stations. – Markus Mar 31 '13 at 16:29
  • @drlobo Then `CircleLine` and `CentralLine` should not be classes but just instances. You should not have a class definition for each train station or train line. For example ( I dont know London so I'll use Boston/NYC) you don't have a class `PurpleLine`, `RedLine`, `GreenLine`). Part of the idea of OOP is reuse through polymorphism. – Adam Gent Mar 31 '13 at 16:29
  • 1
    I suggest having a concrete Line class (no "s" because each instance represents one line) that takes a list of stations as a constructor parameter. Unless and until you find some difference in behavior between two lines that cannot be represented reasonably in data structures, the presumption should be that each line is an instance of a single class. – Patricia Shanahan Mar 31 '13 at 16:30
  • So I could create a separate class called LondonUnderground which creates different "Line" objects to represent the different lines on the underground. Each "Line" object can then contain information about that line such as the names of the stations etc etc. – drlobo Mar 31 '13 at 16:46
  • Yes `LondonUnderground` would be what we call the [*Factory Pattern*](http://en.wikipedia.org/wiki/Factory_method_pattern) – Adam Gent Mar 31 '13 at 16:52

3 Answers3

1

Why not making your Lines class abstract? you would not have the problem of "returning null" => very very ugly.

In this case, you would not have TrainLines interface anymore.

TrainLinesInterface would be interesting if you plan to deal with many different kind of Lines whose implementation really differ. You would benefit thus with a great polymorphism by referencing your different classes in your code with TrainLines type.

To sum up, both solutions:

  • Lines as abstract class follows by concrete classes.
  • TrainLines as interface follows by Lines (or other types) as abstract class follows by concrete classes.

Keep in mind that abstract class implementing an interface doesn't need to implement the methods. Indeed, abstract class could defer this responsibility to concrete class. Thus, no need to implement dummy return null ;)

Mik378
  • 21,881
  • 15
  • 82
  • 180
1

Based on what you have shown thus far you really should only have one class: the Line class.

A couple of reasons (to answer 1-4):

You should use inheritance sparingly. Its difficult to briefly cover why this is but inheritance particularly in Java (where we don't have traits or multiple inheritance and mutability is rampant) is generally not good design. You can Google Gang of four composition over inheritance.

Classes should not be concrete things. That is you would not make a class w/ your name derived from Human. Classes are a category of things.

If you do need more types of Lines you just refactor. Particularly in Java where refactoring is so easy. I think they fundamentally teach software engineering/design wrong from what happens in the real world. In the real world you don't know the whole domain (or taxonomy) so you always start with the simplest model and then refactor.

To answer question #5:

What things can OO do for me that would be cool ? What things should I be looking to do with OO design ?

If you don't know about unit testing you should look into that (a good design means nothing if you can't test it... in fact if you can't test your code or its hard to test = bad design).

With OOP you should decide how you want to manage state. OOP is very good at managing in memory state. Its best benefit is modeling something like a video game or UI where you have lots of in-memory state.

Adam Gent
  • 47,843
  • 23
  • 153
  • 203
0

I dont see any real need for interface in your case. I would make Lines an abstract class and provide all common implementation in Lines class. CentralLine and CircleLine can use that default implementation and provide implementation for rest of methods.

Thumb rule is that whenever you have some common implementation then go for abstract class which is true for your case.

Interfaces can be very useful when you want to have implementation across hierarchies, also as same class can implement multiple interfaces it can be useful. But there is always a word of caution with interface that if new method has to be added then whole hierarchy might break whereas in case of abstract class you can simply put that default implementation in Abstract class without changing anything else.

Lokesh
  • 7,810
  • 6
  • 48
  • 78