(MVC) Controller in shared library? - model-view-controller

In MVC, do controllers belong with an application, or can they go into a shared library? For example:
//this is a shared library
LibShared
//these are two apps
appA ->LibShared
appB ->LibShared
Shouldn't each app implement its own MVC and use any shared libraries as perhaps part of the app's logical model or simply another library reference (utilities)?
Also, is there ever a situation in which an MVC Controller is stuck in a shared library? I thought Controllers needed specific views located in a specific app. Meaning, the Controller must go in that app?
Or can Controllers be generic (i.e. shared library)? Doesn't that mean they are no longer Controllers?

I would advise that you should only be separating out your controllers into their own module/package/library (herein referred to as modules) if you have a requirement to do so (i.e. immediate re-use). If no such requirement exists at present then I would defer the decision to when it is required, it sounds in your case you are about to unnecessarily over-engineer. It should in theory be possible to refactor later to a separate modules without much hindrance, however be careful regarding coupling, separating out to different modules doesn't reduce the coupling, look carefully at your dependencies at how much the controller is orientated to one style of view.

one liners answers to your question to your application is
YES, YOU CAN MOVE YOUR CONTROLLER TO A SEPARATE LIBRARY WITHOUT A SINGLE LINE CODE CHANGES.

I suppose any code can go anywhere, what would drive us to put something in a shared library or keep it with the app?
I would consider two things:
1). What's the rate of change? When we change the app overall is this likely to change.
2). Could anything else need to use it? If so when I realease a new version would the other client immediately
Typically a controller would be strongly associated with the application and hence not of much interest to any other app, and it's probably fundamental to the app changing as the app changes. Hence packaging with the app makes sense.
Now if the conroller is somehow more generic, perhaps configuration driven then shared library makes sense.

Controllers does not necessarily needs to be even in the same operating system. You could have a view in Windows, a Controller in Unix and your Model in a Sparc. Remember MVC is just a pattern, a way you could do something which is more robust and easier to modify.
Your controller could be a shared library. Does your controller should be aware of your views? Not necessarily. That depends on how you handle the communication between modules. On a good MVC implementation, modules simply interchange messages or events. So, a View send an event to the Controller, the Controller decides what to do and send a message back. The response of the controller could be something like "Show Window X". Be advised that "Window X" could be interpret by the View module, if the View is an a Web module, then the View just put the proper aspx page. If you have another view who happens to be a web application the renders Form X.

At least in CakePHP and in the architecture that Mike McShaffry explains in his Game Coding Complete book the controller does belong to the application.
However, in both cases the architecture is such that the application inherits the basic functionality of a model, view, and a controller from the framework.
Eg.:
// "super" controller of all applications using this framework
class Controller
// uses basic libraries that allows the inheriting applications to work minimally
class AppController extends Controller
// mainly uses the parent class's methods but can also substitute to using
// additional libraries
By framework here I mean the system that encapsulates the use of libraries. In CakePHP this encapsulation in turn is done by using libraries in the respecting models, views, and controllers. So neither of those components is free from attachment to libraries.
In Mike McShaffry's architecture however, only the controllers and views use libraries. So the models are left uncoupled and are thus highly portable to different applications.

Related

Where Do I Create External API functions or Classes? Proper MVC Structure for Web Frameworks

I am looking to add multiple API's to my senior project on an MVC based framework (Laravel). I understand the basic concept of MVC, but want to make sure that I am doing things according to best practice.
Basically, I am going to have a class/function that takes a query and calls that query on a Amazon's Product API. I have seen an example of calling API's from directly within the Controller on Laravel (see http://www.phplab.info/categories/laravel/consume-external-api-from-laravel-5-using-guzzle-http-client).
Perhaps I don't understand MVC well enough. Should an external API call be in it's own class? And if so, should it be a Controller Class or a Model Class? I hope the Stack Overflow gurus can enlighten me. Let me know if I need to clarify anything!
It depends to what you want to process with external API.
If it's a part of the business, it can be in Model (lot of people put
the business inside the model to follow the encapsulation principle
of OOP).
If it's the explicit process, it should be in Controller
(like most people do).
For example, if you have a model Transaction in bank transfer (that automatically convert the currency, it needs the external API to get the exchange rate), the external API call should be wrapped in model. So controller cannot modify the Transaction object and it will be safe.
In another hand, you can call to external API in controller, do some extra stuffs then set it back to Transaction object. It's also good because model always contains only properties. It makes application also clear enough.
They are 2 ways of use, none is absolutely right or wrong. But if you choose one, follow it, don't mix.
Another, both 2 are only ok. The better way is putting the external calls to other places (modules etc), then call it by single line in model or controller.

