Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: Naming/structure conventions  (Read 14917 times)
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« on: September 11, 2011, 09:25:15 »

Hi,

Getting through the second week with PureMVC, and still really liking it.  I have another question, though:

Q: How do you name VO objects?

The issue I keep running into, making me feel all weird and uncomfortable, is that I find myself adding VO to the end of all of my data classes.

e.g.
- TextureProxy creates TextureVO objects.
- ShaderProxy creates ShaderVO objects
- SoundProxy creates SoundVO objects
- LoaderProxy creates LoaderVO objects

the list goes on.  This how I had it previously:

- TextureManager creates Texture objects.
- ShaderManager creates Shader objects
- SoundManager creates Sound objects
- LoaderManager creates Loader objects

So basically where I would have had 'naked' classes before, I've got VO appended to everything.

I can live with this, however here are some more examples of where it starts to get weird for me:

- WorldProxy creates and manages:
  EntityProxy, which manages EntityVO objects, MapVO, CollisionVO etc classes.

Now... EntityVO objects aggregate other, non-trivial, data objects that are really outside the realm of MVC.  They're game specific utility classes, amongst other things, that makes sense to that Entity.  So I'm not appending VO to them, because their logic will always stay in the Proxy domain (i.e. not be used in Commands or Mediators).

So, in short:

I've been appending VO to class names that tend to be created directly in the Proxy and exposed to the outside world (Commands/Mediators/Views), and everything else is under a 'do' (Data Object) folder under Proxies.  Is this how it's supposed to be done?

e.g. Here's a modified/trimmed version of what I'm doing:

:
- root
  - util (This is the namespace for all non MVC related code.  General framework classes for useful functionality)
    Pathfinding.as
    Collision.as
    Debug.as
    Math.as
    RenderUtils.as
  - mvc (This is the PureMVC application structure)
    - Main.as <- entry point
    - AppFacade.as
    - controller
      - startup
        InitCoreCommand.as
        InitDataCommand.as
        InitGameCommand.as
        LaunchGame.as
        StartupCommand.as
    - model
      - game
        GameProxy.as
      - world
        - vo (I have VOs for objects that tend to get passed across application boundaries)
          - entities
              EntityVO.as
              PlayerVO.as
              EnemyVO.as
        EntityProxy.as
        WorldProxy.as
      - util (Theses are utility classes that related to functionality not appropriate for MVC)
        EntityCollision.as
        EntityVisibility.as
    - view
        - components
          uiView.as
        UIMediator.as
        WorldMediator.as

Does this look ok to you?  I really want to nail this down, so when I explain the new structure to our other programmers, they know where to put old and new code.

When I've finished all of this, I might expose it to everyone as a full game implementation, in order to help the community.

Cheers,
Shane
Logged
Deril
Full Member
***
Posts: 22


View Profile Email
« Reply #1 on: September 12, 2011, 03:34:13 »

Hi,

 its a good practice to use VO with value objects.

 If you see VO in the class you instantly know that this is just data container. Nothing else.

If you have complex data structures, for example that needs to have some inner mechanics that work as black box, and it is not just value object anymore - it's better to avoid adding VO. Name whatever makes sense... "Data", "Info", "Attribs"...

 In almost all cases Proxies juggle plain data, thats why Value Object naming convention is used.. if you don't have value object - don't use this convention.

Plain classes is best used with View clases. "MainMenu", "PromptWindow" and so on.


I have little personal practice to name Command that passes temporal Value Object as body with ending "Param" to know that those are purely temporary VO classes just to sent data around, they have same role as parameters sent to function. I create them near command under "param" folder.
(Of course sometimes commands gets VO to body, this way I know this is data that is not temporal and needs to be stored in proxy somewhere, or is taken for proxy.)

Have fun.
« Last Edit: September 12, 2011, 03:40:14 by Deril » Logged
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« Reply #2 on: September 12, 2011, 03:53:19 »

Hi Deril,

Thanks for the reply.  What you've said is more or less in line with what I've done.  I've seen other people append DO (Data Object) to Proxy managed classes too.

So you didn't say whether you think the structure I'm building seems right?  What do you think?

The main problem I have with the VO concept, with respect to games, is that it's rare to have a simple VO data structure.  Sure, these can exist as aggregates of more complex classes, but ultimately they tend to have functions that operate on their data.

So this leaves me wondering if games are a good fit for PureMVC.  The idea of a UI (View - Mediator) that manages multiple dialogs/buttons etc (View - components) which request their data from a data managing Proxy (Model) is fine, but I question the use of Commands (Controller).

Also, I can't seem to find anyone using PureMVC in realtime games, not simple turn/event-based games (no offence intended to anyone making non realtime games ;) ).

Anyway, I'll keep looking at a palatable structure, but I'm beginning to worry I'm trying to shove a square peg into a round hole.

