tags:

views:

683

answers:

16

Hi!

I have a problem. My mind isn't working as I wish it would.

I'm currently working on a small 2D game-engine in C++, but I am now facing a deamon - I suck at designing a 'system of classes' that actually works. There are a blockade in my mind that disables me from seeing where I should use a class and where I should not. I was reading an article about engine-design and it purposed to use a 'State' class to manage the state of different game entries (I was using an int). It also suggested that all objects for the game (not io/video/sound etc) derive from either Renderable or NonRenderable classes. That's smart. I already know that that was a smart way of doing it - I mean, every object in Java is of baseclass Object right? Smart, I know that! How come I didn't do it that way? What do I have to read to really get into this mindset?

Another example. I'm taking this summer-course in Ruby (really simple) and we're supposed to design a camping site. Simple! So, a camping is a collection of 'plots' that each have a electrical-gauge to measure how much power the guest has consumed. My design was three classes, one for a Camping - that in turn used arrays of Guest and Plot classes. My teacher suggested that I use more classes. WTF(!) was my first thought, where, what classes?? Everything was a class in my opinion - until I realized, maybe the gauge should be a class to? Right now the gauge was an Integer in the Plot class.

I want to learn how to come up with a object oriented solutions to my problems - not just how to make the most obvious stuff into classes!

Tips/books/articles/blogs?

Keep in mind, I'm not new to programing. I'm two years into a collage degree in CS and have been programming as a hobby for many years! I'm 'just' stuck - and it's preventing me from creating any larger piece of software!

Sorry for the wall of text. Thanks, much appreciated Andreas

+3  A: 

Head First Object-Oriented Analysis and Design

I love Head First Books because they are fun to read. They have exercises and puzzles to scratch your head. I've read this book and found it very good.

The book covers:

  • Use OO principles (encapsulation and delegation)
  • Open-Closed Principle (OCP)
  • The Single Responsibility Principle (SRP)
  • Design patterns, UML, Use cases etc.
chikak
When you recommend a book, don't just post a link - explain why it is a good book and addresses the question.
anon
The whole Head First series is just brilliant, no matter how experienced programmer you are. It covers all the "mysterious concepts" in a very simple, non-academic way.
ohnoes
A: 

Haha. I remember that point. The whole "how the hell does this oo thing work?". Just keep at it, at some point it just clicks. It really is like a lightbulb going on. One moment it doesn't really make sense and then a split second later you're coding everything up in classes.

Try downloading some of the open source tools you will likely end up using and read the code. It'll give you something to reference your code style against.

Russell Troywest
A: 

Write a really huge piece of software, and throughout the process, the bigger it gets, the more extensiblity you'll need and the more good class design you'll need, thus next time you'll think ahead and make your class design good in the beginning...

Lawand
+1  A: 

Hi

Just remember there is never 1 solution to a problem. Turning everything into a class is also not the solution. Especially tiny things (like the gauge) might very well be an int or float member inside the plot class like you had.

My suggestion is that practice is a good teacher. Just keep on trying, and keep on reading. In time you'll be more and more fluent.

Toad
+6  A: 

My personal experience was learning Object Oriented Software Construction with Object Oriented Software Construction, 2nd Edition by Bertrand Meyer.

The book was invaluable to me at that time, and still remains the single book from which I've learnt most regarding OO programming and software construction in general.

Here are some of its strong points:

  • In Part A: The issues, a very good definition of software quality.
  • In Part B: The road to object orientation, a logical, step by step search for OO techniques in a way that makes the reader think the investigation is being done live, that is, as if there were still no known results. You'll probably acquire the mindset you're looking for from this part.
  • In Part C: Object oriented techinques, the real core of the book, you'll make your knowledge solid and learn very useful techniques regarding Design by Contract, Inheritance, Genericity, etc.
  • Part D: OO methodology: Applying the method well is a more practical approach on design. Still useful. See for example How to find the classes (22), which you can find online.

After these parts, more advanced topics come. I admit to still have not read some of the chapters completely, but by then you'll have already got most of the benefit from the book. Not that you can't get extra value from reading about Concurrency (30) or Databases (31).

Since the book uses the Eiffel language (designed by the author), this will put you in the right mindset and teach you to think. It will be easy to apply these ideas to other, more or less OO, programming languages.

Daniel Daranas
Thanks for the tip, I will try to get my hands on the book!
Andreas
+1: one of the most controversial books ever, however I like it
dfa
A: 

