AngularJS: controller vs service - angularjs

I have read a couple of posts regarding proper usage of angularjs entities: services, factories, controllers and directives.
My particular concern is a comparison of a controller and a service. None of the posts though told me what is that a controller can do what service cannot and vice versa.
Can this be listed or is it just a matter of being canonical in angular's usage?

Controllers are typically used to be bound with a view. Controllers manage a view's life cycle, and should be thought of as View Controllers. A new controller will be created for each instance of a view, meaning that if you navigate away from a certain view, and then back again - or if you have more than once instance of a certain view, a new controller will be created each time.
Services are typically used as the business logic of your application. Services are similar to singletons in the sense that they are created once, and the instance is maintained throughout the entire life cycle of your application. It is a good place to put your logical functions which many views or components will require, and also hold global cache which needs to be accessed throughout multiple areas in your application.

controllers - responsibilities: initialize the view, mediate interaction between view/scope and services. It has dependencies on the view and model, but is more concerned with the view and making it work.
services - responsibilities: provides business services that is not dependent on the view or the controller. Its primary concern is delivering services, regardless of the consumer (controller/view/other services).
I'm not convinced if persistence factors into the differences.

As per the AngularJS documentation, https://docs.angularjs.org/guide/concepts
Controllers are to do with view related business logic. Services, on the other hand, are to do with reusable business logic independent of the views.

In addition to what have been said above. Controllers may also hold the logic of your application while the application isn't so big. But as you application grows you would need to move the logic to use services(like factory). This would allow variables and functions needed around your application to be easily accessible.

Related

Multiple controllers bad for performance?

Does it have an impact on performance to use multiple controllers for the same container?
I'm asking because I'm using several layout modules in my project. I'd like to know if it is easier to have separate controllers and scenes for every module.
the performance is not linked to number of the controllers directly
more controllers for further functionality.
Users Controller where users can create new accounts.
admin interface where you can edit the resources with higher privileges.
is depend on the context of your application you put in one controller if the context is the same
one controller for every table in your database that users can access. But this is really only a very crude measurement.

AngularJS and separate model classes

I plan to use AngularJS verion 1.latest. I'm new to this framework. Previously I was programming in mainly in PHP. I've studied https://docs.angularjs.org/tutorial
As far as I understood - there is no model stricte. Controller has $scope and this is the data layer for view.
Then I have troubles how to logically put data models into Angular application. Assume that data model represents computer: 1 mainboard with some properties, 1..* ram modules, 1..* processors, 1..* hard drives. Each device has its own properties. The data is fetched via RESTful API with several requests.
The data will be shared among few controllers.
How should all this be organized to preserve testability? I'd use Service for operations with REST.
I was talking to very experienced developer. He confirmed what I've studied by myself.
For storing data about PC I use a service (lets call it data-service). Data can be fetched by the same service or another one. Then data from data-service can be accessed in each controller and assigned to controller variables available in view (which should use controllerAs).
The guy also suggested to have as small data models as possible. It should be pure objects (can be nested) preferable without additional methods (opposite to classes from any backend) as they role is only to carry data. This sounds like truth in 90% of cases.

Angular controllers: 1 per view - does it make sense?

