Once you go OO, you never go back?

Started by
23 comments, last by superman3275 11 years, 4 months ago

I've tried to understand how Data-Oriented Programming works, but it just doesn't snap into your mind like OOP did.

Also, are there specific languages for DOP, like there is for OOP?
No specific languages.

There really isn't anything to get with DOP.

In OOP you think about objects and their relationships. This is fine, but the actual instructions that get generated is not optimal for the way modern machines work. The gap between processor and memory speeds has kept getting bigger. So all these abstractions are not making the best use of the current machine architecture.

DOP still thinks about objects and relationships, but puts more emphasis on the actual data, how it is stored, and how it gets read and written to. You think of things as groups instead of singular objects with their own data. When you have to update 10,000 of something, you can just store all those things in one flat list and update them in one go instead of having to hunt down all the memory locations of that variable across those 10,000 objects.

It's how to program something for machines with massive amounts of slow memory instead of small amounts of fast memory.
Advertisement

I've tried to understand how Data-Oriented Programming works, but it just doesn't snap into your mind like OOP did.

Also, are there specific languages for DOP, like there is for OOP?


DOD isn't all that hard to understand, and while the term 'Data-Oriented Design' might be relatively new, the concepts behind it have been around for quite some time.
Just don't try to learn DOP by comparing it with OOP as that'll make things a lot more difficult for you.

I like to make the comparison between DOD and relational databases since they have a lot of things in common.
When you read papers on DOD you'll always come across a piece of advice which goes something like "Store your data as a struct of arrays, not as an array of structs", and a 'struct of arrays' is nothing more than a regular old table where column data is stored contiguously.
Just like with tables in relational databases this allows you to easily do operations on entire columns in an efficient manner, which is exactly where the strength of DOP lies.
This type of data layout is also very friendly for multithreaded applications, as you can just split up the data set and let multiple threads handle their own chunk of the data at once (this is completely safe since the same operation is done on each data entry anyway).
When a table needs info on a relation stored in another table you can again use an RDB approach by adopting the concept of foreign keys to some extent to allow for proper data encapsulation. This way you can create complex 'objects' (to put it in OO terms) with a DO approach.

I'd advise anyone who wants to learn how to work with Data-Oriented designs to learn about the basic principles of relational databases, maybe learn how to work with SQL at a basic level, and play around with building properly designed databases.
Not all the concepts found in RDBs will be applicable to DOP though, but it could become a possible eye-opener for anyone struggling with wrapping their heads around it.

I gets all your texture budgets!

Again, keep in mind DOD and OOP are not mutually exclusive.

Using the SoA example, say you have a 3d model resource that stores its vertices. You may store them as a vector of Vec3, or you may store them as 3 separate float vectors. Either way your 3d model resource is hopefully very simple in purpose (SRP) as a container of the necessary data. The way you organize that data is up to you. Now, even in this example, it's not as easy as SoA versus AoS. The 3 vectors of floats might be nice for SIMD usage, but those vectors could be in very different parts of memory. If you are bound by memory transfer rates then the vector of Vec3 (or Vec4) might actually be a more optimized organization of your data. And SIMD doens't have to be out of the question here because more and more I am seeing horizontal instructions.

DOD is not about doing it this way or that, it is about programming around the best way to organize your data. You have to figure out what "best way" means though, given your situation. [edit] And it doesn't get you off the hook from figuring out how to best organize your code wink.png

As another example, think about how you might store a binary tree in a single array...


[a lot of thoughtful insight]

This sounds to me like a mix of Data Driven Programming and Data Oriented Design. Just wanted to make note that they are 2 very different concepts.

This sounds to me like a mix of Data Driven Programming and Data Oriented Design. Just wanted to make note that they are 2 very different concepts.


I am very well aware that data-driven programming and data-oriented programming are completely different concepts, don't worry about that, I was just trying to create a link between DO concepts and other well-known concepts so it might become easier to understand.
On the matter of data-driven designs, I always hate to compare it with paradigms like OO and DO as these comparisons just don't make sense. It's completely possible to do data-driven programming within the confines of a paradigm like OOP as they're completely orthogonal concepts.

And it's also true that OO and DO are not mutually exclusive, but programmers who think of software purely as interactions between objects (as with OOP) will have a very rough time trying to adapt to DOP as they'll always try to translate the concepts to OOP. Trying to make sense of a data-oriented design with an object-oriented mindset will force you to make a bunch of confusing 'mental jumps', which is something you'll want to avoid when trying to learn something properly.

I gets all your texture budgets!

I have to say that in my opinion object-oriented programming is relatively worthless to me.

I used to think like that but there are some examples where OOP is clearly beneficial. For example look at the scroll bar. With procedural programming, a scroll bar can be implemented with a function plus one or two global or static variables. If you need several scroll bars, you can copy and paste the code and create more global variables. You get more code and you can't change the style of all scroll bars easily.
With OOP, you can implement the scroll bar with a class. If you need several scroll bars, you just declare several instances of the class. You don't need more code or more variables. You can change the style of all scroll bars by modifying the class, and you can create new scroll bar styles easily by using class inheritance.
OOP also helps breaking long functions into small pieces by creating more places where you can logically put the code in.
That being said, I think most roguelike games are made with C and they're not small projects. The advantage of procedural programming is that you can focus on getting tasks done quickly without having to worry about how to package functions and data inside classes.
I draw the line where I have something that I need to act on data independent of what it is recieving.

If I have a single function that takes in four parameters, and the parameters are the only data it interacts with, than there's no point to wrap it into an object. And if I have an object that is only composed of grouped data, I'll use a struct. And if I have a set of functions that needs a set of data to work, I'll wrap it into an object. However, I consider the single-responsibility principle: Does this only have a single responsibility, is there a smart way to divide it?

A good example would be how I'm currently loading maps (Just wrote the refactored code yesterday, currently working on Map-Texture's). I have a Map class that loads a map and inserts it into a Two-Dimensional vector of Blocks. I then have another class, MapTexture, that contains a pointer to a map and keeps a single texture. If I change the map, I have MapTexture update itself. This means I'll have a single class to load and store data, while another class uses that data to create an actual texture for the map and display the map using that texture.

Many new object-oriented programmers would like to put these classes together. However, than I have a single class that load my map, updates my map into a texture, and draws the texture. By seperating my classes, my code is easier to maintain and follow. Changing how my MapTexture displays the map is completely separated from how I load the map. This makes it far easier to refactor and change my code later on without having to worry about causing other classes to stop functioning correctly.

Data-Oriented Programming and Procedural programming both have their uses. However it depends on your infrastructure more than anything. If I have a single class that loads an image into memory, there's no point in having a procedural function for it.

I enjoy using all programming styles depending on my current project's infrastructure.

I'm a game programmer and computer science ninja !

Here's my 2D RPG-Ish Platformer Programmed in Python + Pygame, with a Custom Level Editor and Rendering System!

Here's my Custom IDE / Debugger Programmed in Pure Python and Designed from the Ground Up for Programming Education!

Want to ask about Python, Flask, wxPython, Pygame, C++, HTML5, CSS3, Javascript, jQuery, C++, Vimscript, SFML 1.6 / 2.0, or anything else? Recruiting for a game development team and need a passionate programmer? Just want to talk about programming? Email me here:

hobohm.business@gmail.com

or Personal-Message me on here !

This topic is closed to new replies.

Advertisement