MVC: Differences Between Two-Step and Composite View Patterns - oop

In simple terms, could you please tell me the difference between the "Two-Step View" and "Composite View" Layout Design Patterns?

Composite View, as the name implies, is a Composite (as in the GOF pattern) of Views. That means the Composite View is a tree structure of other (Composite, Template, Transform, …) Views, which you can handle uniformly through the root Composite View object.
If the client dispatches to the root View, it will dispatch to all the Views in the tree structure, thereby creating the result page. So in Composite Views, there is not two steps, but just one, because each individual View is a one-step View (of the concrete final output).
Use Composite Views that are composed of multiple atomic subviews. Each subview of the overall template can be included dynamically in the whole, and the layout of the page can be managed independently of the content.
In simplified Pseudo-Code:
composite = new CompositeView;
composite.add(new HeaderView(headerData));
composite.add(new TableView(tableData));
…
composite.add(new FooterView(footerData));
composite.render();
This is different from Two-Step-View in that the Two-Step-View is not a Composite, but just two steps of execution, first from Domain Data to a logic screen representation of that data and then to the concrete output format. That is, it separates logic structure and formatting of the page.
Two Step View deals with this problem by splitting the transformation into two stages. The first transforms the model data into a logical presentation without any specific formatting; the second converts that logical presentation with the actual formatting needed.
In simplified Pseudo-Code:
twoStepView = new TwoStepView;
twoStepView.setData(data);
twoStepView.setFirstStep(new ConcreteScreen);
twoStepView.setSecondStep(new ConcreteHtmlScreen);
twoStepView.transform();
As you can see, the Two-Step-View is only orchestrating the two steps. For instance, if your Two-Step-View uses XSLT, it would only handle the transformation from the input XML to the Screen XML to the final HTML output. The Concrete Screen and ConcreteHTMLScreen would then be the XSLT templates.

I see "Composite View" as the design pattern that suggests that you design your views via composition, or combining smaller parts (sub-views) to create the whole - This lends itself to increased reusability and better maintainability.
The "Two-Step View", on the other hand, is more of a specific implementation of the Composite View Design Pattern, largely driven by the Zend Framework Layout. This implementation suggests that you define all of the content your sub-views first (step 1), then allow a layout to render the sub-views at the appropriate places in the rendered HTML (step 2).
I am generally a fan of a layout pattern but find the idea of two-steps (and defining all your sub-views first) limiting. I tend to think of layouts more along the lines of how Smarty 3's Extends/Block functionality works:
http://www.smarty.net/docs/en/advanced.features.template.inheritance.tpl
Functionality like Smarty's doesn't have a fixed number of steps in its composition - i.e. layouts can extend layouts and sub-views can be composed of further sub-views, etc.
Hope that helps.

Related

How to right model a MVC class diagram in UML?

I am modeling a movie tickets system in UML. I need to use MVC so I must have a Model; which controls the available tickets in data base, a View; which asks the customer for some data and a Controller; which controls everything and is the path between Model and View. The thing is, I model this system like this:
but my teacher said that I can't use a Composition relationship between the Controller and the View and Model. But I don't understand why because if I initialized the Model and the View inside the Controller (so it can control everything), when the Controller dies, both (Model and View) will not exist anymore. My teacher said I must use an Association relationship. Can you tell me what is the right relationship and why?
The Controller in the MVC pattern manages the interaction between the Model and View, which are both independent things that can exist on their own, therefore it references them (association) they are not composite parts of it (composition).
I would also note in your UML class model example that the terms Model, View and Contoller are solution constructs in a design pattern, rather than specific types that you must have in your design or implementation. The "Model" in your scenario is probably in fact the Ticket business entity, and probably a bunch of other entities as well. The "View" is probably a "TicketDetailsView" or "ListTicketsView" and the "Controller" would be a "TicketController". In the original MVC pattern that was embedded in SmallTalk a View read the Model directly, and the Controller manipulated the Model, whereas there are now many variants of the MVC pattern in which the associations are not quite the same (MVP, MVVM, MVPC, Page Controller, and so on).
For reference I would highly recommend reading Fowler (https://martinfowler.com/eaaDev/uiArchs.html).
The UML specs on p. 110 says:
composite - Indicates that the Property is aggregated compositely, i.e., the composite object has responsibility for the existence and storage of the composed objects (see the definition of parts in 11.2.3).
Composite aggregation is a strong form of aggregation that requires a part object be included in at most one composite object at a time. If a composite object is deleted, all of its part instances that are objects are deleted with it.
So that makes clear that the controller can not compose the Model because thats what permanently stores data. A composition would mean: if the controllers dies, the model shall die too.
About the shared aggregation you use (same box on p. 110):
shared - Indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.
So you need to specify what you actually mean when using it. Or (even better) just leave that diamond away!

Where is representative data placed in the MVP or MVC pattern?

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

Reusable complex read model

In my organisation we have a complex product card with lots of different properties. I could use Steam product card to visualize what I'm talking about: http://store.steampowered.com/app/219740/ (PS: Awesome game, check it).
Product card representation consists of properties such as title, description, price and associations like screenshots, reviews, ratings, tags etc.
Segments of product are used in different parts of application - for example you can find tag lists in user library (where you don't need screenshots).
How would you structure read model here?
a) Try to create small, generic view models (Screenshot, Tag) and composite them in concrete view (ProductCard, UserLibrary)?
b) Create one, god Product view model that'll contain every property that is related to product? (performance-wise - doesn't sound very good)
c) Create property tailored view models for each view? If so, how can I avoid code duplications (we use parts of product on EVERY page) if I have to re-use some specific parts (product title, price etc) all across application?
d) ?
I cannot use event listeners as projectors since product state is changed via legacy CRUD application which we cannot modify - we rely on shared database.
The answer is...
Create property tailored view models for each view
Why? Because it's the simplest and the most maintainable solution. In a read context, you're just dealing with read-only data. You don't need encapsulation or granular representation (a specific model for 'Screenshot' or 'Tag'). That doesn't mean you can't reuse any of the other view models if you already have them and they have the same data, but the main principle here is to create a view model to serve a particular view only.
Duplication doesn't exist in this context, because DRY refers to (same context) behaviour not data.
Why do you want to avoid code duplication ? Or more specifically why do you want to avoid code duplication in different bounded context ;)... If you create dependencies only based in avoiding code duplication you will create a wrong abstraction (not related to a valid use case).
I will quote Sandi Metz :
duplication is far cheaper than the wrong abstraction
prefer duplication over the wrong abstraction
Find more here about wrong abstraction

iOS architecture and components

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.

Trying to follow MVC - Seeking advice on a good design

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.