I have been thinking about this lately. Up until now I have always subscribed to John Papa's recommendation which can be seen here:
https://github.com/johnpapa/angular-styleguide#controllers
Define a controller for a view, and try not to reuse the controller for other views. Instead, move reusable logic to factories and keep the controller simple and focused on its view.
He gives a reason that I don't understand but for me it was primarily motivated by ease-of-work/maintainability. Basically, in working on large applications, it really sucks to come upon a bloated controller that is responsible for several disparate views. If a developer wants to clean up the controller, he/she has to go to each view and determine what is being used and why (so that methods can be consolidated if they are very similar) which is a big job. Typically (especially if they are under time constraints), they choose to just add whatever functionality they need to the model and to "come back to it later" which is how it got bloated in the first place. Also, I have always used the controller/directive as an indication of whether logic is repeated in many views or not (i.e. if another developer walks up to a controller that I have written he/she can be sure that I have only used it with one view because otherwise it would be directive).
This is a similar problem to the endpoint-problem which basically has people adding endpoints on an as-need basis and the eventually due to new people not knowing about old endpoints or simple forgetfulness the API gets super bloated and repetitive.
However, as I said, recently I have been thinking that this 1-1 controller to view relationship really works against the entire MVC pattern because it couples the model to the view and destroys the separation of concerns. I mean, as long as a controller stays focused (i.e. we have an EditUserCtrl whose job it is to edit a user etc.) then why shouldn't two views be able to use that controller? I mean if the business decides it needs a new view in another place that has the same function, why shouldn't I just write a new view and hook it up to the old controller? I guess what I am saying is that I am having trouble reconciling a convention that goes against the fundamentals of a framework.
Would love to hear others thoughts on this. Thanks in advance.
Like you said yourself. If a controller is responsible for more than one view, any developer can walk up to it, change something in the hopes of adding new functionality to view A and not even knowing it's breaking view B. I think the primarily goal would be to keep controllers clean and neat. That way, it's best to have 2 controllers almost identicals, but with only 2~3 line of codes than to have files being referenced by a numerous number of other files that nobody has control over it.
At one hand, you have to change 2 controllers if something drastically changes in view A and view B, but if it's a complex task, you'll probably have the controllers calling some sort of Gateway and that might mean that you won't have to change any of the controllers at all (good outcome).
On the other hand, if you have 10 different views repeating the same 2~3 lines of code, maybe it's time to abstract the controller functionality.
It doesn't couple the model because the it's best practice to have the business logic in services and view logic in directives , and have there be no real logic in the controllers. So you can one controller per view, but that controller should be very skinny. Personally, I like to only use controllers to assign and communicate variables between services and directives. If you want to reuse controller code, what's stopping you from either putting that logic in directives and services?
Almost none of the controllers I write (and for my job I write a large enterprise application in angular) have logic in them. Granted sometimes logic in controllers is unavoidable, but try to keep as little as possible there.
In this way, the controller stays focused. For a large application, with, say, 10 pages, it's better for both usability and readability to have small controllers for each page instead of one giant controller with a mix of variables, and when you want to re-use methods and functions, put them in services. If you find yourself having three pages with a form or button that has the exact same logic, then that might be better served with a custom directive.

What is the real purpose of ViewModel in MVVM?