- Shane
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: September 12, 2011, 08:00:40 »

I would sort the classes in the util package under the MVC tree. The point with MVC is to separate all of your code into the three tiers. It is a central organizing principle, not just a library.

There is a drawer in my kitchen called the 'just for now' drawer. When my wife and I moved into this house and we were figuring out where all our stuff was going to go, this drawer ended up full of odds and ends. Being the clean freak, I objected to this senseless appendix of clutter when we were doing such a great job of finding a proper place for everything. She said 'just for now, honey'. Now, years later, that drawer is as cluttered and random as it ever was. I just don't put anything in there that I ever expect to see again, myself.

My point is that the problem with 'utility' classes is that they don't have clear roles, responsibilities and collaborations associated with them. Anytime you need a function for this or that, it ends up getting stuck on some unsuspecting class in the utility folder. And the MVC collaboration rules are right out the window. Anything goes in a 'utility'. Anything on any tier will access it and it will feel free to access anything on any tier. Next stop, Blue Plate Spaghetti Special.

You might start by simply creating separate util packages under each of the model, view, and controller packages in your app. This will at least force you to do some thinking about which tier these utilities belong to. Later you'll probably find that many of these utility functions can be implemented as commands.

Also, with regard to the lowly Value Object, it should definitely have the VO part added to the end to indicate the role. But, like view components, they can have encapsulated logic for keeping themselves internally consistent, or for transforming data stored internally in one format to another presented to the client of the VO.

For instance, XML as a datatype in AS is really great, but you don't want to pass it around raw, having code in every class that handles it having to do XML operations on it. Instead, it'd be great to encapsulate XML inside a typed object, such that the data is really XML that's read from and saved to a file or service. But instead of having another actor parse the XML and set the properties of a Value Object, what if you could just set the XML on the value object, and all the properties were really implicit accessors (getter/setters) that take data out of the XML and return it as a type or visa-versa? The nice thing about encapsulating this behavior is that only the VO has to be updated when a new property is added, instead of the VO and some Proxy, Command or 'util' parsing class.

For lack of a better name, I call this a SmartVO. See an example of a 'Smart VO' here: http://forums.puremvc.org/index.php?topic=1293.msg5973#msg5973

Note that this SmartVO shouldn't know or care about any other classes unless its composed of them. The biggest benefit is that you can work with it anywhere in the application, including the view components, and never worry that you're making bad collaborations. No other actor needs to know what's going on inside the VO or mess with its XML except to populate it or store it.

-=Cliff>
Logged
Deril
Full Member
***
Posts: 22


View Profile Email
« Reply #4 on: September 12, 2011, 09:45:09 »

Cliff has a good point.

 imagine your application done in units or modules.
Those modules are not dividable, and they can stand more or less on there own.

 one module can use and aggregate other modules. but it should not implement those.

 Then I see that my code does not meet this characteristics, I naturally start to feel that something is out of place.. with time you start to feel it like intuition. :)

 Now if there is the need to create sub System that does not fit that picture - it will not find place in PureMVC folders. PureMVC will probably have Proxies and VO that will hold artifacts from those subsystems, but it will not implement it, and it will not have code of it.

 Imagine utility that abstracts XML... you could call it... XMLData.as in utility folder. Now XmlProxy.as could hold instances of XMLData in VO's and use it as it needs to. but XMLData implementation should be completely separated from PureMVC.


 About games... I work in big online game making company. I have examined/collaborated on couple of huge project and was leading one that uses PureMVC.. (60000+ line of code game and growing.)

 Yes. You can and in lot of cases you should use PureMVC in games.

There are 2 main reasons for that... (not to mention array of minor once..)
 - big games tend to change much. if you don't have a good framework you will end up with a mess.
 - big games tend to have many programmers, and over long time they change.. everyone has his programming stile. If you don't use framework you will end up with mess done by "coding in different directions"

 Have fun.


Logged
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« Reply #5 on: September 12, 2011, 03:27:59 »

I like your drawer story, Cliff.  We have one of those too, we call it the "Third Drawer" ;)

Whilst I know where you're trying to go, not everything can ever really fit into 3 discreet tiers.  Classic utility classes are used across all boundaries, a good concrete example being math classes.

Math classes are truly used in everything from view components to transforming data at a model/data level. The code (e.g. matrix.cpp, matrix.as, matrix.m) has to live somewhere.  Sure it can be arbitrarily placed in one of the layers (probably the model layer), but it breaks the MVC pattern because now these layers have to know about the proxy. Worse, how would isolated view components access this math class?

The fact is libraries/utilities/helpers have a place in programming languages. They are a form of encapsulation, isolating an outside world from knowing about their innards, in a a reusable form.

PureMVC itself is using the Flash runtime as a library.  The Flash runtime is using the OS as a library, it's natural and necessary.

