It's a fairly common scenario for an application to pull data from a server (usually a JSON string). This data is then parsed and converted into native classes like NSString, NSArray, NSDictionary, etc.
Most of the time, however, we want to use custom models to represent this remote data.
For example if we're pulling a JSON array of blog posts we'd want to map those into BlogPost model objects for example:
// BlogPost.h
#interface BlogPost: NSObject
#property NSString *title;
#property NSString *body;
#property NSDate *dateCreated;
#property NSArray *comments;
#end
What's your approach for decoupling the "JSON" model from the native model?
I often find myself writing a custom initializer in the model itself which takes a dictionary (which typically comes from the JSON feed).
For example:
// BlogPost.h
+ (BlogPost *)blogPostWithJSON:(NSDictionary *)jsonDictionary;
Then I have to keep track of the keys used on the server and map those to my properties.
I always feel a little uneasy doing this because the model in the application shouldn't really have to know what keys are used on the server.
Should I instead move this JSON-to-Object mapping in another class? Perhaps a Factory? Or should my network manager be creating and returning ready made objects to me directly?
Perhaps something like:
// NetworkManager.h
- (void)getBlogPostWithCompletion:(void (^)(BlogPost *blogPost))completionBlock;
(Of course I'm omitting lots of details here like which blog post to get but it's just to demonstrate an approach).
Any other approaches? How do you decouple your server data from your local models?
I have faced this problem a couple of times and got pretty much the same questions as you. In the end what I find works for me is:
Create an OO representation of the original model. In your case this would mean decoding the JSON array into whatever it uses as an underlying model (a dictionary?). Depending on how is modeled the service that you are using, you may end up with some "record classes" (i.e. classes without behavior). I generally prefer to have these type of classes instead of arrays or dictionaries, since as your software evolves this allows to add behavior to them if you need. If, on the other hand, you use arrays or dictionaries you can't do that.
Once you have a low-level OO model, create an OO domain model. In this new model you design things as your domain requires and not tied to the service provider's model. Many times you will find a 1 to 1 mapping between your domain classes and the provider's one, but that is not mandatory. The point here is that you should abstract your domain and design it as you feel is right.
The mapping between this two models can be done in different ways, according to its complexity. I generally like to pick one of these three approaches and stick to it in order to have an homogeneous approach in the project:
Write a class method (class)HighLevelObject>>from(aLowLevelObject) in your domain model. This takes a low level object and configures itself. You do this for all your high-level objects that have a low-level counterpart.
The opposite to the previous one: write an instance method LowLevelObject>>createHighLevelObject() in the low level object that creates an instance of your domain model. Here you a re shifting the responsibility of creating a new object to the lower layer.
Create a factory or builder (depending on the complexities of your models) that takes care of the whole creation process.
If you have simple models with many 1 to 1 mappings between them I would go for options 1 or 2. Which one to choose depends pretty much on your tastes; the option 1) has the advantage that the object knows how to construct itself but places the transformation process burden in the domain model. The second approach leaves a "cleaner" domain model, but forces the lower layer to know the details of the upper one and may force you to break encapsulation. I don't think that there is a silver bullet here; IMHO you should choose the approach that best fits your needs and programming tastes.
HTH
Related
I am using a UDF to apply some ML models to a data stream. Because the Model class (from a third party library) cannot be serialized by Flink automatically, I am using two variables as illustrated below:
class MyUDF extends KeyedCoProcessFunction[String, ModelDef, Data, Prediction]
with CheckpointedFunction {
// To hold loaded models
#transient private var models: HashMap[(String, String), Model] = _
// For serialization purposes
#transient private var modelsBytes: MapState[(String, String), Array[Bytes]] = _
...
}
Where:
models holds the loaded (running) models (created from a ModelDef, basically a string)
modelsBytes is the real (keyed) state, which holds the same models but as a blob of bytes so that checkpoints work well.
The overall solution is simple (just requires to invoke fromBytes/toBytes on my models when restoring/saving them) but I don't know if this is a common/best practice. Having two variables for essentially the same thing looks like a quirk. For instance, here you can find an example which uses a TypeSerializer[Option[Model]] instead, which looks cleaner but also more complicated to implement.
So, basically:
Should I use the TypeSerializer approach or having a somehow duplicated state for running/serialized models is ok?
Also, if you could please point me to some docs/examples regarding custom types serialization in Flink, that would be great, generally I find the official docs a bit lacking on this regard.
I'd probably go with a heap state backend and a custom TypeSerializer.
Heap state backend will only serialize the data on checkpoint and else keeps the data as is. So you have almost no performance penalty when using that backend over managing the map itself. However, it will remove the need to perform the serialization and sync manually.
Judicious denormalization of data for the sake of performance is a very common pattern. If you're not using too much memory then stick with this approach.
I have a Flight class which currently does nothing else but hold lots of variables containing details on a given commercial flight.
Most of these details are just passed through the constructor but some of them need to be calculated or formatted. For example I format the flight arrival time in to a string saying "6th June" and sometimes the airport name is missing from the initial flight data so I use an array of airportcodes and airportnames to find that airports name.
Should the methods that calculate this additional information be located within the flight class or a series of other models such as DateProcessor or Airport?
Chris K has correctly pointed out the litmus test i.e when you need to make a change; how many places do you need to make that change in.
OOP concepts encourage decoupling and modular programming to maximize code reuse.
The key is high cohesion and low coupling. Refer to this Cohesion & Coupling
If you thing that the additional flight details that you are deriving
from Flight class variables will only the need in one activity and now
where else.Then its ok to have these functions in our activity.
But, if these functions may be required by other Activities or classes
currently or may require in future.Then, place these functions in your
Flight Class
Ideally the best OOP will be to keep these functions that are deriving details from Flight class variables in flight class itself.As, you will be able to re use code if not now , latter in future.I will also suggest the same.
Also, if you use multiple instances of Flight class, the you should place all the functions accessing and modifying the class variables in Flight class only to maintain data consistency of each instance.
If you will stick to OOP programming techniques, it will be easier to maintain code as there will be more code reuse and no duplicate code.
There are four major principles of object oriented programming:
Data Abstraction
Encapsulation
Inheritance
Polymorphism
P.S : Can refer to http://en.wikipedia.org/wiki/Object-oriented_programming
It's perfectly normal to have login, data and UI seperate. For example, JavaBeans are convention for having classes that store data. Read more here. MVC fallows similar logic, i.e. View is created from data, taken from Model, and Controller updates the data.
Good class design encapsulates data and provides methods to access that data. In your case you should ask yourself "is all the data related" ... think if I had a group of employees would I give this data to one of them to remember or would it make more sense to partition the data and give sections of it to number of different employees.
You already have identified the data that should go into one class so it would seem logical to put the methods that act on that data in that class as well.
The MCV Design Pattern is flexible but overkill here I think.
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.
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.
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.