gamelab / kiwi.js

Kiwi.js is a blazingly fast mobile & desktop browser based HTML5 game framework. It uses CocoonJS for publishing to the AppStore.
www.kiwijs.org
MIT License
1.41k stars 195 forks source link

Public component access on `ComponentManager` #250

Open BenjaminDRichards opened 8 years ago

BenjaminDRichards commented 8 years ago

The manager does not actually let us see the list of components. I'd like to be able to see it. A components property would make a nice companion to the private _components.

1O1O1O commented 8 years ago

Does mutators not make more sense than expose properties publicly? I mean, it's a purely "architecture choice" question, but I saw that you made the choice to often expose properties insteed of encapsulate it.

I would like to understand your coding philosophie, for produce code not in sync with your strategie and so waste your time and mine.

BenjaminDRichards commented 8 years ago

That's a great question. Encapsulation is very important - I'm making sure that it's strong elsewhere in KiwiJS. For example, another recent issue talks about camera transforms - which should be calculated on the camera, not in various other points in the codebase.

In this case, we would be using a mutator/getter-setter to map components to _components. It doesn't really make much difference, because it would be a straight mapping, effectively exposing the property; but it means not tweaking the internal workings of the ComponentManager.

We need a certain level of exposed access. It helps efficient performance. We can't predict every possible outcome, so we need to leave room to do unexpected tasks.

This was an unexpected task. I want to go through every component on a game object, and unless it's a Box, set it to active=false; and then later do the reverse. It's so specific that it's not worth making a public method, but it also requires access to private data.

Personally, I think it shouldn't have been private in the first place; but that's how the code was set up, and we can't change it until v2.0.

So this is about as encapsulated as it should be: clearly part of the object responsible for that task, but accessible to external logic.

Hope that clarifies things! Let me know if you want more information.

1O1O1O commented 8 years ago

So if I understand correctly, getters / setters are not a strategy by default due to performance reasons.

Thus, an object of your design preferentially deliver its publicly properties, rather than give them access via mutators, unless the property which require a more serious integrity control , in which case you encapsulate the property and then set mutators.

Am I right?

I understand that performance issues are capital, the mainstream development frameworks often make use of non-recommended architectural choices to optimize, and I didn't know that basics uses of getter / setters were so greedy.

I'm a little confused on the subject,

Thus, migration of public property to private, for example in the case of adding a feature that imposes more controls on this property, forces you to break your interfaces, and thus break your public contracts. This has the consequence of forcing you to upgrade to a major release in semver rather than a minor release, because of the violation of the backward compatibility, no?

In fact that's not a major issue until you'll need to add control for a super used public property, and then force all users to upgrade theirs implementation for use the mutators.

In the end, I'm not saying that it's a bad choice, I guess that performances are a really major issue, but I still don't agree about that : So this is about as encapsulated as it should be: clearly part of the object responsible for that task, but accessible to external logic.

Architecturally, in absolute, everything can stay accessible, but encapsulated. And it's almost allways better like that, because of the benefits of the SOLID principles.

Sorry for the digression, and thanks for you answer!

BenjaminDRichards commented 8 years ago

You are correct: we like public properties, and only mutate them when checks and filters are necessary.

KiwiJS has a long history, and it wasn't always built with a clear architectural philosophy in mind. I'm currently in charge, and I want to encourage good practice. However, at the same time, it's important to keep the API stable. That's why we take semver very seriously. This does sometimes prevent us from implementing a best solution. We have some ideas for introducing superior development flexibility in v2.0, but that will entail a lot of work.

(Incidentally, I define the API as the set of public methods and properties, and expected behaviours, of a class. This does give us some freedom in rebuilding private systems. JavaScript does give us the ability to cheat and invoke nominally private properties at will, because privacy is just a naming convention, but it is never a good idea and never officially supported. That's why this issue exists in the first place - I don't want to rely on _components, because the possibility exists that I might remove it tomorrow.)

This is a useful conversation to have. It helps us articulate our practice (and perhaps identify elements of practice that we should eliminate). You're also giving me food for though by using certain kinds of terminology. For example, the last time I was in a computer science class was before SOLID principles were formally articulated (then I spent time with illustration, 3D animation, and media design before cycling into game development), so simply having this discussion is continuing my education. Thanks for the input!

1O1O1O commented 8 years ago

I understand your constraint, and to be honest the actual result of Kiwi is impressive. It's really constructive for me to to exchange with you and your team and understand the path you used to make such a library.

I didn't get any computing class at all in my life, only biochemistry (nothing really useful around here ;)) so I have to learn by myself everyday to keep my skills up to date, that the great part of this job, the infinite learning, from books, and from developers like you.

SOLID principles are a really agnostic development base, which allows you to structure code the same way whatever language you use. An agnostic architecture becomes much more portable, and less coupled to the idiosyncrasies of the language used, significantly increasing the maintainability and convenience of developers , I love it !

Thanks to you for your time!