There's an essay in the book "ThoughtWorks Anthology" by Jeff Bay: "Object Calisthenics" in which he gives a set of rules for designing OOP sofware:

  1. Use only one level of indentation per method
  2. Don't use the else keyword
  3. Wrap all primitives and strings
  4. Use only one dot per line
  5. Don't abbreviate
  6. Keep all entities small
  7. Don't use any classes with more than two instance variables
  8. Use first-class collections
  9. Don't use any getters/setters/properties

On the first look it may look too strict to follow all these rules. Keep in mind that even trying to write some code that coplies them will make you better OOP designer.

Boris Pavlović
A: 

Peter Coad and Ed Yourdon wrote a book about it couple years ago. While not filled with new overhyped methdologies, this book provides good foundation for thinking in object style.

smok1
Slightly more than "a couple of years ago", I think you'll find. This book does not have a good reputation in the OO community.
anon
Yes, this book is written in a bit complicated language manner. I realize it does not have good opinion; however, I was learning from this book and ion fact quite liked it. So maybe it is not so evil at all?
smok1
A: 

In my opinion, one of the the best books I've read for learning object oriented concepts is:

The Object-Oriented Thought Process

For me, this book really gets you thinking in an object oriented way (well, the clue's in the title! :) It's fairly language agnostic, containing some small code samples throughout the text in VB.NET, C# and Java and frequently references many "greats" in the world of OO analysis and design, like Grady Booch, Martin Fowler and others.

Since the book helps you to think in an object oriented way, it'll often take a specific example and show the differences between the OO way of approaching a problem and the procedural way. This can be a big help if you're coming from more or a procedural background. It also touches on things like UML to help explain and understand the design behind complete libraries of classes (e.g. frameworks) and the interaction between classes and also the design of rich class hierarchies using concepts such as aggregation and composition.

CraigTP
+4  A: 

There are a blockade in my mind that disables me from seeing where I should use a class and where I should not.

When it comes down to it classes are a way to separate complex systems into simple parts that interact with each other. Try to create classes where otherwise you would be repeating yourself.

Right now the gauge was an Integer in the Plot class.

Does the gauge need to be a class? What would the advantage of turning it into a class be? These are the sort of things you always need to ask yourself.

  1. Game Engines are difficult to design. The separation of such a vaguely defined requirements is a complex process, read here: article on game engines
  2. Design is iterative and you'll refactor serveral times, don't be suprised by this.
CiscoIPPhone
+1 "Design is iterative and you'll refactor serveral times, don't be suprised by this." - I'm just starting to get this point! I'm refactoring some code I wrote a few months ago, using some design patterns, and yes it's a rich experience, but your statement totally applies! :)
Tony
A: 

I probably learned most about object oriented software development from Craig Larman´s Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development.

In his approach, classes are derived in a systematic way from use cases:

  • Nouns in the use cases are mapped to classes,
  • verbs to methods and
  • adjectives to member variables.

This, of course, works better for notions in the problem domain than, say, GUI widgets. Nevertheless, starting with a description/use case of the program to be written helped me to find better abstractions than when I omitted that step.

Jochen Walter
+1  A: 

For me OO didn't 'click' until I read a book about design patterns. If you're already comfortable with concepts like abstract classes, interfaces, etc that's only half the battle.

The next step is figuring out why you should prefer composition over inheritance, how to code to an interface and how to write your classes so that they are decoupled and well-encapsulated. Design patterns show you solutions to common OO problems and help you structure your code adhering to the above guidelines.

I can't recommend any particular books about C++ but the GOF book is the standard on Design Patterns (Java). I prefer books that talk about design patterns in a particular language so that you can get concrete code examples. Design Patterns In Ruby is pretty good, as is PHP: Objects, Patterns and Practice.

I get the feeling that your instructor doesn't particularly know what he's talking about. 'More classes' is pretty useless advice by itself.

Ali
+2  A: 

It pays to remember: OO is not an end in itself. The point of OO is to make development and, especially, maintenance of code easier over the lifetime of the product. Beware of the "OO for OO's sake" mindset.

j_random_hacker
Yeah, thanks for the heads-up. However at the moment I'm far at the other end of the spectrum ;)
Andreas
+1  A: 

Object-oriented

Object-oriented programming is about asking objects to do something: a deceptively difficult concept to correctly apply.

Goban

Consider a 2D game board, like for playing Go (called a goban).

Think first about the behaviour it requires to accomplish its task. This means listing the behaviour for an object rather than deciding on data the behaviours manipulate. For example a basic board might have the following behaviours:

  • Place a Go stone.
  • Remove a Go stone.
  • Remove all the stones.

For a computer version of Go, it is convenient to bring attention to specific areas:

  • Mark an intersection (e.g., triangle, number, letter, circle, square).
  • Remove a mark from a marked intersection.
  • Remove all the marks.

Notice that a goban does not need to provide a way to provide clients with a reference to the stone at a specific intersection. Instead, it can answer questions about its state. For example, a goban might answer the following questions:

  • Is there a black stone at a given intersection?
  • Is there a white stone at a given intersection?
  • Is there a mark at a given intersection?

It is not the responsibility of the goban to know the state of the game: that belongs to an instance of a Game (which has Rules). In real life, a goban is simply a stage for stones.

At this point, we could write an interface for a goban without knowing how the underlying implementation will work.

public interface Goban {
  public void place( Stone stone, Point point );

  public void removeStone( Point point );
  public void removeStones();

  public void place( Mark mark, Point point );

  public void removeMark( Point point );
  public void removeMarks();

  public boolean hasWhiteStone( Point point );
  public boolean hasBlackStone( Point point );
  public boolean hasMark( Point point );
}

Notice how the board is cleanly separated from both Rules and Games. This makes the goban reusable for other games (involving stones and intersections). The goban could inherit from a generic interface (e.g., a Board interface), but this should suffice to explain one way to think in terms of objects.

Encapsulation

An implementation of the Goban interface does not expose its internal data. At this point, I could ask you to implement this interface, write unit tests, and send me the compiled class when you have finished.

I do not need to know what data structures you have used. I can use your implementation to play on (and depict) a Goban. This is a crucial point that many projects get wrong. Many, many projects code the following:

public class Person {
  private HairColour hairColour = new HairColour( Colour.BROWN );

  public Person() {
  }

  public HairColour getHairColour() {
    return hairColour;
  }

  public void setHairColour( HairColour hairColour ) {
    this.hairColour = hairColour;
  }
}

This is ineffective encapsulation. Consider the case where Bob does not like to have his hair coloured pink. We can do the following:

public class HairTrickster {
  public static void main( String args[] ) {
    Person bob = new Person();
    HairColour hc = bob.getHairColour();
    hc.dye( Colour.PINK );
  }
}

Bob has now had his hair coloured pink, and nothing could prevent it. There are ways to avoid this situation, but people do not do them. Instead, encapsulation is broken resulting in rigid, inflexible, bug-ridden, and unmaintainable systems.

One possible way to enforce encapsulation is by returning a clone of HairColour. The revised Person class now makes it difficult to change the hair colour to Pink.

public class Person {
  private HairColour hairColour = new HairColour( Colour.BROWN );

  public Person() {
  }

  public HairColour getHairColour() {
    return hairColour.clone();
  }

  public void setHairColour( HairColour hairColour ) {
    if( !hairColour.equals( Colour.PINK ) {
      this.hairColour = hairColour;
    }
  }
}

Bob can sleep soundly, knowing he will not awake to a pink dye job.

Dave Jarvis
A: 

A simple way to come up with a reasonable set of things which probably should be objects (and hence, classes): write down a problem description of your task, like:

One a camping site, there are guests, and each guest has access to a few outlets. The software should be able to manage the power consumed by each guest, so it should know the outlets used by a guest and the power consumed through each outlet.

Now, create a list of all the nouns for a good idea of what classes (= kind of objects) are involved in your problem:

  • Camping Site
  • Guest
  • Outlet
  • Power

This is not necessarily a definitive list, but it's a good start.

Frerich Raabe
A: 

Hi,

One of the things which helped to get into OO mindset, along with the practices that earlier posts outlined has been, is to rewrite/improving the existing code you have written using OO principles.

For example :

a. In situations where there is a lot of if/else constructs then probably you can think of having a class hierarchy to distribute the branch codes accordingly, and to use polymorphism.

b. Any use of operators like (instanceof in Java) would indicate programming to concrete types and you can think how the instanceof check can be get rid of.

c. Use "Law of Demeter" as a guideline and see whether the coupling between classes is high

To an extent the practice of "Test Driven Development" also helped me since it forces you to think in terms of interfaces/behavior to be exposed by a class rather than just concentrating on how best solution to a problem can be coded.

sateesh
A: 

Maybe you will find Thinking in patterns by Bruce Eckel useful. You can download this book from his site for free (I can only post one link as a new member, so just click on the links there and you can find it). Although, the book is from 2003, maybe the ideas presented in this book will help you grow as a programmer in general.

Gert