3

I have an architecture similar to this:

User (Name, Email, ID...)
---- Studios (Name, Location, Description...)
---------- Videos (Title, Description, URL, Length, Views...)

Simply put, a user can have 1 to multiple studios and a studio can have 1 to multiple videos.

Each of these are Classes in my PHP application (User, Studio & Video) that stores information (User name, User ID, Studio name, Studio location, Video name, Video URL, Video views...)

Right now, if I want to show, for example, the total amount of videos & views that a user has considering all of his content, I build all of his Studios from the User Class (with a function like "build_Studios", then for each Studios I build all of the Videos from the Studio class (with a function like "build_Videos".

This allows me to easily access any data that I need rather easily, however now that I am looking at the length of our data, I am a bit skeptical about this approach. For example, one user can easily have posted in the range of thousands of medias spread across his Studios. Also, I am now thinking about the Pagination feature which seems like it would make much more sense using LIMIT instead of parsing an array...

So I would like to know if I should review my architecture while the project is still at an early stage. If so, how would you recommend that I organize my data? Otherwise, is a structure like the one I cited previously proper for a large application?

  • If are submitting data from this objects into databas, check out Doctrine. it will enable you to work with each class/Entity easily. All you have to set is relationship among your objects. – Muhammed M. Mar 12 '16 at 15:51
2

A sentence in your question raises a huge red flag for me... I'm talking about where you say, "This allows me to easily access any data that I need rather easily..."

In a properly designed system, nothing outside of the User class will "need to access" any of its Studios objects and nothing outside the Studios class will need to access the Studios' Videos objects.

If you enforce the above restrictions, it won't matter whether you load all the Studios/Videos at once or stream them in a little at a time, because changing the system from one method to the other will only require modifying one class.

To quote Arthur J Riel from "Object-Oriented Design Heuristics"... "From time to time, a developer will argue, 'I need to make this piece of data public because...' In this case, the developer should ask him or herself, 'What is it that I'm trying to do with the data and why doesn't the class perform that operation for me?' In all cases the class is simply missing a necessary operation."

-- EDIT --

To drive this point home. Imagine I have a Rectangle class that contains two points topLeft and bottomRight. One of the invariants of the class is that topLeft.x must always be less than bottomRight.x. Assume that I create the getters all around.

What is a poor rectangle to do when someone does this?

myRectangle.topLeft.x = myRectangle.bottomRight.x + 12

The answer is that there is nothing the Rectangle class can do. It's invariant is broken and it had no chance to protect itself.

  • I am not much experienced in OOP and I am not sure what you mean by this? At the moment, for example, I create a User object then call my Studios builder, then with my Studios getter (from User), I can retrieve all of them then proceed to a foreach on each Studio to then retrieve their Videos in pretty much the same manner... This is what I meant by easily accessing my data. – Estarius Mar 1 '16 at 2:51
  • The only code that should be using foreach over the Studio array inside a User is a method that is in the User class. That way, if you later find that you can't load all the Studio objects in, you will only need to change the User class, not every one of User's users. – Daniel T. Mar 1 '16 at 2:53
  • IE, the studios array inside User should be private, and there should not be a public getter to it. Getter's are anathema to OO design. – Daniel T. Mar 1 '16 at 2:55
  • Oh ok, at the moment I'm looping in my Controller, I will try to make a method inside. As far as stepping away from Getters/Setters, I will most likely have to read on the subject. However, according to your comments, it seems like the encapsulation of objects inside their parent is fine ? – Estarius Mar 1 '16 at 2:59
  • It's fine, even critical, to encapsulate objects inside their parent! When you provide that public getter, you are breaking the encapsulation boundary and allowing just anybody access to, and modification of, the parent's guts. It's okay to do that with simple data transfer objects, but you shouldn't have getters all over your primary objects. (Note I'm dissing getters only here, not setters.) If you must have a getter, ensure that it returns a copy of the objects contents rather than the contents themselves. The object must have full control over the state of its guts. – Daniel T. Mar 1 '16 at 3:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.