how should I structure data for a complex object in ActionScript 3? - actionscript

I hope this isn't too vague, but I'm stuck on a problem that has put me in an Unfortunate Position.
I'm Flash developer getting my feet wet with with AS3 and am trying to build an interior decoration tool for a client. My thinking so far has been: create the basic user interface, get the screen flow down, and then finally use a couple of simple arrays to store user selections and stuff like that.
Naturally my 'couple of simple arrays' is totally inadequate to model the many user decisions that my program has to take into account. So I find myself trying to create an enormous, multi-dimensional array with several layers of nesting and before Panic sets in.
Here's an example of my thinking for the 'bedding' component of the application in pseudo ActionScript:
bedding['size'] = 'king':String
bedding['cover'] = cover:Array
cover['type'] = 'coverlet':String
cover['style'] = 'style_one':String
cover['variation'] = 'varation_one':String
cover['fabric'] = fabrics:Array
fabrics[0] = 'paisely':String
fabrics[1] = 'argyle':String
fabrics[2] = 'plaid':String
cover['trim'] = trim:Array
trims[0] = trim_pair:Array
trim_pair['type'] = 'trim_one':String
trim_pair['color'] = 'blue':String
trims[1] = trim_pair:String
trims[2] = trim_pair:String
cover['embellishments'] = embellishment_pair:Array
embellishment_pair['type'] = 'monogram':String
embellishment_pair['letters'] = 'TL':String
... keep in mind that this is just a fraction of what goes into bedding and there are several other of these kinds of arrays that would go into a room like flooring and walls and funture... all equally complex. And I'll need to frequently access different combinations like, how many options under bedding have no value associated and things like that.
So, I realize I'm out of my league and am going to get hurt on this, but I'd like to try to get this right so that I get better and any help you guys can provide is great.
My questions are:
1) Could it be that using nested arrays like this actually isn't such a bad thing and I should just stick it out? That would suprise me, but I want to make sure I'm not already on the right path.
2) If not, where do I go from here if I want to do this right?
Off the top of my head I feel like I could maybe make everything class based. So my sheets are a class and beds have instances of sheets and rooms have instances of beds... etc. It think it would be complicated but might be the way to go.
Or maybe, I go the XML route and store all of the room options in nested blank XML nodes that a user then populates as they move through the application.
These are my thoughts but I'd like to hear what more experienced members of the community say.
Thank you so much for your help!

My suggestion would be to use a strongly typed model. Look into using collections and value objects to store and retrieve data. A collection could be a class that wraps an Array and provides a clean interface for fetching the value objects that it stores. Value objects are simple objects representing data that can be assembled in various ways to create more complex collections. Value objects can also be passed around to transfer data to various parts of an application. The advantage to using collections and value objects is that your code will be ( potentially ) more explicit and over-all easier to read than if you went with a dynamic approach. For some, the downside to this approach is that you end up with too many classes. Personally, I prefer working with many small to medium size classes versus one monolithic class.
If you are not familiar with the concept of value objects: http://en.wikipedia.org/wiki/Data_transfer_object.

AFAIK, AS3 is not well suited to the type of complex data model you're trying to create.
You need to completely decouple the UI/Flash tier from your "inventory" system. The UI should be completely abstract, with no knowledge of, or coupling to, your data schema or content. This could be accomplished with a middle-tier webservice-styled system that handles all the business logic around searching/retrieving/updating your data.
Store everything your UI needs to handle presentation-side rendering in your product metadata. This will allow you to add new products and types without having to update the UI every time new products are introduced. For example, if a product comes with an image, store a URI to the image with the product record and load it on demand. You could extend this all the way to custom animations, I believe- just reference an outside .SWF file and load it into your application on request.

Related

Named (map) constructors do not work in grails.gsp.PageRenderer

When I use a map constructor like:
Person p = new Person(name: "Bob")
through something that is called via a grails.gsp.PageRenderer, the field values are not populated. When I use an empty constructor and then set the fields individually like:
Person p = new Person()
p.name = "Bob"
it succeeds. When I use the map constructor via a render call, it also succeeds.
Any ideas as to why this is the case?
Sample project is here in case anyone wants to dig deeper: https://github.com/danduke/constructor-test/
Actual use case, as requested by Jeff below:
I have a computationally expensive view to render. Essentially it's a multi-thousand page (when PDF'd) view of some data.
This view can be broken into smaller pieces, and I can reliably determine when each has changed.
I render one piece at a time, submitting each piece to a fixed size thread pool to avoid overloading the system. I left this out of the example project, as it has no bearing on the results.
I cache the rendered results and evict them by key when data in that portion of the view has changed. This is why I am using a page renderer.
Each template used may make use of various tag libraries.
Some tag libraries need to load data from other applications in order to display things properly (actual use case: loading preferences from a shared repository for whether particular items are enabled in the view)
When loaded, these items need to be turned into an object. In my case, it's a GORM object. This is why I am creating a new object at all.
There are quite a few opportunities for improvement in my actual use case, and I'm open to suggestions on that. However, the simplest possible (for me) demonstration of the problem still does suggest that there's a problem. I'm curious whether it should be possible to use map constructors in something called from a PageRenderer at all. I'm surprised that it doesn't work, and it feels like a bug, but obviously a very precise and edge case one.
"Technically it is a bug" (which is the best kind of bug!), and has been reported here: https://github.com/grails/grails-core/issues/11870
I'll update this if/when additional information is available.