MVC is just a concept, a way of mentally organising data, control logic and display, and I've seen obsessive adherence to a particular pattern end up causing more trouble than it solves. I've witnessed this particularly with junior programmers who aren't code reviewed regularly, which happens because it's the nature of development.

Frameworks are great if they're consistent, structured, fit the needs of the purpose for which they're designed, reduce code, help thinking about data ownership etc. I really see that PureMVC has the right hallmarks, I just haven't seen it really pushed yet. I'm sure it is in closed source projects, but I'd like to see something more complex than a user admin app.

This is why I'm trying to really do things the 'right way', because once I find a way to make this all fit together, I'll likely open source a game example for other people to check out.  I'll do this because I've seen a lot of people interested in PureMVC and games.

As for experience and intuition, it's fair to say I've done my time (linkedin.com/in/shanestevens), but I'm always looking for a better way to do things.

Cheers
- Shane
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #6 on: September 12, 2011, 04:47:07 »

The fact is libraries/utilities/helpers have a place in programming languages. They are a form of encapsulation, isolating an outside world from knowing about their innards, in a a reusable form.

I agree completely with this point.

And The framework is meant to work and play well with other frameworks and utilities and it does. There are cross-cutting concerns that require actors that aren't specifically part of the MVC tiers. The MultiCore pipes utility is a good example. It provides classes that connect to each other forming pipelines and allowing data to pass through them and be filtered, split, joined etc. They don't get packaged into MVC tiers in the utility. But then again, they are in a separate library devised according to their own requirements. The question becomes what actors in the application need to know about those things in that library and how do they use them. No worries.

From the perspective of PureMVC application design, I'd suggest putting those utilities into a separate library project and importing them into the project. That way, they cannot see the code of the application and will truly be encapsulated (at least with regard to dependencies on the app).

Inside the application project itself, I still maintain that a utility folder as a sibling of the model, view, and controller folders is a bad idea because it makes it too easy to have one of those utilities that began life as a 'pure, encapsulated utility' make a dependency on one of the framework classes, value objects or view components. When that happens, the spaghetti will begin. Once a 'utility' messes with one of the classes in the MVC tiers, its role should be more clearly defined and it should be placed in the proper tier and included in the appropriate collaborations for that tier.

-=Cliff>
Logged
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« Reply #7 on: September 12, 2011, 09:29:19 »

From the perspective of PureMVC application design, I'd suggest putting those utilities into a separate library project and importing them into the project.

Ok, that's a good compromise I think, and in line with how I usually structure non-PureMVC apps.  Basically I'll keep all of the application itself in PurePVC, with any truly decoupled helper libraries separated out into their own SWC.  Is this what you meant?  If so, that's very natural, and standard, way to code.  I feel much happier with that.

As you suggested, I took a look at the more utility-like libraries - "Utility_AS3_MultiCore_Pipes", "Utility_AS3_StateMachine", "Utility_AS3_Loadup", and I see they tend to hang their code off

:
package org.puremvc.as3.multicore.utilities.*
This works for me, although I'll use our namespace.

However, after hunting around, I've seen other examples of people putting a 'utilities' namespace under their project.  One example is Renju I found here: http://www.emanueleferonato.com/2008/03/25/full-renju-game-with-source-code/.

He has a utils folder as a sibling of his mode/view/controller folders, which just holds a couple of filters.  This is an example of what I was talking about, in that these are small helpers, that don't live in the MVC pattern, are application specific, and are not good candidates for putting into a separate library.  Sure you could put them into a separate application-specific library, but that is starting to feel like overkill, no?

Or... based on your initial feedback:
You might start by simply creating separate util packages under each of the model, view, and controller packages in your app

Would you suggest, in this case, putting the utils folder under view, given they're view related filters anyway?  If so, I could live with that.

- Shane
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #8 on: September 13, 2011, 08:14:35 »

Basically I'll keep all of the application itself in PureMVC, with any truly decoupled helper libraries separated out into their own SWC.  Is this what you meant?  If so, that's very natural, and standard, way to code.  I feel much happier with that.
Definitely.

However, after hunting around, I've seen other examples of people putting a 'utilities' namespace under their project.  One example is Renju I found here: http://www.emanueleferonato.com/2008/03/25/full-renju-game-with-source-code/. He has a utils folder as a sibling of his mode/view/controller folders, which just holds a couple of filters.  This is an example of what I was talking about, in that these are small helpers, that don't live in the MVC pattern...

Or... based on your initial feedback... Would you suggest, in this case, putting the utils folder under view, given they're view related filters anyway?  If so, I could live with that.
Those are DropShadowFilterHelper and GlowFilterHelper. So, yes, I'd suggest these would be best placed under view/utils. They work with DisplayObjects to modify their appearance. These are pretty clearly View tier utilities.