Layered architecture mvc

I'm creating a web app using an MVC framework. I thought of adding a layer between the controller and the domain models, I think it's called application layer in DDD, to avoid putting logic that is specific to a certain use case in the domain models.
The controller will only interact with this layer and this layer will orchestrate the operation using the domain models. This layer will be kept as thin as possible pushing all the logic that is not use case specific to the domain model.
I will call the classes that belong to this layer DomainCtrl.
Example login scenario:
Model: LoginForm
DomainCtrl: AuthCtrl
UI: ui controller
1.ui controller receives request
2.creates instance of AuthCtrl
3.AuthCtrl creates instance of a LoginForm and fill it with request data passed to authCtrl
4.LoginForm performs the login
5.authCtrl does other things that are specific to this specific way of login -> returns errors to ui controller
Is this a good way to organize an app?
Your question
Is this a good way to structure an app
is a very loaded question. The simple answer is Yes, but the more correct answer is It depends.
Let's start with the simple answer. Having your main application be unaware of the UI is generally a good idea. It means that you can easily consume your application from various places. In DDD this outer layer is usually called Application Layer. It is mainly responsible for orchestrating interactions between your domain, persistence and other resources that you might rely on. This also allows you to have your domain at the center unaware of everything else. This makes your domain easily testable and maintainable if implemented well.
Now the "it depends" part of the answer. DDD is not the only successful way to build an application, and in some cases it might be more of a hinderance than anything else. You have to ask yourself what is my app doing. Are there many domain specific rules? Am I only fetching and storing basic data etc? These are all questions you need to answer before you choose an architecture and technologies.
I would still say you probably won't go wrong by choosing the DDD approach as it is generally a good way to do things.
*Note: Your example is not that clear to me but you should be careful of spilling UI concepts into your domain/application. A login form is completely a UI concept as is auth to a certain extent. You can probably have your application return the details of your user, but the UI layer should decide if the user is allowed to proceed or not.
At a high level view, Yes
But it ultimately depends on "how" you logically separate your layers. In your scenario, I don't see any application layer.
I assume AuthCtrl is the domain? Who creates AuthCtrl? what layer does it exists?

Controller in Backbone.js