When should I create a model in MVC?

I am just getting started with ASP.NET MVC. So far I like it a lot.
I am trying to get up to speed but I need some clarification. I want to know when should I create a model for the logic.
I mean so many times I found my self putting all logic into one "master" model. I know its not the right way to go.
But then again I'm not sure if it is good to have redundant properties in my model.
I assume you are talking about ViewModels, and it is perfectly fine to have different viewmodels instead of having one complex model even the properties are repeating. With master model, it tends to get complicated down the road. However, for special cases like CustomerCreateVM and CustomerEditVM, I would create the commmon properties in base class CustomerVM and inherit it and for more readability I will keep them in one file. Does it answer your question ?
Your "View" model should accurately represent the information that is being shown/processed in that particular view. This means it should only have the fields that relate to the information being shown and nothing else. If it is not shown or used on the screen, it should not be in that model.

Best practice question - Working straight with Linq to sql classes

This is possibly a bit of a stupid question, but I am getting confused due to the ASP.NET MVC book I am currently reading...
Working with Linq-To-SQL it seems to say that it is not good practice to pass the Linq-to-SQL objects straight to the controller, but that each object should be modelled separately first and this should be passed between the controller and the repository.
Say, I have a database of products. Linq-to-SQl creates a product class for me with Name, Price and Whatnotelse properties. I could pass that straight from repository to controller and then view, but instead it seems to recommend that I use and third class, say Product_Entity, with also Name, Price etc. properties and pass that to the controller.
I fail to see the benefit of this approach, except possibly for adding attributes to the properties... But apart from that it seems to have more drawbacks than benefits. Say each product has manufacturer information as well, I don't see how I can model that easily in my third class.
Is this approach really best practice? Or did I misunderstand all that? If so, why is it bad to work straight off the linq-to-sql generated objects? And how do you deal with relationships between objects in y
The huge benefit to this other class you create is that, to use your example, it doesn't necessarily map to either a product or a manufacturer. Think about it like this:
Your Linq to SQL classes are meant for talking in the "data" domain.
Your "data" classes (the ones you're having trouble with) are meant for talking in the "application" domain.
Let's take an example. Suppose in your MVC application you wanted to show a grid of information about products. You want to see their Name, Price (from the Product table) and their Country of Manufacture and Manufacturer name (from the Manufacturer table). What would you name this class? Product_Manufacturer? What if later on you wanted to add properties from yet a third table such as product discounts? Instead of thinking about these objects in purely the data domain, think about them with regard to your application.
So instead of Product_Manufacturer, what about calling it ProductSummaryItem? Each property of the ProductSummaryItem class would map 1:1 with a field shown in your grid on the UI. Your controller would perform the mapping between the information in the data domain (Product, Manufacturer) with the custom class you'd created in the application domain (ProductSummaryItem).
By doing this, you get some awesome benefits:
1) Writing your views becomes really, really simple. All you have to do to display your data is loop through the ProductSummaryItems and wrap them in and tags, and you're done. It also allows for simple aggregation. Say for example you wanted to add a field called ProductsSoldLastYear to your ProductSummaryItem class. You could do that very simply in your views because all it is to them is another property.
2) Since the view is trivial and there's mapping logic in the controller, it becomes much easier to test the controller's output because it's customized to what the view is going to see.
3) Since the ProductSummaryItem class only has the data it needs, your queries can potentially become much faster because they only need to query for the fields that would populate your ProductSummaryItem object, and nothing else. This overhead can become overbearing the more data-domain objects make up your ProductSummaryItem object.
This pattern is called Model View ViewModel (MVVM) and is hugely popular with MVC as well as in frameworks like WPF.
The argument against MVVM is that you have to somewhat reimplement simple classes for CRUD operations. Fair enough, I guess, but you can use a tool like automapper to help out with things like that. I think you'll find fairly quickly, though, that using the MVVM pattern even for CRUD pays dividends, because before you know it, even with simple classes, you'll start wishing you had extra fields which can easily drive your views.

Creating the same model from multiple data sources

This is mostly of a design pattern question. I have one type of model that I'm going to get the data to create them from multiple sources. So for example one record my be created from an API where another is created via screen scraping with Nokogiri.
My issue lies in how best to abstract out these different data sources. Right now I'm building lib classes that return the same hash which I then use to set the attributes of the model. But I'm wondering if this isn't more of a case to use STI. Or if there is some other way of doing this I'm just not thinking about.
I think your design decision would depend largely on what attributes need to be stored. From your description, it sounds like you have a model with multiple data sources, but which would be storing the same attributes regardless of the source. In that case STI seems like overkill. When you retrieve a row from the table, does it matter whether the source is the API or the screen scraper? If not, then you could just define separate methods for each data source and use the appropriate method in the controller.
#instance = MyModel.new(:datasource=>"API")`
I'd say don't worry about inheritance (or mixing in code from modules) unless you really need to. There are some gotchas -- STI is not fully supported by some gems/plugins, for example.

