That hits the nail on the head. One important thing to note about object oriented design is this, you're planning a system of interacting objects. That means you're objects will work together. Many a beginner programmer, including me , don't grasp this. You're objects should work together. They shouldn't be isolated from each other so you only make separate instances of them, you should be using them together.
Object-oriented design is the process of planning a system of interacting objects for the purpose of solving a software problem.
This leads into the first Principle of good object-oriented design
The Single Responsibility Principle
In object-oriented programming, the single responsibility principle states that every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.
This is the fundamental building block of object-oriented design. Before we continue, let's take a closer look at what a responsibility is. In programming, a responsibility is something the class handles or does. Let's use a pong example:
When I first programmed pong, I had my Paddle class drawing itself, checking for collision, and updating itself. <-This was how all my other classes were designed too. This led to fragile code that would break if I changed any class, and the only way to fix it was to go through all my source and header files to fix the problem. The single responsibility principles goal is to make the above problems nonexistent in your code, and it largely succeeds.
Let's look at how we could fix this:
Have the paddle classes main goal to only update the paddles position and values. It doesn't draw the Paddle to the screen anymore. Do the same for the Ball class and the AIPaddle class. Then create another class called GameDraw. This has one AIPaddle, one Paddle, and a Ball. All this class does is use my get() functions to draw my objects to the screen. This means making a change to how I draw the screen doesn't affect my classes at all, and changing how I update my variables doesn't change how I draw my objects. Then I create a gamelogic class. This class calls all my Update() functions, thus making a change to how I update my objects won't change this class, and making a change to the order I update or what I update won't change the other Object's classes. Then, I create a BaseGame class. This class' responsibility is to run the game. It includes the gameobjects I need and a GameDraw/GameLogic class. Now, changing my class' won't mess up the rest of my code, because my classes are handling their responsibility, and the rest of my classes don't have to deal with them.
I hope all beginner programmers can read either this, or another article about this, because the Single Responsiblity Principle is extremely important to writing bug/error-free code, and will save you a lot of headaches by isolating what's causing problems, while still letting your classes work together.
On to Data:
Encapsulation is also fundamental, and it isn't something I'm going to go into length about, because considering almost every tutorial you will see uses it in the correct way, and in most books it is expressed at length. But, it is worth a mention. In fact, it's worth more than a mention. If you don't use the single responsibility principle, this is the next best thing. The idea behind encapsulation is:
Hide implementation details in a class from users of the class, exposing only a public interface
This goes hand-in-hand with the Single Responsibility Principle. You only want the users of your class to use your member functions to do what your classes intent, or responsibility, was. You don't want some other user using your classes member data to do something that the class has no intention to do. The most common way to go about this is to make the data members your class needs private and only use them in your classes member functions. This brings on get() and set() functions.
A get() function returns one of your classes data members.
A set() function changes the value of one of your classes data members.
Let's get this out of the way: Set functions are not object oriented. The only time set functions should be used is in cases where they are part of your classes responsibility. Get functions, on the other hand, are very important. Let's use the pong example from earlier. Imagine this:
The paddle class' responsibility is to update the data values. If it is gong to update the position it needs the Sprite and Image that the class is using. I include the Sprite and Image in the classes data members. Now, to draw the class in GameDraw I need to use a sprite. Instead of making an all new sprite or going through pointers, I just use a get() function. I say screen.draw(Paddle.GetPaddleSprite()). This is object oriented, because it allows the other class to perform it's responsibility, and allows my class too, while not making my class more fragile. This is the basics of encapsulation, but there's far more to it.
I would add more Principles, and I will later. I just have to go eat lunch. I hope this helped many a-new developer, and feel free to add your own principles, ideas, and corrections below !
Edited by superman3275, 13 October 2012 - 11:27 AM.