In the MVP and MVC pattern you want to clearly separate the View from the Model.
But to display stuff like Icons, Animations that should play when something happens etc., the Model needs to tell the View how it wants to be represented. For example the icon on a button that selects an element.
Thus I think that stuff like Images, Animation Frame Data etc. should be part of the Model as the elements of the Model need to define this. But I also feel like this should not be the case. As such the only thing I can imagine is having a huge Mapping stored somewhere that maps types of the model to representative data. That seems like a huge anti-pattern to me.
How would you structure this stuff in a project? Where is the data of "how should it look" be stored? Inside the Model, inside the Presenter (a Mapping) or inside the View (a Mapping). Maybe I am missing something crucial here.
To clarify where this is coming from:
Consider you have objects that get represented by icons in a list. These objects all have a common supertype but each differ in details and thus should be represented by different icons. Moreover, maybe you implemented everything as a common type and define it's whole behavior just during construction or setting stuff up during runtime, so you do not even have a way to differentiate between icons to display via type. As such I would deem these objects need an accessor like "getImage" to get the representation they would like to have in the GUI. But having the image be part of the model seems wrong.
To present a common way to form an answer, the imaginary project may be structured in the following directories:
src/model/
src/view/
src/presenter/
Where would each type/class with what methods be located?
How would you structure this stuff in a project? Where is the data of
"how should it look" be stored?
This is where I use a ViewModel. You map your Model to the ViewModel and use the ViewModel to represent what properties get displayed. You can tailor the ViewModel to:
Style/css the property,
Combine properties,
Validation logic,
Change how the property is displayed and more.
Where would each type/class with what methods be located?
src/viewModel
Related
I've been struggling to understand the best way to insert controller logic when using IB, NSObjectController sub-classes and bindings.
I need to insert controller logic between the model and the view, and I'm struggling to find an elegant way to do so. Yes, you can send actions to the file owner and handle controller logic in there, but when some core data models can extend across fifty entities or more with deep relationship structures, this starts to mount up to an incredible amount of boiler-plate code.
A very simplified example would be this; imagine you have an entity with four string attributes myTextWinter, myTextSpring, myTextSummer, myTextAutumn. You have a view which connects to this in IB via an NSObjectController. Now, say the user can select which 'Season' they wish to view by choosing Spring, Summer, Autumn, Winter from a Menu somewhere - when that season is selected, I would like to display the appropriate season's text.
In this simplified example I could probably fetch the object in the NSDocument sub-class, create a property called mySeasonText which I bind to in my view, and then check my NSUserDefaults for the appropriate season and route the requests to the appropriate attribute in the model.
The problem comes when I have fifty entities, some with relationships some two, three or more deep, each with their own set of season specific text attributes that I wish to switch between when selecting from the Season menu. Or if I have a bunch of nsarraycontrollers chained together to access objects at a deeper, and deeper level.
To date, I've been doing the following; adding a property in each of my model objects called 'mySeasonText', then grabbing the setting from my controller setting, and routing to the appropriate season. I refresh these objects whenever a new item in the menu is selected.
Whilst this works and eliminates an absolute ton of boiler-plate code, my controller logic is now in my model.
There must be a better way! Could someone please point me in the correct direction?
This is a tricky topic. Apple even mentions these challenges in its own documentation:
By using the bindings technology, you can easily create a Cocoa MVC application whose views directly observe model objects to receive notifications of state changes. However, there is a theoretical problem with this design. View objects and model objects should be the most reusable objects in an application. […] Design-wise, it's best to keep model and view objects separate from each other, because that enhances their reusability.
The design pattern you are looking for is a Mediating Controller - a way to use the cocoa-bindings classes to insert controller logic:
Mediating controllers are typically ready-made objects that you drag from the Interface Builder library. You can configure [Mediating controllers] to establish the bindings between properties of view objects and properties of the controller object, and then between those controller properties and specific properties of a model object. As a result, when users change a value displayed in a view object, the new value is automatically communicated to a model object for storage—via the mediating controller; and when a property of a model changes its value, that change is communicated to a view for display.
Here is how I like to think of them: Have you ever seen a movie or TV show where two characters need to talk, but they don't speak any of the same languages? They find someone else (or in a comedy 5 other people) who each have one language in common, and they communicate by playing a giant game of translation telephone.
Mediating controllers are kind of like that.
As your application grows they learn all the super specific rules about where to look for this one thing on this one view. This is the kind of code that an app needs to run, but you rightly feel that it is nasty when put in your model.
For several specific and detailed examples, Apple provides this amazingly detailed document: Bindings Message Flow.
For some really good discussions about this and related MVC + Bindings please see:
MVC and cocoa bindings best practices question
Why use NSObjectController?
Replacing model objects using an NSArrayController
For quite a while I've been looking at objective c examples, watching the Stanford lectures, and playing around with some code to get a hang of creating an iOS app.
However there are a few things that I can't find a good answer on:
How do I properly separate my layers? I understand the MVC structure, and I saw some examples of creating Categories for models to implement business logic. Is that the proper way, by enriching models or should I create dedicated classes (e.g. to authenticate users, extract models from json, group orders)?
How smart should views be? Can I make a view that displays a Contact (by assigning the contact property) or should I create separate properties for all of the Contact fields or should the view request it's information via a delegate call?
I'm using a Storyboard in my application. On my screen I want to
have a navigation bar, and let's say a view that displays orders. On
other screens I want to reuse the order-view.
How can I re-use the order-view's ViewController and View in other ViewControllers?
If I have 4 screens with the same look-and-feel, do I have to simply copy them in the Storyboard? This seems like a pain to main, what if I want to change my background? Or add a button to all of the views? When I create a setup-wizard I don't want to define the look-and-feel for every screen separately.
Coming from a C# background I probably have to get into the objective-c mindset :)
Any help on this would be great.
1) ObjC-Categories will easily distort your understanding of the main problem you're facing. ObjC-Categories are completely unnecessary. You could always approach these extensions by subclassing, object composition, additional methods in the actual model, or some customization in the controller or view. So if you need to format data (e.g. which is present in the model) for display in a view -- that task would often land in the controller. As far as the examples you provide: You may opt for models in simple cases -- as well, any of the examples could merit dedicated class, if complex enough or if it would keep you from redundant implementation. Note that these may be accessory classes, which simply produce a model, or they may be composites of multiple concrete of abstract classes. Not everything needs to land squarely in the definition of M-or-V-or-C. You're free to use many design patterns with ObjC. Think of MVC as the patterns Cocoa typically uses -- you will need to know them, and you will need to know how to subclass and extend these types, but these patterns lose dominance as implementations move away from Cocoa's libraries (e.g. as complexity increases).
2) They can be smart. However, under MVC, you want to focus its implementation on the view/presentation aspect. A view which represents a collection of information could in fact perform some tasks which are typically reserved for the controller -- however, you would generally cede that the implementation were a dedicated MONContactView in doing so. If you go that route, you would generally do so for easy reusability or to achieve a simple interface. Displaying information about a Contact could be very complex - In simple scenarios, these tasks are often handled by the controller. Specifically, a MONAwesomeContactView is likely less complex (e.g. in SLOC) than MONAwesomeContactViewController (unless you have some very special drawing or layout to perform). It would be more common to set the controller's contact, and let the controller push the contact data to the views' fields. Again, in the case of a very specialized subclass -- a view could very well hold its own controllers in some cases.
3a) There's nothing wrong with creating multiple instances of a class.
3b) No need to copy. When duplication is smelled, I push the implementation to actual code -- the programs can apply the look and feel you desire, or add or manipulate the subviews as you desire. Of course, they will not be present in Xcode's NIB editor. There are of course alternate approaches, but this replication often makes me move the implementation to compiled code. Achieving a good balance of both is not so difficult (personally, I do most of my views programmatically, rather than using NIBs).
This is a pretty abstract question and it's not clear what oh mean by 'layers'. Yes, you should create your own classes where appropriate, but categories also give you the option of adding functionality to existing classes. If you can be more specific with the question it'll be easier to provide a better answer.
It's a judgement call. If you want to create a view class that knows how to display an instance of your Contact type, that's fine in my book. If that view knows where Contacts are stored in the app, though, that's not so good.
Remember that the things in a storyboard are objects, not classes. You don't want to try to re-use a view from one scene in another scene -- that'd mean sharing a view between scenes, which really won't work. If you want to use the same order-view in several places, that'd be a good candidate for creating a class. On the other hand, you can set up your storyboard so that several different scenes all transition to the same scene. If you want different parts of your app to modally display a scene that displays an order, for example, you can do that.
I just resumed work on an old project and have been thinking about rewriting some parts of it.
My question relates to how to structure my program. I have been trying to follow the MVC paradigm. I'll start by explaining where things stand: the program manipulates 4 types of images: Bias, Darks, Flat Fields and Lights. I have a class called Image that can represent all of these. The Bias and Dark are subtracted from the Light and then the Light is divided by the Flat Field. Initially, I was going to use 2 classes for this, one called CalibrationImage and the other just Light. But the difference was only of one method which would be the dividing function I mentioned above. Otherwise, they are the same. So I decided against having two classes for this purpose.
The 2nd major class in the program concerns handling multiple Image objects -- this class is known as ImageStacker. As of right now, it holds Image objects in a mutable array. It can do various operations on this array, like stack all the images, calibrate them etc.
This class also acts as the datasource for the NSTableView object in the main window. I'm not thinking that instead of having a single mutable array, I should have 4 arrays each holding its designated for a type of image (like, an array for Lights, another for Darks etc.). Once the program begins its actual work, it will Darks, Flat Fields and Bias frames. It will then calibrate each object held in the Lights array and then stack them. I feel like this provides the program with logical progression. Its also a bit easy to visualize.
Is this a good program design? Does it follow MVC? As I see it, my view is NSTableView, controller is NSApplication and Model is ImageStacker. But then, Image feels like its not part of the MVC but I cant see how to write the program without it.
My 2-cents: MVC is a presentation design pattern. I will typically write my MVC apps with separate business and data layers apart from MVC portion. It is ok that Image is not apart of the MVC pattern, it would probably better fit into a group of classes that you would define as your business layer. There are a lot of good books, blogs and articles out there that talk about programming design patters so I will not reiterate what they have already done. Simply asking this question is a good start. I would suggest you follow through by looking at content that is already available.
Imagine I have a abstract "FriendEvent" model which has several different concrete implementations, ie. FriendPosted, FriendCommented, FriendUploadedPhoto etc. They should all be rendered in my view of FriendEvents, but should be visually distinct from each other (e.g. FriendUploadPhoto should include a thumbnail).
What is a good object oriented pattern to achieve this?
I'm interested to learn if there's an alternative to switching on the concrete class of the model in the view code. That somehow feels wrong because it uses conditional logic where I believe it should be possible to rely on polymorphism, but I have a hard time thinking up a better idea. Are there any established patterns to deal with this?
(I obviously don't want to implement the view logic in the model, since that would be mixing the responsibilities, and since I may want to have different views for each model)
To clarify: How to model the different event type in the model layer is not the problem. There are several well known OO solutions. The question concerns the view code which is responsible for presenting the models visually. I imagine I have an EventView class which deals with showing an event (model). The question is: How to implement this class without a switch block that selects a different code path depending on the concrete type of Event is is rendering.
Seems like you have some DoubleDispatch concerns going on here.
If I understand you correctly, you are trying to avoid mixing Model and View. Each Event class could have
HtmlString getHtmlView() { /* code */ }
but then all events have view knowledge and each time we add a new kind of view we add a new getXXXView() method. I agree that this sees unpleasant.
So we could increase the separation of concerns by having all events offer
HtmlViewMaker getHtmlMaker { return new MyKindOfViwer(this); }
Now at least we've got the View code out into its own class. Yes we may well need to write special case code for each/many kinds of events, but that's inevitable. Our first problem is where to put that special code - and that we've an answer for.
However we still have a problem: each new kind of View needs a new getXxxMaker method. So we start to look at more complex Factories and the use of Generics and Templates and so on.
For me, I would just use the partial-view concept. The base class is dealt with by the primary view, and that primary view requires a partial view that takes care of the needs of displaying the concrete class.
As my Cocoa skills gradually improve I'm trying not to abuse the MVC as I did early on when I'd find myself backed into a hole built by my previous assumptions. I don't have anyone here to bounce this off of so hoping one of you can help...
I have a custom Model class that has numerous & varied properties (NSString, NSDate, NSNumber, etc.). I have a need to serialize the properties for transmission. Occasionally as this data is being processed for serialization a questions may come up that the user will need to respond to (UIAlertView, etc.)
Without bogging down in too many more specifics where does this code belong?
Part of me says Model because it's about persistence of data - in a way.
Part of me says View because it's another interpretation of the core data (no pun intended) contained within the model. And the user will have to interact with dialogs on occasion as data is processed
Part of me says Controller because it's managing the transformation of data between model & view.
Is it a combination of all three? If so how would communication be handled between classes as the data is being processed? NSNotifications? Direct method calls?
This may be something that you'd want to use the Visitor pattern for -- http://en.wikipedia.org/wiki/Visitor_pattern -- because you might eventually want to use different sorts of serialization for different things and you can have different visitor classes rather than a lot of special cases in the model code.
Here's a discussion of the Visitor pattern in objective-c/cocoa: http://www.cocoadev.com/index.pl?VisitorPattern
Here's an (old!!!) article from Dr. Dobbs about the visitor pattern in objective-c: http://www.drdobbs.com/184410252
The reason that the problem you're working on doesn't fit well into the MVC paradigm is that the serialization that you're doing is like a view on a stream-based rendering surface and it is displayed. Sometimes, this can be done really smoothly in the model but sometimes it's more complex and you need to look at your case to figure out which one it is.
Frequently, the transmission/web service (or whatever) code you're using will have its own handler for this data, for example ObjectiveResource adds a serialization and deserialization handler that works as an extension to NSObject that enables it to do a lot of this stuff transparently, and you might look into that code (particularly the ObjectiveSupport part) if you're trying to do this more generically.
Typically almost all application specific code belongs in the controller. The controller should interact and observe (via notification) the model and update the view as appropriate.
If you are doing model processing such that it is something that might be re-used in another app with the same model, then that processing could be in the model.
Views can be laid out in Interface Builder or created in code and/or be subclassed for custom drawing, but they should not have application logic and would not interact directly with the model.
I would suggest putting the serialising code in the model. If the process fails it can report that to whatever's listening to it (the view / controller) which can then present the UIAlertView, correct the problem and re-submit for another attempt.
I'd say in the model.
The call to serialize the data will be done by the controller. If the data cannot be serialized then the model should return an error which the controller then has to handle.