How to handle view model with multiple aggregate roots?

At the moment, i got quite badly fashioned view model.
Classes looks like this=>
public class AccountActionsForm
{
public Reader Reader { get; set; }
//something...
}
Problem is that Reader type comes from domain model (violation of SRP).
Basically, i'm looking for design tips (i.e. is it a good idea to split view model to inputs/outputs?) how to make my view model friction-less and developer friendly (i.e. - mapping should work automatically using controller base class)?
I'm aware of AutoMapper framework and i'm likely going to use it.
So, once more - what are common gotchas when trying to create proper view model? How to structure it? How mapping is done when there's a multiple domain object input necessary?
I'm confused about cases when view needs data from more than 1 aggregate root. I'm creating app which has entities like Library, Reader, BibliographicRecord etc.
In my case - at domain level, it makes no sense to group all those 3 types into LibraryReaderThatHasOrderedSomeBooks or whatnot, but view that should display list about ordered books for specific reader in specific library needs them all.
So - it seems fine to create view OrderedBooksList with OrderedBooksListModel view model underneath that holds LibraryOutput, ReaderOutput and BibliographicRecordOutput view models. Or even better - OrderedBooksListModel view model, that leverages flattening technique and has props like ReaderFirstName, LibraryName etc.
But that leads to mapping problems because there are more than one input.
It's not 1:1 relation anymore where i kick in one aggregate root only.
Does that mean my domain model is kind a wrong?
And what about view model fields that live purely on UI layer (i.e. enum that indicates checked tab)?
Is this what everyone does in such a cases?
FooBarViewData fbvd = new FooBarViewData();
fbvd.Foo = new Foo(){ A = "aaa"};
fbvd.Bar = new Bar(){ B = "bbb"};
return View(fbvd);
I'm not willing to do this=>
var fbvd = new FooBarViewData();
fbvd.FooOutput = _mapper.Map<Foo,FooOutput>(new Foo(){ A = "aaa"});
fbvd.BarOutput = _mapper.Map<Bar,BarOutput>(new Bar(){ B = "bbb"});
return View(fbvd);
Seems like a lot of writing. :)
Reading this at the moment. And this.
Ok. I thought about this issue a lot and yeah - adding another abstraction layer seems like a solution =>
So - in my mind this already works, now it's time for some toying.
ty Jimmy
It's tough to define all these, but here goes. We like to separate out what we call what the View sees from what the Controller builds. The View sees a flattened, brain-dead DTO-like object. We call this a View Model.
On the Controller side, we build up a rich graph of what's needed to build the View Model. This could be just a single aggregate root, or it could be a composition of several aggregate roots. All of these together combine into what we call the Presentation Model. Sometimes the Presentation Model is just our Persistence (Domain) Model, but sometimes it's a new object altogether. However, what we've found in practice is that if we need to build a composite Presentation Model, it tends to become a magnet for related behavior.
In your example, I'd create a ViewFooBarModel, and a ViewFooBarViewModel (or ViewFooBarModelDto). I can then talk about ViewFooBarModel in my controller, and then rely on mapping to flatten out what I need from this intermediate model with AutoMapper.
Here's one item that dawned on us after we had been struggling with alternatives for a long time: rendering data is different from receiving data.
We use ViewModels to render data, but it quickly turned out that when it came to receiving data through forms posting and similar, we couldn't really make our ViewModels fit the concept of ModelBinding. The main reason is that the round-trip to the browser often involves loss of data.
As an example, even though we use ViewModels, they are based on data from real Domain Objects, but they may not expose all data from a Domain Object. This means that we may not be able to immediately reconstruct an underlying Domain Object from the data posted by the browser.
Instead, we need to use mappers and repositories to retrieve full Domain Objects from the posted data.
Before we realized this, we struggled much with trying to implement custom ModelBinders that could reconstruct a full Domain Object or ViewModel from the posted data, but now we have separate PostModels that model how we receive data.
We use abstract mappers and services to map a PostModel to a Domain Object - and then perhaps back to a ViewModel, if necessary.
While it may not make sense to group unrelated Entities (or rather their Repositories) into a Domain Object or Service, it may make a lot of sense to group them in the Presentation layer.
Just as we build custom ViewModels that represents Domain data in a way particularly suited to a specific application, we also use custom Presentation layer services that combine things as needed. These services are a lot more ad-hoc because they only exist to support a given view.
Often, we will hide this service behind an interface so that the concrete implementation is free to use whichever unrelated injected Domain objects it needs to compose the desired result.

Resources