How many Max users still hate OOP?
Miscellaneous Forums/General Discussion/How many Max users still hate OOP?
( No Mike, please let's not have a debate )
I'm just wondering if it's worth me writing a module which uses my HGE wrapper, but does so in a procedural manner for people who use BMax but hate OOP.
Why do you hate OOP ? For the most part I use bmax because I like OOP :)
Once I got my head around it, I thought it was great. The only problem I have with OOP is that now when doing Maya MEL scripting at work I miss all those nice OOP features, if I had never tried BlitzMax I would still be happily ignorant. :-P
Ragnar
Why do you hate OOP ? For the most part I use bmax because I like OOP :)
He didn't say he hates OOP. He was asking if it's worth it to make a non-OO interface for his HGE module(s).
As for my opinion, the answer is no. What are the chances they'll get it even with a procedural interface if they can't understand how it works with the OO interface?
I have tried a few times to understand OOP, But I can't work out what it is, or how it helps me. I may be looking too hard for something that is actually quite simple.
Anyway, I usually try to program my stuff in B3D in types and at least thats as much OOP as I understand.
hey... what... me... ??!! debate... you must be thinking of another Red Ocktober... meee... never :)
BoomBoom... just think of objects as instances of TYPEs with functions, for the most part...
then, once that starts becoming second nature, then try building new TYPEs from the ones you just made, and using the functions from the new TYPE and the ancestor TYPE...
--Mike
OOP is a lot closer to the way people actually think. Once you work with it it's definitely tough to go back. As for you question, I think it's rather fruitless. People that don't like OOP probably won't be using BMax anyway.
I use Max, and I haven't fallen in love with OOP.
Some aspects of OOP are nice. For example, methods. At first, I didn't like putting methods in my types. I thought it would be messy. And the way most people format them, they are. I found a way to format them that I'm happy with though.
Methods are nice, because they save you a lot of typing when accessing the object's fields, and you can treat functions that return information about an object just like you would variables.
On the flip side, you can't actually treat functions just like variables. I can't assign a function a value, I have to pass it values. So it is not entirely hidden that Sprite.X# is not the same as Sprite.Y#().
In addition it is hard to design objects that make sense, if you want to keep certain things conceptually seperate.
For example, in my sprite system, I have a sprite type, an animation type, and a physics type. I have to have the animation type if only to store animation instances, but I could stick almost all the functions in it in the sprite type. And all the physics stuff could be stuck in the sprite type as well.
But conceptually, this doesn't make sense to me. If I have a calculator and I want to push it across the table, I don't say to myself Calculator.ApplyForce! Though I might think Hand.ApplyForceTo(Calculator). But what if nothing, at least, no other sprite, is actually applying a force to that calculator, but the force most certainly is coming from an external source, say a point? Unless I want to create a point object just to hold points and then give points the ability to apply forces to objects which conceptually is just silly, the object oriented paradigm breaks down. Cause if I go Calculator.Accelerate() then I'm implying that the calculator has a rocket strapped to it.
So, I don't agree that OOP is closer to the way people think. I think people make lists of things they need to do, and do them.
Yea. I get the general idea of it. I am at the stage where I can see the general outline through the fog, but, like most things, I need to atually do some to get my head around it. ATM I am too busy :(
But conceptually, this doesn't make sense to me. If I have a calculator and I want to push it across the table, I don't say to myself Calculator.ApplyForce! Though I might think Hand.ApplyForceTo(Calculator).
that's where i think you are making your mistake swifty... it's the result of the procedural thinking that has served you so well, and for so long, in Blitz...
OOP dev really requires a lil more thinking before you start coding... and a different approach in the way you 'see' the objects that will exist in the virtual world thatyoua re creating... at least that's the way i see it...
you have to approach the whole coding process in a more granular way than you did with procedural coding in Blitz... you've gotta loose the false assumptions about implementing behaviors of objects that that unplanned way of coding promotes...
in your example above, the calculator, like a calculator in the real world, must obey the laws of physics (whatever physics your virtual world imposes), right... therefore, while not making it a physics object, you must give it the abilty to automatically follow the rules of physics... so, this would mean that the calc would've either been an ancestor of a more generic object , an object derived from a collider class (TYPE in BMAX) , that does nothing but implement these physics functionalities, or could have been the 'child' of a collider object... this way the calc would inherit the functionality needed... and therefore would react just as you correctly said, when a hand, or whatever other collider object interacted with it...
the calculator class (TYPE) itself would not have such inate functionality... and you could concentrate on making it a calculator... it would inherit this behavior from its predecessors... or from it's parent object...
that's the really cool thing about OOP... you only code what you need, where you need it... say you coded that collider class four months ago... or a year ago... and you've fogotten just how you got it to work... or you got the class from a code lib... you really don't have to be bothered now, seeing as the collider class would be way down at the base of your class ancestral tree... and almost all objects would inherit from it... and would be 'physical'...
neat... eh.. :)
Jeremy was right... objects are the way in which the real world works... everything is an object of one type or another, which can be traced back to another class of object, which in turn can be traced back to a more generic class ofobject, and so on... until you get at the base virtual class where it all started...
developing programs in a manner like this is really the more natural way to do things...
--Mike
sswift: No, you see, it would be like this:
void Hand::Push( IPhysics& object, double force )
{
object.ApplyForce( force );
}Maybe that makes sense. The idea is that you can break things down into a primitive form. In this case, the calculator isn't a Calculator type, all it does is implement the IPhysics interface.
BUT, BlitzMax doesn't support interfaces, so you would be better off to use a collection of components to compose the objects. E.g., a calculator would have the Physics, Interactive, and Renderable components in the case of a game where the calculator could be thrown around, interacted with, and drawn.
That probably confused everyone...
actually... it wouldn't be like that at all... it should be automatic...
you're still thinking procedural, which is why you too don't see the entire process clearly...
a hand moves... that's all... now, the result of this movement can cause something to be pushed... or not...
was it Newton who came up with the for every action there is an equal and opposite reaction thing... well, a hand doesn't really care about all this... but the physics object (unseen, yet still there) that Newton was referring to does...
it is what represents (implements in code) the force that does the actual pushing...
stop for a second and think about it... if a hand, or a calculator, or an apple, a pen, anything that was derived from, or was a child of a collider object, raised a collison event, they would automatically react...
the only thing that a hand would do, would be to move... the collider functionality would be what pushes whatever it came in contact with... it would check for collisions and automatically invoke the required interaction to it's descendant class objects or its child objects... just like real world objects...
you're right about one thing though... it can be a lil confusing... at least until you get used to the more granual approach OOP development demands of you... it's naturally gonna be hard to abandon the way you've been comfortably doing things for so long, and adopt a new approach towards them... especially if what you were doing has worked so well for you... OOP should probably best be apporached gradually (although i might think differently, as i see it as an all or nothing thing) as to ease a coder from what he/she has ingrained in their thought and dev process...
but the benefits of approaching coding like this cannot be overstated enough... once the physics has been implemented, either at the base of the class hierarchy, or as a class which objects can be parents to other objects, you no longer have to concern yourself with it any more... all descendant or child objects will automatically be physical... now, all you have to concern yourself with is implementing your calculator to calculate... if it is pushed, it will automatically react as the physics in the world you are coding tell it to...
--Mike
Listen to Red there, he's got it down. It's tough though for most of us coming from a procedural background to break things down like that. It's all about organization though and understanding that less is more. Each class or type should be very minimal and just tie into other minimalist classes or types. The complexity comes from extensions, not by creating any one complex class or type.
Oop is the major reason I still use it.
I love the OOP in Max.
I like OOP.
but I dislike overuse of it. I like a nice Balance between OOP and Procedural.
Ideally, the main loop would be procedural, calling out to the OOP stuff. Perhaps this is wrong but it fit's better in my mind this way!
Red actually made some sense in this post and Noel didn't ;)
>was it Newton who came
come on Red, a great master like you knows answer to that question already, why ask ;)
Ideally, the main loop would be procedural, calling out to the OOP stuff. Perhaps this is wrong but it fit's better in my mind this way!
yes i agree make it more managable, i think the mix of procedural and OOP just adds that little extra. i think that max is great because of OOP.
I have learnt to like OOP in Bmax.
In case of maxgui, why have a mainloop (other than the waitevent instruction)? Emitevent, Eventhook, the whole thing runs (or so it should) automatically.
I came to Max with no intention of using OOP but it grew on me and makes life easier if used sensibly.
Cygnus hit the nail on the head: like it but hate overuse.
From the perspective of using a wrapper, I think OOP or non OOP would make little difference - do it the way you like.
OK, thanks for the opinions guys, doesn't look like there's any need for me to write a procedural version. I recalled someone on IRC saying how much he hated the OO design of HGE when the original base class wrapper was released so I thought I'd better do a quick poll to see if I should account for that.
@ Jeremy...
It's all about organization though and understanding that less is more. Each class or type should be very minimal and just tie into other minimalist classes or types. The complexity comes from extensions, not by creating any one complex class or type.
without turning this into a mutual admiration exchange :), i just wanna say how impressed i am with your clarity of vision on this topic...
you've managed to encapsulate everything that took me about 50 or so lines of typing, into a short two or three liner... which exactly explains the whole concept in one short, sweet, and concise paragraph...
i wish i had put it exactly that way :)
one thing i left out in my soapbox above, was the idea of code reuse... although i briefly touched upon it, i neglected to emphasize that making clean classes for the base of your class heirarchy is a key part of the development cycle... mainly because these classes can be reused over and over again... and it frees you from having to redo stuff that you will be using again and again in your new projects...
don't expect to get BlitzMax, and immediately jump into coding up your killer game app... you should start off thinking about exactly what functionality your game, or for that matter, any game, would require, at it's most generic state... then code the classes to implement these functionalities, with an eye towards your future development needs...
like Jeremy said above... keep it clean and minimalist, so that each class only does what it needs to do to present the functionality it is supposed to, and doesn't restrict any descendant classes in any unreasonable way...
soon you will have a class library that you can use over and over again to jumpstart most of your new projects... and while in the beginning, this might seem like a drawn out and unnecessary process, you will soon start to see and reap the benefits of this approach...
Cyg and Norman... i really don't understand the whole idea about overusing OOP... not trying to be pedantic here, or to force a point of view... i seriously just don't understand what you mean by overuse of OOP... but in the back of my mind i'm sensing that there may be something to what you are saying...
... can you guys come up with a simple illustrations or example of this?
--Mike
Red;
What I mean when i say "Overuse" is that you don't need to Object Orientate everything.
In my mind, the best way to write a program is to have your OOP stuff etc in seperate modules and include them into your Main.BMX-
In my mind, Main.BMX would be the glue to all the external files, and to me it wouldn't need to be all wrapped into a type/class. I see no need to have a "GAME" type and an "APP" type.
Ant's done this in the Game Framework, which is fine- it works. However, I see no need to do that when you can just have "Function Blah" instead of having to keep track of where Blah is; "Game.Blah()", "App.Blah()", "This.Blah()" Ok, the last doesn't count :P
However, OOP is quicker when its done just like Aurora has been done.
Object.Sync() updates Object visually. No need to worry about other crap :-) thats perfect.
Object.X() returns the X position of Object. yeah, simple, quick, and works :)
I see no need to have a "GAME" type and an "APP" type.
well... lets look at this for a moment...
an application is a fundamental concept in windows programming... every application, no matter what kind it is, should therefore have certain functionalities that are geared towards making it aware of the environment is running in, and to give it the capability to do do certain application related things...
foget that we are making a game for a moment, and concentrate soley on the application... say you want your application to be the only instance of itself running at one time... this functionality would be implemented here, in the app class (TYPE)... other things, such as getting system info, making sure that it exits cleanly, making itself aware of windows messages while it is running, serialization, all that would be implemented here...
ok... now that we've coded a simple, functional application type, we can start on our generic game class, which would naturally be a descendant of the app class... i mean, after all, a game is nothing more than another windows app... right...
our game class would now inherit all the functionality of the app class, which you can forget about now, and center on making a generic game class that does only what is necessary for any type of game you might envision creating...
each game must have certain basic properties and functionality... for example, a player, a view, timers and schedules, the game loop, things like that... these would be implemented here... now, at this point you can decide if you want to make a 3DGame class, or a 2D Game class, seeing as they are so fundamentally different... or you might opt to have a single game class... either way, all you would need to do (after you've fleshed out the classes needed for your game (player, view, game objects, etc), would be to now start on your game...
and all this would entail would be creating a new instance of a game class, which would automatically bring in with itself all the functionality of is ancestor classes... it would automatically have the functionality of an application because its class was an extension of the app class... you would automatically benefit from this any time you created a new game... now, and in the future... a perfect example of code reusabilty...
plus, it allows you to center your thinking on the granular functionality that is immediately in front of you...
that's how i see it, anyways... a game class that is derived from an ap class is almost fundamental to the process... once those classes are done and tested sound, you will always have a solid springboard from which any game you want to write can be jump started...
--Mike
Aha, see, it looks like I simply don't have enough knowledge of it, since that does make sense read. Thanks for the enlightenment. (Ant will be sighing with relief now :P). Before, i was simply using types/methods for the wrong reasons.
So, it should be (this makes sense)
Type App
End Type
Type game EXTENDS App
End type
Okay, extends can be a few other things but here, I'd prefer the layout to be
Type APP
Type Game EXTENDS App
End type
end type
The second sample makes more sense. I'm going to have to try it in max later since I've not seen it done like this before- Is this possible?
Cyg: You're crazy that will enver work.
btw my Game Framework has a Type TGame that I make a single instance of. I would expect people who use this code to either Extend it to Type TMyGame extends TGame (for future upgrades to TGame) or just hack it and use it as they want (not as clever).
See? This is exactly why I don't do much with OOP.
I can read it, i know enough to work with it, but my brain doesn't work with it well at all.
Cyg: You're crazy that will enver work.
What will enver work? Just saying how i'd prefer the layout :-)
lol, OK, but that layout to me is horrid too :-D
Shut it, you......
well... good luck... it'll all start to gel a lot sooner than you think...
keep us updated as to your progress...
--Mike
Hehe nah, I'm going to be learning C# pretty soon :-)
It's not even that I dont understand it, its that I'm inexperienced with the *proper* form of them.
embrace OOP, be one with OOP :)
Once you start coding with OOP you'll wonder how you ever got anything done without it.
I'm all for OOP !
OOP is necessay. I have type that stores information about a light relative to an entity. I have an instance of this type for every single light/entity interaction that occurs.
Perhaps I've used procedural languages for too long, but OOP seems to over-complicated things at times.
The basic concept I like - but it just seems a little over-cooked for my taste. BlitzMax does compromise here though - it doesn't follow C++ in it's implementation, which I think is a good thing.
That's what I like about C++ compilers - they can also run C code. Having said that there are things that I prefer in C++ - like memory management.
Type App
End Type
Type game EXTENDS App
End type
Okay, extends can be a few other things but here, I'd prefer the layout to be
Type APP
Type Game EXTENDS App
End type
end type
Why? This means you have an APP with game properties inside of it ... instead of a Game that gets all the APP properties. By adding the Game EXTENDS App inside the APP that's like overcomplication of the APP instead of making a Game that gets all of APP without having to add extra code.
I've really come to see the benefits of OOP from working with Torque I think and also BlitzMax. I haven't actually written my ultimate BMax hierarchy yet but I have a base class/type called entity2D which basically morphs into everything else possible in a 2D game and itself is very simple.
Anyway, the true benefits of OOP aren't evident until you're working on something big and predominatnly written by other people. OOP lets you work with something which you don't know everything about. That's the most important thing about it.
In real life you don't know everything but you're able to interface with the world and made decent decisions. OOP is the same thing. With procedural programming ... forget it, if you don't know the whole program you're pretty much screwed.
Additionally ...
Think of it more like this:
Type Amoeba
End Type
Type Human EXTENDS Amoeba
End Type
Your way would be:
Type Amoeba
Type Human EXTENDS Amoeba
End Type
End Type
This infers that Amoeba is more complex than Human, because Human is contained within Amoeba the way you've got it. In reality the reverse is true.
I know a few people that just maybe are uh less complex that Amoebas, for sure.
I think, to truly benefit from OOP, you need big projects.
Im working with the HL2 SDK right now, and that has OOP very well implemented, from what I can tell.
Hehe nah, I'm going to be learning C# pretty soon :-)
Well in that case, it'll definitely start to gel sooner than you think, or else you'll really be struggling with C# because C# is incredibly object oriented. Right up there with Java.
Loved the BMax language, however with the lack of built in 3d, had to move back to Blitz3d....
Found myself lusting over BMax (the lacks in Blitz3d that would be so much easier to deal with using the BMax language).... Now after working with B3D for the last year again, I will have to re-learn BMax again (whenever the 3d module rears its head)... sheeeshhhh.....
BTW, nice explanation Red, Kudos for a facinating read!
Well in that case, it'll definitely start to gel sooner than you think, or else you'll really be struggling with C# because C# is incredibly object oriented. Right up there with Java.
I said it wrong, but thats what I meant. C# is just Object Orientated. Max can be both.
I like OOP TBH it makes some things in Max much easier.