Seriously, I think you'll find that the occurrence of application-specific, cross-cutting concerns that don't fit into one of the Model, View, or Controller tiers is in fact few and far between. If I'm far off base with that statement, I would love to see a good long list of them posted here for my own educational purposes.

-=Cliff>
« Last Edit: September 13, 2011, 08:19:45 by puremvc » Logged
shanestevens
Jr. Member
**
Posts: 17


View Profile Email
« Reply #9 on: September 13, 2011, 04:09:57 »

Great, I'm as happy as a clam in a mudflat now, thanks Cliff. :)

Ok, back to VOs.

I was actually unaware that there is a Value Objects pattern, I thought it was a PureMVC concept.  So I landed upon Martin Fowler's definition:

http://martinfowler.com/eaaCatalog/valueObject.html
VO: A small simple object, like money or a date range, whose equality isn't based on identity.

which in turn led me to Data Transfer Objects (DTOs):

http://martinfowler.com/eaaCatalog/dataTransferObject.html
DTO: An object that carries data between processes in order to reduce the number of method calls.

Very succinct definitions.

Further reading found more detail, but basically boiled down to VOs being small, mostly data-only, immutable structures; almost like C structs.  DTOs we slightly more heavyweight, the idea being that they can minimise the calls back to a model layer, which may be remote.

I have to assume that model != server, so in the case where the model == client (an in memory structure), what should I use?

Imagine again our imaginary game world.  This PureMVC app has a EntityProxy class, which is basically a replacement for a EntityManager in the more traditional sense.  This EntityProxy creates and manages entities, which mediators (amongst other things), render.  These entities also know how to handle their own per-frame updating (AI).

So now we've got an encapsulated entity which is more than just data, it has its own personal brain (logic) too.

So that means it's more than just a VO.  Should it still be called a VO? e.g. MyCrazyPacman.as or MyCrazyPacmanVO.as ?

When the Mediator wants the entity, I don't want to copy all of the data out of the main object to a temporary VO either.  That could be expensive (matrices, vertex data etc).  This is the same thing client/server OpenGL drivers do.  I really just want to ask the EntityProxy for the instance of the object I want (more like a unified memory model); i.e.

:

MyMediator extends Mediator
{
    private var _crazyView:CrazyView;
    onEnterFrame():void
    {
        var ep:EntityProxy = EntityProxy(facade.retrieveProxy(EntityProxy.NAME));
        var player:MyCrazyPacman = ep.getEntityByName("player");

        var _crazyView.renderPlayer(player);

        // Or I could put all of this in a command, but feels like overkill to me given it's so specific to this mediator.
    }
}

This feels natural to me, but it doesn't fit the VO convention of PureMVC.  i.e. These are chunky reference objects passed over the Model/View boundary.  This feels more like Martin Fowler's DTOs.

So what to name my example entity, when it's actually the object, not temporary/transient/immutable copy?

I hope this all makes sense. ;)

- Shane
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #10 on: September 14, 2011, 08:06:59 »


Further reading found more detail, but basically boiled down to VOs being small, mostly data-only, immutable structures;
VOs are used to transfer data from the server to the client and back (in some serialized form usually), but also across tiers of the client. But immutability isn't a typical characteristic of the VO in the wild. You usually want to write them as well as read them. And having a mutable version is just impractical.

So now we've got an encapsulated entity which is more than just data, it has its own personal brain (logic) too. So that means it's more than just a VO.  Should it still be called a VO? e.g. MyCrazyPacman.as or MyCrazyPacmanVO.as ?
Usually they're just objects with some properties. But they can encapsulate their own domain logic. Not business logic, but domain logic. That is, a setter for a property on a VO might make sure that the value is valid for the field by checking an internal list. That would be domain logic. But business logic would be more like making sure the user had the right permissions before letting them update the data. That would be a job for a command. The VO can be as complex inside as need be to encapsulate management of its own data integrity. But it shouldn't know any other actors except other entities of which it is composed.

But regardless of what it looks like inside, the VO should be called a VO. That is its role, and what its internal responsibilities are don't change that.

As for the naming difference between MyCrazyPacman and MyCrazyPacmanVO,  MyCrazyPacman should be the name for the view component that renders the MyCrazyPacmanVO. Many classes in the framework may handle a MyCrazyPacmanVO, so it is useful for its role to be part of its name. But only the MyCrazyPacmanMediator should handle the MyCrazyPacman view component. So tacking a rolename like 'View' onto the view component is redundant.

But if you decide that for completeness sake you want a role name on all your view components, don't name them after their implementation. For instance if you were using Flex, don't name a component based on mx:Panel InvoicePanel, because later you might change the implementation to a s:VGroup. Then you'd either refactor it to InvoiceVGroup or deal with the fact that its name doesn't match what it is. The better name would really just be Invoice. Its name is its role.

-=Cliff>
Logged
Pages: [1]
Print