Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: True OOP  (Read 24269 times)

0 Members and 1 Guest are viewing this topic.

  • Guest
True OOP
« on: August 15, 2008, 07:43:44 am »
Hi all,

I'm a newcomer to SFML and so I don't want to rub anybody the wrong way but I feel I need to mention something..

Objects (classes) in Object Oriented Programming have both Methods and Properties.

Methods typically do some calculation and return a value.
Properties typically HOLD a value and return it upon request.

I have noticed that some methods in SFML seem out of place as if they didn't always use OOP conventions.

Take, for instance:

Code: [Select]

unsigned int Input::GetMouseX() const
{
    return myMouseX;
}


This looks like it was written by someone who's been accustomed to Procedural programming (notice the Get/Set prefixes in methods prevalent throughout the entire library). If it were me writing this class, the MouseX would have been a protected int MouseX, etc. because it does absolutely nothing but return a value with no calculations.

Please note, I am totally not trying to knock any of the hard work that has been done.. Maybe just perhaps trying to figure out why it's been done this way. Maybe nudging for a change to a more pure OOP style. Maybe someone just needs to put me in my place, I'm not sure.

Thanks!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
True OOP
« Reply #1 on: August 15, 2008, 10:24:02 am »
Consistency, wrapping and flexibility. What if one day I change MouseX to be computed ? I'd have to change the public interface. The fact that internally the method does or not some calculations should not affect the public interface. I don't want things like that :
Code: [Select]
int x = input.GetX(); // --> because there are caculations inside
int y = input.Y; // --> because it's a direct variable
Laurent Gomila - SFML developer

Avency

  • Full Member
  • ***
  • Posts: 113
    • View Profile
True OOP
« Reply #2 on: August 15, 2008, 01:38:14 pm »
Getters/setters are quite common.
It's to allow internal changes without changing to public interface (otherwise you will need good refactoring tools).
And if nothing is calculated, most compilers will inline them, so it's only a personal matter of taste if you prefer input.GetX() or input.X.
And how do you access a protected property without a friend declaration?
You would need to inherit, which often makes sense, but not always.

A side note on OOP:
I think OOP is great, but no always the best way to do things.
I've seen pretty ugly constructs, just because "it had to be OOP".

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
True OOP
« Reply #3 on: August 15, 2008, 05:56:26 pm »
I think what you're saying is just wrong(at least if I understand what you want to say: you're saying that you should access the membervariables directly, right?), because in a truly object oriented program classes should never make their membervariables public.
The concept is called data encapsulation and is one of the basic things in objectorientation.
Just because a class can offer public membervariables in C++ it's not said that it is object oriented.

  • Guest
True OOP
« Reply #4 on: August 15, 2008, 11:26:52 pm »
Yes.. Either making it public (not protected) or overloading some Get/Set methods.

Get/Set is totally throwing me.

An Apple does not have a GetSkinColor().. It has a SkinColor().

As its creator I can:

void

If one method needs to "get" and one needs to "set" it should be overloaded, not separated into Getter/Setter IMO.

Code: [Select]

#include <iostream>
#include <string>

using namespace std;

class Apple
{
    protected:
        string color;

    public:
        Apple();

        string Color();
        void Color(string);
};

Apple::Apple()
{
    color = "Colorless";
}

string Apple::Color()
{
    return color;
}

void Apple::Color(string newcolor)
{
    color = newcolor;
}

int main()
{
    Apple myApple;
    cout << "Lets talk about my apple." << endl;
    cout << "My apple is " << myApple.Color();
    cout << " but I can change it.. " << endl;

    myApple.Color("Green");

    cout << "Now my apple is " << myApple.Color() << endl;
    return 0;
}


This way just makes more sense to me.. If it doesn't to you, that's cool too. It'd probably be worth it to regex-out the Get/Set prefixes in the source if it really bugged me too much :-)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
True OOP
« Reply #5 on: August 15, 2008, 11:57:28 pm »
So it's just a matter of naming convention. We could talk about naming conventions for hours if you want.
Laurent Gomila - SFML developer

Ankou

  • Jr. Member
  • **
  • Posts: 52
    • View Profile
True OOP
« Reply #6 on: August 16, 2008, 12:09:58 am »
Quote
An Apple does not have a GetSkinColor().. It has a SkinColor().

But it's still a method => an action.
You can get the Skin color of an apple => you can GetSkinColor()
but you can't SkinColor() an apple.

Wizzard

  • Full Member
  • ***
  • Posts: 213
    • View Profile
True OOP
« Reply #7 on: August 16, 2008, 01:07:11 am »
Is there any libraries you can name that use that method?

I have seen many libraries that use get/set accessors for their member data.
These sort of things need to be consistent in order to aid programmers in moving from library to library.
If it really bugs you that much, I suggest you relax on the perfectionism a bit.

  • Guest
True OOP
« Reply #8 on: August 16, 2008, 04:43:41 am »
Quote
We could talk about naming conventions for hours if you want.


You're right and I think I've ruffled some feathers and nobody has agreed with me so I'll bow out gracefully. I found SFML in the middle of wrapping SDL OOP style so I'll waste my time with that for now and tinker with SFML later on :-)

Sorry about that!

<backs up slowly>