I had a talk with teamlead about this topic and from his point of view we can just use bindings and commandings omitting ViewModel, because we can test UI behaviour without VM using Automation or our own developed mechanisms of UI testing (based on automated clicks on Views). So, if there are no real benefits, why should I spawn "redundant" entities? Besides, automated integration tests look much more indicative than VM tests. So, it seems that we can mix VMs and Models.
update:
I agree that mixing VMs and Models brings into single .cs a data model and rules of data transformation for representing it in a View. But if this is only one benefit - I don't want to create a VM for each View.
So what pros of VM do you know?
The VM is the logic behind your UI. combining the UI code with the logic ends up in a mess, at least from my experience. Your view should define what you see - buttons, menus etc. Your VM is in charge of the binding and handling events caused by the user.
Edit:
Not wanting to create a VM for each view doesn't sound like a SW-oriented reason. Doing so will leave your view clean of logic and your model free to be the connecting layer between the core layer and your app layer.
I like the following example referring to the model and its role (why it shouldn't be combined with the VM): imagine you're developing some Android app using Google maps. Google maps are your core. Then one fine day you really need the option to, say, color parts of the map in pink, bright pink. An email to Google asking for colorPink(Map)will probably get you nowhere. That's where your model steps in and provides you the map wrapper that you need to define your pinky method.
Without a separate model, you'd have to go through every VM that uses map and update it.
So, the view has a role, the model has a role, the VM is the logic between those.
Edit 2:
There are some cases where there's no need of a model layer - I tended to disagree at first but was convinced after a discussion: In relatively small applications, the model can end up being a redundant wrapper with no added functionality over the core. In such cases, you can use the core objects directly.
What is he binding to? Whatever he is binding to is effectively a view model, whether you call it that or not. If it also doubles as a data model, then you're violating the Single Responsibility Principal (SRP). Essentially, the problem here is that you're lumping together code that is servicing different parts of the application architecture, which will lead to a convoluted mess.
UI Testing is a pain not just because you need to accomodate for changes in the View which can occur many times but also because UI tends to interfere with its own testing. Depending on the tests needed you'll need to keep track of focus, resize and possibly other (mouse) events which can be extremely hard to make it a representative test.
It is much easier to scope the test to the logic in the ViewModel and leave the UI testing to humans. The human testers do not need to test the logic; their only consern should be the UI.
By breaking down a ViewModel into a hierarchy of ViewModels you might be able to reuse a ViewModel multiple times. There is no rule that states that you should have a ViewModel for each View. (After a release or two I end up there but that's besides the point :) )
It depends on the nature of your Model - sometimes they are simple and can serve as both like you are suggesting. However, depending on the framework, you'll need to dirty up your model with some PropertyChanged event code which can get messy and distracting. In more complex cases, they serve as a mediator between your the view and the model. Let's suppose you're creating a client app that monitors a remote process or database entries - creating View Model's for these entities let's you surface your data in a way that is convenient to bind to for a UI framework (but is silly in a DB framework), encapsulate operations as commands, perform validation, etc etc.

CakePHP - where to put service logic

I am Java programmer who tries to investigate CakePHP - currently I have problem with application structure/design. I could not understand where to put core logic of application.
When I am developing in JavaEE, common approach looks like following:
Model classes are simple beans which represent data entities (products, people etc) - mostly like data structures with getters/setters;
Controller classes are simple enough classes which aggregate necessary data and inject them into dedicated View template which is then sent to user;
DAO (DataAccessObject) or Repository classes are ones which can load and store entities into database;
Service classes are usually singletons which contains certain business-logic methods - these are called by controllers, by other services or by scheduled actions, on the other hand they themselves call DAO / Repository methods to fetch or modify data.
For example if I have entities Person, Product and Order, when user selects some product and clicks "put it into my cart/basket" new Order for this Person should be created and this Product should be added to this Order (we may check that Person is not bad debtor and that Product is present at store etc.) - all this work is performed in methods of OrderService called by some controller.
Usually some kind of IOC (Inversion of Control) is used so that all services and controllers have links to necessary services etc.
Now I am slightly bewildered about how this all is done in CakePHP. Where should I put this business-logic etc. ?
In CakePHP the model layer is made up from collection of active record instances, called AppModel. They combine the storage-related logic (that you would usually put in DAOs and/or Repositories) with business logic (what usually went into your "models").
Any other domain related logic (from your Service) becomes part of controller.
If you want to know, how you are supposed to implement domain business logic in CakePHP, just look up articles which praise active record pattern.
Personal opinion
CakePHP and CodeIgniter are two of the worst frameworks in PHP. They are filled with bad practices.
Actually, if you were doing correct-ish MVC, then model layer would contain all of the business logic and everything that is related to it. Model layer is made of DAOs, Repositories, Domain Objects (what you call "models") and Services.
While your descriptions of Java-based code indicates, that you are kinda moving in that direction, CakePHP is not even remotely close to it.
Then again, it might be that my understanding of MVC is just wrong.
The controllers should only contain logic relevant for the whole thing being a web application. Your business logic belongs into the models. I think it is one of the basic mistakes that you find in many cakePHP applications, that to much logic is put into the controllers, which actually belongs into the models.
In CakePHP. the "M" is just a bunch of Data Models instead of Domain Models.
In my opinion. CakePHP is made for RAD development. It is not a good fit for enterprise applications.
My opinion though.

Resources