First of all i know MVC well and have been using it in project but when it comes to organizing classes and there role i am bit not sure of there proper implementation. Lets take a scenario to proceed with:
A sample which will display All Employee and Department. Data will be fetched from Web Services(Json) and will be stored as offline(Core Data).
So MVC pattern would be:
View will be my storyboard with Employee and Department UIViewController.
Controller will be EmployeeViewController.swift and DepartmentViewController.swift
Model will be Employee.swift and Department.swift
class Employee: NSObject {
var name: String?
}
class Department: NSObject {
var departmentName: String?
}
ServiceManager which will make calls to the web service.
ParseData which will parse the web service response and convert it into Employee and Department objects
CoreDataManager is singleton class to manage CRUD operation on offline DB.
Here are series of question on the above scenario which i have:
Is my understanding correct? Is the structure which i am trying to build follows proper MVC?
How the controller will interact with these components (Service Manager, ParseData, CoreDataManager). Should there be another class which will facilitate the communication between controller and data management(if controller does this then it will a tightly-coupled structure and massive as well).
Should Model be having any code other then property and initialization method as most of the model which i have seen only have property declaration?
Should there be separate UIView classes instead of storyboard to create a proper MVC structure?
Is my understanding correct? Is the structure which i am trying to
build follows proper MVC?
First I will say that "proper" MVC will depend on who you're asking. Its origin is commonly attributed to Trygve Reenskaug when he introduced this into Smalltalk in the 70's. However, his type of MVC was widely different from the bloated versions most commonly used today. The modern way of thinking about MVC is
Model = mostly a dumb class which primarily encapsulates data
View = whatever we present on the screen
Controller = the big lump of code that does almost everything,
sometimes offloaded by a manager class or two of some sort
Reenskaug, however, would have a model and a view and a controller for a button. For a label. For a field. I'm not saying that is what we should strive for, but there should be better ways to structure a project than using the Massive ViewController pattern (as it is jokingly referred to in the iOS community).
Luckily, there are.
Uncle Bob is preaching Clean Architecture. There are several implementations of this, and various people have made their own implementations of this for iOS, like VIPER and Clean Swift.
How the controller will interact with these components (Service
Manager, ParseData, CoreDataManager). Should there be another class
which will facilitate the communication between controller and data
management(if controller does this then it will a tightly-coupled
structure and massive as well).
Following the principles of Clean Architecture, you should encapsulate these functionalities into layers, in a way that enables you not just to split the code into multiple components, but also enables you to replace them with other components when that is needed. (But yes, at the very least avoid putting all of this in your controller!)
Should Model be having any code other then property and initialization
method as most of the model which i have seen only have property
declaration?
Again, there is not a single answer here. Some proponents of "real" OOP will say that each object should be self-served (i.e. a model object should know how to persist itself), while others extract the knowledge of such operations into "managers". Putting code to persist an object into the object could mean littering persistence functionality into many objects, or require you to rely on subclassing or other solutions to avoid this coupling.
Should there be separate UIView classes instead of storyboard to
create a proper MVC structure?
Storyboard or not does not determine whether you're using "proper" MVC. Also, what kind of class you're choosing (UIView or UIViewController) to represent the View is also not important. Your ViewController can be dumbed down to such a degree that it contains no logic (forwarding the logic that it DOES have to another class, i.e. the Presenter in VIPER).
I would recommend reading about the Clean Architecture and maybe watch a video of Uncle Bob explaining it, read other people's reports on implementing it, and then consider whether MVC is the correct pattern for your iOS project.
Related
I have been doing iOS development using MVVM and dependency injection for a couple of months and I am really happy with the results. The code is so much clear and easier to test. But I have been stragling with a problem which I haven't found a solution that I felt really confortable with.
In order to understand the problem I want to give you a little bit of context. The last app that I have been working was architectured in the following way / layers:
Model
View models
View / View Controllers
Services: Classes that know how to deal with external services like Twitter, Facebook, etc.
Repositories: A repository is class that knows how to interact with a resource of the application's REST API. Lets say that we have a blog application, we could have the users resources and the posts resources. Each of thoses resources have several method. There is a 1-to-1 relation between the resources and the repositories.
When the applications starts we have a Bootstrap class that initializes the app and creates the main view model. We have a restriction that only view models can create other view models. For example in the case of having a view that contains a list of elements (in iOS it will be represented with a UITableView) and the detail view for each of thoses elements that is presented by pushing it to the navigation stack after tapping on the element in the list. What we do is make the view model that is attached to the table view controller create the detail view model. The table view controller listens to the table view model and then presents the detail view model by creating the detail view controller and passing it its view model. So the view controller does not know how to create a view model it only knows how to create a view controller for that view model.
Is the responsability of the parent view model to the pass all the dependecies to the child view model.
The problem comes when a view model that is very deep in the view hierachy needs dependencies that its parent controllers does not require. For example a service to access some external web service. Because its parent does not have that dependency it will have to add it to its dependecy list, thus adding a new parameter to the constructor. Imagine how this goes if the grand parent does not have the dependecy either.
What do you think is a good solution? Possible solutions:
Singletons: Harder to test and they are basically gloabl state
A factory class: We could a set of factory that knows how to create certain types of object. For example a ServiceFactory and RepositoryFactory. The service factory could have method to create services like: TwitterService, FacebookService, GithubService. The repository factory could know how to create a repository for each of the API resources. In the case of having a few factories (2 or 3) all the view models could dependent on this factories.
For now we have chosen the factory class solution because we don't need to use singletons and we can treat the factory as any other dependecy which makes it relatively easy to test. The problem is that it kind of feels like a good object and by having a factory you don't actually know which is the real dependecy that needs the view model, unless you look inside the constructor's implementation to check which factory methods are being called.
In our application, we have chosen to have our view models access their dependencies via dependency lookup rather than dependency injection. This means the view models are simply passed a container object which contains the necessary dependencies, and then "looks up" each dependency from this container object.
The major advantage of this is that all objects in the system can be declared up front in a container definition, and it is very simple to pass around the container, compared to the seventy-eight or so dependencies that might be needed.
As any dependency injection fan will tell you, dependency lookup is certainly its inferior cousin, largely because dependency lookup requires the object to understand the idea of a container (and therefore usually the framework that provides it), whereas dependency injection keeps the object blissfully unaware of where its dependencies came from. However, in this case I believe the tradeoff is worth it. Note that in our architecture, it's just the view models that make this tradeoff - all other objects such as your "models" and "services" still use DI.
It's also worth noting that many basic implementations of dependency lookup have the container as a singleton, but that does not have to be the case. In our application, we have multiple containers that simply "group" related dependencies together. This is particularly important if different objects have different lifecycles - some objects may live forever, while others may only need to live while a certain user activity is in progress. This is why the container is passed from view model to view model - different view models may have different containers. This also facilitates unit testing by allowing you to pass a container full of mock objects to the view model under test.
To provide some concreteness to an otherwise abstract answer, here's how one of our view models might look. We use the Swinject framework.
class SomeViewModel: NSObject {
private let fooModel: FooModel
private let barModel: BarModel
init(container: Container) {
fooModel = container.resolve(FooModel.self)!
barModel = container.resolve(BarModel.self)!
}
// variety of code here that uses fooModel and barModel
}
What you need to do is move the instantiation of all your objects to a Composition Root. Instead of parents passing down dependencies they don't even necessarily need to their children, you have a single point of entry at the start of your program where all of your object graph is created (and cleaned up, should you have Disposable dependencies).
You can find a good example here, by the author of the Dependency Injection in .NET book (highly recommended to understand concepts like the Composition Root) - notice how it frees you from having to pass dependencies 5 or 6 levels deep for no reason:
var queueDirectory =
new DirectoryInfo(#"..\..\..\BookingWebUI\Queue").CreateIfAbsent();
var singleSourceOfTruthDirectory =
new DirectoryInfo(#"..\..\..\BookingWebUI\SSoT").CreateIfAbsent();
var viewStoreDirectory =
new DirectoryInfo(#"..\..\..\BookingWebUI\ViewStore").CreateIfAbsent();
var extension = "txt";
var fileDateStore = new FileDateStore(
singleSourceOfTruthDirectory,
extension);
var quickenings = new IQuickening[]
{
new RequestReservationCommand.Quickening(),
new ReservationAcceptedEvent.Quickening(),
new ReservationRejectedEvent.Quickening(),
new CapacityReservedEvent.Quickening(),
new SoldOutEvent.Quickening()
};
var disposable = new CompositeDisposable();
var messageDispatcher = new Subject<object>();
disposable.Add(
messageDispatcher.Subscribe(
new Dispatcher<RequestReservationCommand>(
new CapacityGate(
new JsonCapacityRepository(
fileDateStore,
fileDateStore,
quickenings),
new JsonChannel<ReservationAcceptedEvent>(
new FileQueueWriter<ReservationAcceptedEvent>(
queueDirectory,
extension)),
new JsonChannel<ReservationRejectedEvent>(
new FileQueueWriter<ReservationRejectedEvent>(
queueDirectory,
extension)),
new JsonChannel<SoldOutEvent>(
new FileQueueWriter<SoldOutEvent>(
queueDirectory,
extension))))));
disposable.Add(
messageDispatcher.Subscribe(
new Dispatcher<SoldOutEvent>(
new MonthViewUpdater(
new FileMonthViewStore(
viewStoreDirectory,
extension)))));
var q = new QueueConsumer(
new FileQueue(
queueDirectory,
extension),
new JsonStreamObserver(
quickenings,
messageDispatcher));
RunUntilStopped(q);
Doing this is pretty much a prerequisite to do proper Dependency Injection, and it will allow you to very easily transition to use a container if you want to.
For the instantiation of objects that must be created after startup, or depend on data available long after startup, what you want to do is create Abstract Factories that know how to create these objects and take as constructor parameters all needed stable dependencies. These factories are injected as normal dependencies in the composition root, and are then called upon as needed with the variable/unstable arguments passed in as method parameters.
Here are a couple of suggestions.
Best coding practices suggests that if you are using more than 3 parameters, then you should use a class to host the parameters.
Another approach is to separate the data services [repositories] out, so that they line up to a task based service. Mainly to in line with the ViewModel (or Controller) So if you ViewModel uses Customers and Orders, most would use two services - one for CRUD operations on Customers, and one for CRUD operations on Orders. You could, however, use a service that will deal with all the operations needed for your ViewModel. This is a task based approach used in designing Windows Communication Foundation Services and Web Services.
It looks like you need to make use of the Managed Extensibility Framework (MEF), you can find more information here.
Essentially, what this will allow you to do is to use [Export] and [Import] attributes. This will allow your class' dependencies to be injected, without having to worry about massive constructors on your parent view models.
lately I've been toying with the idea of placing ViewModels in a separate project and populating them in repositories, then handing them to the controller. This could make for really thin controllers.
What is this pattern called?
Hexagonal Architecture has this notion of Adapters, in this case you're adapting from business objects to presentation objects.
However :
If you mean repositories as in persistence layer repositories, it's typically not their responsibility to populate presentation-specific data structures. The persistence layer shouldn't know about the UI.
"Thin controller" doesn't mean you have to place the ViewModels or ViewModel population logic in a separate project. Besides, just because a controller shouldn't contain this logic doesn't mean it can't invoke it. Your controller can call an Adapter object from the same MVC project to convert from whatever it receives to ViewModels, or you could just do the conversion in the ViewModel's constructor.
While #guillauem31's answer is usefull, I think it was missing a bit, and a bit misleading
In short, an adapter is
Adapter
The ‘Design Patterns’ book contains a description of the generic ‘Adapter’ pattern:
“Convert the interface of a class into another interace clients expect.”
In my mind, I'd like to place an adapter between the controller and repository.
He usefully suggests that the adapter can be in a constructor of the viewmodel. I'm not sure I like this, but it seems okay.
I'd really like to keep my models as simple class objects if possible.
So I'd be equally okay with populating the viewmodels in a service layer.
and I guess thats where this question comes in...
Fat model / thin controller vs. Service layer
and here is an approach where the viewmodels are populated using an adapter of sorts
http://paulstovell.com/blog/clean-aspnet-mvc-controllers
I use ASP.NET MVC 3.
I encountered at least 2 approaches for mapping Model->ViewModel on the server side:
inside ViewModel class constructor
inside Controller or designated mapper class
I like first approach the most as the ViewModel property declarations and its mapping are in the same place, easy to maintain and unit-test. Can anybody specify more pros and cons, or other better practice?
ViewModels can exist independently of any database-originated model classes.
I don't recommend putting ViewModel population code inside the Controller as this it not the responsibility of the controller (and is also a maintenance nightmare).
My opinion is that mapping from ViewModel to DBModel (and vice-versa) is the responsibility of the ViewModel, so all of my ViewModel classes implement two members:
public static TViewModel FromDBModel(TDBModel dbModel);
public void ToDBModel(TDBModel dbModel);
The first is a static method that the Controller calls when returning a View. The static method constructs an instance of the ViewModel and sets its members accordingly.
The instance ToDBModel method is passed a constructed DBModel instance (either constructed by the Repository when retrieving or updating data, or constructed by the controller when inserting new data).
HTH.
EDIT: Note that many people swear by libraries such as AutoMapper (which uses reflection and other tricks to automate the DBModel<->ViewModel mapping process). I'm not a fan of auto-mapping because it takes control away from the developer and I don't see it buying me time when I have to learn how the mapper works and how to get it to map non-trivial operations. YMMV.
I'll tend to keep entities and view models separate such that they are unaware of each other. This is to improve encapsulation and minimize dependencies when testing the controllers and mapping itself. See Separation of concerns.
Instead I'd write classes to perform the mappings myself (if its simple) or use AutoMapper and use that method from within the controller. For a larger systems with tens or hundreds of database entities and views, I tend to lean towards AutoMapper. Writing the mapping yourself can become very tedious and error prone. You have to balance the value of you writing it yourself with the value such implementation gives to business. After all, if we wanted to know everything about every framework, we'd each be writing our own version of the .NET framework. :)
That said, there may be little benefit using view models for some systems, especially those where there is a one to one mapping between "fields" in a view and database entities [aka typical CRUD]. I usually cringe when I see that, but it is always an option given a time frame and complexity of the system.
Then there is a case when you use ASP.NET MVC to expose an API. In this case "application/json" and "text/xml" representations of your entities are just "views". View models are often used filter sensitive and unnecessary data from that external presentation. In this case mapping becomes rather complex due to the fact that there may be several representations (and versions thereof) for the same entity. However, this seems outside of the OP.
I'm just getting started with Dependency Injection (DI) using Ninject and am working through my controllers looking to decouple them from my models a bit more.
At the moment, inside of my controllers I am creating an instance of some given model e.g:
var activitiesModel = new ActivitiesModel();
For each of my models that I've been instantiating in this way, should I extract an interface for these and then use DI to tie these things together?
An example of where I'm currently doing this is inside my ActivitiesController:
IActivitiesModel _activitiesModel;
public ActivitiesController(IActivitiesModel activitiesModel)
{
_activitiesModel = activitiesModel;
}
and this is tied together in my global.asax:
Bind<IActivitiesModel>().To<ActivitiesModel>();
Is this the correct way to go about doing this? Should I be creating a new interface for each of my models that is instantiated inside of a controller?
Cheers for any help and nudges in the right direction :-)
It depends on what those models are doing. If they posses data access and manipulation methods then they should be abstracted to weaken the coupling between your controller and data access logic and ease the testing in separation. If they are simply POCO and/or data transfer objects then you don't need to abstract them.
I recently followed Stephen Walther through creating a generic repository for your data models using the Entity Framework with the following link, http://bit.ly/7BoMjT
In this blog he briefly talks about creating a generic repository and why it's suggested to do so (to be clear of friction). The blog itself doesn't go into great detail on how to inject the GenericRepository into your project for that you'll need to download his source code of Common Code. However, once I finally understood the importance of the Repository pattern, and how it makes a difference in the data models I create in ASP.Net MVC I was wondering if I could do something similar to my Controllers and Views?
Can I create a ControllerRepository or ControllerFactory(as I've Bing'd it) and create a generic controller with 5 ActionResults and depending on what I inject into my GenericRepository datamodel (i.e. I have DellXPSComputers, GateWayComputers, HPComputers as a single db datamodel)
And actually have only one controller besides the Generic one I create that will go and grab the right datamodel, and view?
If so, what is the best way to implement this?
You could create a generic controller factory, but I don't see many scenarios why you'd ever want to. Except in your tests and redirects, you'd never be calling a controller method directly (vs. a repository method which you're calling in many places).
Yes! You absolutely can!
I've done it in the past with great success. The result is that you end up with a web application layer surfacing your repos with almost no code (just what's necessary to provide CRUD services for your entities).
Ultimately, you'll end up with something like this in your implementation of CreateController:
Type controllerType = controllerbase.MakeGenericType(entityType, datacontextType);
var controller = Activator.CreateInstance(controllerType) as IController;
return controller;
Wiser men than me would use a IOC framework to inject the types, I'm using plain old reflection and reading the type names out of the route values in URLs like:
http://computer/repo/entityname/by/fieldname/value.html
Good luck!