How to make this OOP?

BlitzMax Forums/BlitzMax Programming/How to make this OOP?

Glenn Dodd(Posted 2007) [#1]
Hello,
This section of code opens a text file and examines it, byte by byte, for preconceived values.
It works. I have no issues with how it works. There are more checks to be done on the rest of the contents of the file but they don't matter for todays question.

This is all Procedural Programming (from what i understand).
Can you give me some tips on how i should change it to be more OOP?

Files will always be of varying length/size and only the first part will be static (matching byte by byte).

I am happy with responses saying "hey it works, you don't need to change it" but since i am still learning i would like to know the different styles.

Regards
Glenn





Winni(Posted 2007) [#2]
Going OOP not always makes things easier and it also does not always make as much sense as the OOP fans claim.

-- The -- advantage of OOP, in my (sometimes not so) humble opinion, is encapsulation.

In your case, this means that you basically put the whole thing in an own class and instead of declaring all variables as globals, you make them private. You can pass the name of the file you want to examine to the constructor of the class and let the method that does the actual work return the result array. This way, all the temporary and worker variables are hidden from the user and the rest of the code --- encapsulation.


CS_TBL(Posted 2007) [#3]
yes yes, "\o/ yay \o/" for encapsulation and datahiding. Globals might look tempting at first sight, but are immensely evil in the long rung when an app keeps expanding and expanding and you run out of sense making namespace.


Winni(Posted 2007) [#4]
While we're at it, Wil Shipley (Delicious Monsters) recently wrote some interesting things about OOP in his blog:

http://wilshipley.com/blog/2007/05/pimp-my-code-part-14-be-inflexible.html


Gabriel(Posted 2007) [#5]
As the name suggests Object-Oriented programming means you should be thinking about objects. I've taken a quick peek at your code, and I don't see anything crying out to be an object. That's the test I always make. Is there an obvious object? In your code, I don't see it, but then you know your code better than I do.

If you had it more generic, say a function ( or set of functions ) to read and write to .ini files then you could have any IniFile object, read them, write them, add entries, remove entries. That's your object. Indeed entries could be objects too. In your code, you look to be hard coding for a specific purpose and as such, I don't see much reusable code that I would call related to an object.

Just my 2c.


Glenn Dodd(Posted 2007) [#6]
Gabriel - nothing sort of jumped out at me either but it is always good to ask other people.
CS_TBL and Winni - I will need to read up a bit more on your comments.

All feedback appreciated.

Cheers
Glenn


H&K(Posted 2007) [#7]
I agree in part with Gab, cs and wini, but to continue their comments, if all the functions are being passed the same first parameter ie
RotateCamera(Camera,rot):PositionCamera(Camera,x,y,z)
etc then its probably a case for an object, in the pure sence.

However, in the drive to never have a Global, I would also say that if you do have seven globals that are always to be used together, I would be very very tempted to put them into a Type, so as to have them in the same namespace, probably keeping them as Globals.

Once I'd done this, it then wouldnt be behond the relems of possibility, that I would also put the fuctions that used those globals inside that "Namespace" (ie Object)

It wouldnt be an Object in the This is an "Object" sence, ... but well you know what I mean


Glenn Dodd(Posted 2007) [#8]
H&K - Not sure if i understand correctly.
I create an object and have those values still as Globals? (or locals?) and put the functions into the type too? Do these functions then become methods?

I will have a stab at OOPing this on the weekend based on suggestions from you all.

Cheers
Glenn


H&K(Posted 2007) [#9]
1) As Globals, and they stay as static to that Type, that mean that even if you made 20 instances of that type, there would only be one of each global
2) No, they stay as functions of the type

What you have is Variables and Procedures of either the type/class itself or instances/objects of that type

Globals and Functions defined within the type are part of the type, but the dont belong to any instance of it, really you can look at them as simply haveing a longer name than before
AType.GlobalVariable  AType.Function:Int() etc
Fields and Methods on the other hand belong to a specific instance of that Type, specificly when in Methods the type "Self"

As an example, if I want to create a new Instance of MyType, I could do this
MyInstance:MyType = New MyType
MyInstance.MethodAllocate(Parameters)
or
MyInstance:MyType = New MyType
MyType.FunctionAllocate(MyInstance,Parameters)
The first one calls the allocate Method inside MyType. This method knows that is was called by MyInstance, and infact thinks of itself as part of MyInstance and reffers to it as "Self"

The second example the allocate is a member of MyType, but you can see that it isnt called by the instance, but rarther by the Type itself, (Self still works, but Mark has said that it really makes no sence in a function in a type, and is really only there for lazy typers with intellisence in the IDE), and MyInstance needs to be passed as a parameter.

The way I do this allocation (for example) is
MyInstance:MyType = MyType.FunctionCreate(Parameters)
The function then News the Instance and passes the Parameters to the Allocate Method.
(I do this for a few reasons, partly becasue it make inheritance easier, but mostly because I dont like NEW as a command in "open" code)

I do agree with Gab, for whilst I would put it all inside a type, that would only be because in my mind it is tidyer, not because Im makeing in any real sence an "Object" in the OOP meaning. All I'd really be doing is creating a subProgram/namespace that contained all the variables and fucntions, then I would just call it as though each function was still a normal function, but now with a longer name.


CS_TBL(Posted 2007) [#10]
Another bit o' info about avoiding globals. Imagine you're creating a pinball game using globals. You have global variables like BallX, BallY, BallSpeed, BallAngle, BallRadius, BallImage, LevelWidth, LevelHeight, LevelMap, Score, Highscore, Lives, etc. etc.

All nice, the game works. And then suddenly you want to make a 2-player option where you'd have 2 of such pinball machines next to eachother. It would mean you need all those global variables twice. What could you do? Make 'em an array of 2? Could be, but those variables are everywhere, it's quite tiresome to run through the whole code to fix things.

OO?

You'd have all those varibles in a pinballmachine type, and then simply:

Player1machine:TPinball=New TPinball
Player2machine:TPinball=New TPinball

or

Local Player:TPinball[2]
Player[0]=New TPinball
Player[1]=New TPinball

That's far more easier than to manually change all those variables.. and this is actually a very simple example.
Ofcourse, do you need Bmax for this? Of course not, I was doing this in B+ already with banks, but instead of "Player1.shootball" I'd be doing "shootball Player1".

The problem with globals is the sheer lack of namespace you'll run into, sooner than you'd hope. If you have a lot of different 'objects' and they're all destined to use globals, then you either get cross references, or you're really cooking some extravagant names.

Another nice one, imagine you'd be making your own gadgets (knobs, sliders, buttons, etc.). If you would be doing this without OO and with global functions, then you'd get stuff like: UpdateKnob MyKnob, UpdateSlider MySlider, UpdateButton MyButton. While not the end of the world, it's still some typing work.

When doing OO, an update method is part of such a gadget. So it'll be MyKnob.update, MySlider.update, MyButton.update. What you gain is that you loose those global functions. Within the type (e.g. in some method of 'Slider') you only need to type 'update', that's what you do most of the time anyway: updating from within the object.

About namespace, when still doing the non-OO way and use global functions, it could very well be that you could commit yourself to names you're aware of so that you will avoid nameclashes yourself. If you keep some guidelines this could very well possible, since *you* are the one who's managing the whole shebang.
And now you want to use library x from coder y (since it's such a good library from a respective coder) .. now all of a sudden you don't control your own sources anymore since it has external code, which is usually quite hard to read. (at least it is for me!) If it's such a respective coder then you're lucky since all the stuff would prolly be tucked away in types, just as I wrote above. But what if the library is good, but not very cleverly written? What if you were using some UpdateKnob function, but the coder of that lib does so too (for a whole different reason/situation of course)? Here you see the benefits of datahiding. You can hide zillions of variables and methods into a class. Without OO you'd have zillions of variables and functions all being global and all being around messing up with whatever comes next -which you can't always know!-.

So, what globals are allowed? Well, depending on the scale of your app there are perhaps some. Perhaps -for a game- having variables such as gamewidth and gameheight as a global seem obvious, but is it? In most cases it'll do.. but what if you want to run multiple instances of the game in multiple windows, each with its own size? True, perhaps not a realistic example, but technically it's a perfect example. If you store gamewidth and gameheight in your game type then you can do this. When you make 'em globals, then you can't.. (unless you make 'em an array orso)


Glenn Dodd(Posted 2007) [#11]
H&K and CS_TBL - Thank you for your responses.
This is why i posted the original question...

1 - So i can get some specific feedback to my code
2 - So very well written explanations in a more generic sense will be posted for other readers.

Thank you again.

Glenn