I'm new to Backbone.js. I have gone through the documentation. My question is
where does the controller concept come into picture? In other words, what is a controller in Backbone.js?
I heard that the router is the controller. If so, why it is considered as a controller? Can we develop simple basic apps without the Router also? In that case what will be the controller?
To clear things a little bit here. A Router is not a Controller, It's a way to define a client-side route map (similar to Rails's routes.rb). This helps routing client-side pages to certain actions/handlers. And that's different from a controller's job which is to provide a bit of orchestration between Models and Views. And there is actually more than one way to do this using Backbone. Quoting from Backbone's documentation:
References between Models and Views can be handled several ways. Some
people like to have direct pointers, where views correspond 1:1 with
models (model.view and view.model). Others prefer to have intermediate
"controller" objects that orchestrate the creation and organization of
views into a hierarchy. Others still prefer the evented approach, and
always fire events instead of calling methods directly. All of these
styles work well.
This brings three different approaches to accomplish this. The first one is pretty straightforward which is to have the model object included as a property to the view.
The second one proposes including a third component that performs this role of orchestration. I believe this can be helpful in quite large and complex applications. For this I encourage you to look at Chaplin, a sample application architecture using Backbone.js. The guys have done a great job in separating things out and also introduced the concept of a Controller into the architecture.
The last approach is suggesting using events to mark for actions and mediator to handle these actions. For this I encourage you to look into the mediator and Publish/Subscribe JavaScript patterns.
Check out Addy Osmani`s article on MV* on the client:
http://addyosmani.com/blog/understanding-mvc-and-mvp-for-javascript-and-backbone-developers/
From the article:
In Backbone, one shares the responsibility of a controller with both the Backbone.View and Backbone.Router.
and
In this respect, contrary to what might be mentioned in the official documentation or in blog posts, Backbone is neither a truly MVC/MVP nor MVVM framework.
It's more similar to how for example iOS Cocoa Touch framework works, you shouldn't think about it like a backend MVC, backbone team itself even never mentions MVC on their website to avoid confusion people often have when coming from backend MVCs. The View in backbone is what's called in iOS a ViewController/AppController and usually your main AppController will be a View which sets the main wrapper for your application which usually you would also use as a global pub/sub system and controller for your main app logics.
Router is exactly what it say - it converts routes into set of params and passes them to the app controller to figure out what to do with them, what subview to load etc. (or if application is less sophisticated it can load/change the views straight from the router level) - It used to be called controller but it was renamed in (0.5 I believe?) to clear this confusion.
At least this is our approach - if you checked multiple tutorials in the wild you've probably seen that when it comes to Backbone there are as many approaches to this as many developers there are. And that's what is beautiful about Backbone! :)
Usually I make my own controllers, and let the router do it's thing (catching routes, and pointing towards a controller action). These controllers are home made, just javascript objects with methods on them. They take the request from the router, collect the right data (collections, models...) and take the necessary view, combine them and pass the data into the view.
from there on it's backbone again.
however recently I came arcoss a 3rd party backbone plugin called backboneMVC. Have read it's documention, but have yet to try it out myself.
It aims to take over your router and make routes based on your controllers and actions you define with it.
Take a look at that library however I cannot promise anything because I have yet to build something with it myself.

MVC programming practices

I'm working on some new software, and I'm trying to make it as modular as possible. I have been coding for a while..but I lack some key principles which I am learning as I go along.
In trying to make my current project modular, I am using the model-view-controller architecture. In designing my application, I have found certain things I am unsure of. So I come to you...
I'll give you some information which may be useful:
I am developing this application in Qt.
It is a desktop application.
Single user, so it is not very complicated
My questions are:
When implementing the various modules(models, views etc..) and all
of the classes associated with them, should I be initializing
modules within modules? Should I create a 'model' instance within a
'controller', or should I create everything in 'MAIN' and simply
pass the modules as references?
My strategy is to separate my application into many MVC bundles.
Each one will follow the basic principles: model gets the data, view
displays it, and controller takes care of all interactions between
model-view, and performs all required logic. Is this correct?
I appreciate all of your help.
Thanks.
Should I create a 'model' instance within a 'controller', or should I create everything in 'MAIN' and simply pass the modules as references?
Pass the modules as references. I don't know if Qt has the concept of packages within a bundle, but in Java, I have separate packages for the model and the view.
My strategy is to separate my application into many MVC bundles. Each one will follow the basic principles: model gets the data, view displays it, and controller takes care of all interactions between model-view, and performs all required logic. Is this correct?
Yes, that's correct MVC principles.
Sometimes in a more complicated application, your application view might consist of the GUI (a view) and a model of the GUI (a model). In this case, the application model, which is probably a database access model, interacts with the GUI model. The controller for both the GUI and the application is driven by the actions of the user.

Tips/tricks for architecting MVC in non-trivial desktop app

What are some lesser known tips for implementing a loosely-coupled MVC structure in a non-trivial desktop application (e.g. having at least two levels of views/controllers and more than one model)?
Use interfaces.
A lot. I like using the "IDoThisForYou" style (even in a language where this isn't idiomatic) because an interface represents a role that another class can use.
Make the controllers responsible for controlling interaction
The controllers control interaction between domain objects, services, etc.
Use events to pass information between controllers
Let every controller who needs information subscribe to the event. Use an interface.
Don't put presentation information on your domain objects
Instead, allow the controller to create a presenter or view model which has the information you need. This includes no "ToString()". If you're in a language without multiple inheritance you might end up with a bit of duplication between presenters. That's OK - duplication is better than coupling, and the UI changes a lot anyway.
Don't put logic in your gui
Instead, allow the controller to create a presenter or view mdoel which has the information you need. This includes train wrecks like "MyAnimal.Species.Name" - make it present "SpeciesName" instead.
Test it
Manually. There is no substitute. Unit and acceptance testing goes a long way, but there's nothing like bringing the app up and actually using the mess you wrote for finding out how messy it is. Don't pass it to the QAs without having a go yourself.
Oh, and don't mock out domain objects in unit tests. It's not worth it. Use a builder.
Declare event handlers in your interfaces (important for the views). This way you can loosely couple event handling which is managed by the controller. You may need to use the InvokeRequired when working with the view if your application is multi-threaded.

Resources