Should a Model interact with external services? - model-view-controller

Example 1:
A Model class "News" stores its text in two different languages (fields: en_text, jp_text). Usually it has text in only one language. Should I translate the text in callback before_save using the Google Translate API, or should I place this code in the Controller?
Example 2
A Model class "Payment". When the payment is going to be settled, the system must notify an external service about the successful settling of the payment. Where should this code be placed, Model or Controller?

The model is usually used to "get" or "set" data, so technically speaking, if your external service provides a service to "get" or "set" data, then yes.

Your Models should be literally the whole business logic of your application. Requirements for your Application mean that you should translate your text or notify some service on payment, don't they? That means that you should write it in your Model.
Controller is an entity that processes request parameters to some business logic actions. Controller should not contain such parts.
As I know, you are using Rails for now, so look at following links (this patterns are also helpful for non-Ruby programmers):
http://api.rubyonrails.org/classes/ActiveResource/Base.html
http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model - classics :)

Related

Creational adapter

I have a lot of code like this
additional_params = {
date_issued: pending.present? ? pending.date_issued : Time.current,
gift_status: status,
date_played: status == "Opened" ? Chronic.parse("now") : (opened.present? ? opened.date_played : nil),
email_template: service&.email_template,
email_text: service&.email_text,
email_subject: service&.email_subject,
label: service&.label,
vendor_confirmation_code: service&.vendor_confirmation_code
}
SomeService.new(reward, employee: employee, **additional_params).create
The same pattern applies to many models and services.
What is the name of this pattern?
How to refactor the current solution?
Is there a gem to solve this kind of solution? Like draper or something else
To me, that looks a bit like a god object for every type of entity. You expect your service to take care of everything related to your entity. The entity itself just acts as a data container and isn't responsible for its data. That's called an anemic model.
First of all, you need to understand that there can be several representations of the same entity. You can have several different classes that represent a user. On the "List user" page, the class contains just a subset of the information, maybe combined with information from the account system (last login, login attempt etc). On the user registration page, you have another class as it's not valid to supply all information for the user.
Those classes are called data transfer objects. Their purpose is to provide the information required for a specific use case and to decouple the internal entity from the external API (i.e. the web page).
Once you have done that, your service classes will start to shrink and you need fewer custom parameters for every method call.
Now your service class has two responsibilities: To manage all entities and to be responsible for their business rules.
To solve that, you should start to only modify your entities through behaviors (methods) and never update the fields directly. When you do so, you will automatically move logic from your service class to your entity class.
Once that is done, your service classes will be even cleaner.
You can read about Domain Driven Design to get inspired (no need to use DDD, but get inspired by how the application layer is structured in it).
You can try the builder pattern. I am not familiar with a ruby gem, but you can find information here: https://en.wikipedia.org/wiki/Builder_pattern and https://en.wikipedia.org/wiki/Fluent_interface

Responsibility of Controller or Service?

I have a question about responsibility of Controller and service about a piece of my code. I have a HTML form to save an article which can submit three image(thumbnail, summary and body) with their text. The body text can contains some images in Base64 format. I get them by a post Action which accept a DTO object to support all inputs.
The Tasks I want to do are:
Get DTO from client
Fetch images from body
Check Summary and body text rules
Check Fetched images rules
Check Thumbnail, summary and body image rules
Save them
I have a service layer here which has some class about checking article texts and images logics.
My question is that how should I act here. Which steps are for Controller and which ones for Service.
Step 2 is most confusing step to me. Should I do it in controller or just pass all DTO to Service to separate things itself?
Or about checking text, should I check for example summary text length in controller or it should be check by Service layer?
Can any one explain these to me?
Possible duplicate.
The responsibility of the controller, is to accept a request, invoke the processing, and respond according to the result of the processing.
Try to look at the SOLID principles and always try to apply them.
So first of all, DTO, it depends on your architectural design, but I would say that the DTO is the abstraction that allows you to decouple you Domain Model from the client model.
The DTO should be seen as the data representation between two layers, if the DTO crosses more than one layer, it probably isn't a DTO but a business or data entity.
) Fetch images from body
this looks like something you designed to be able to receive the desired data, but is not something your domain model cares about.
For example if your form allow you to save "Sale advert", which is made of few images and some text, probably this aggregation of data in your business layer (service), is represented by one or more domain objects, so the fact that you receive a body in whichever format, depends more on technology or transport, and should be transparent to your business layer.
A good example to help you find boundaries, is thinking about re-usability. How would you reuse your service layer if you were to use it from a WCF service for example?
Your service should always receive and expose Domain Objects.
Leave to the consumer component the responsibility to decode/encode.
3) Check Summary and body text rules (and all other checks)
seems to be a validation, but I cannot tell if this validation is only related to the domain.
Some validation is also done in the controller itself to check if the request is valid or not.
So if this check is done on the DTO structure, before you try to convert it, probably that is a controller validation, if instead, this validation is necessary to decide weather or not the input can be saved, well probably in this case it would be considered other's responsibility.
You mentioned:
for example summary text length
if this is a business rule, then I would place it in a validation object, responsible to validate the "summary text" or let's call it again "Sale advert".
The responsibility to save a domain object to a data store, is normally delegated to a Data Access Layer, which is coupled to the database structure and provides the abstraction to the business layer.
This can be done implementing a repository pattern or maybe using an ORM, I normally don't add logic to persist data in the business layer.
Another note, here you are asking about controller responsibility, but pay attention to your service "layer", I have seen often code where a huge service class, was encapsulating all the business logic and validation, that is very bad because again goes against most of the solid principles.
Look at the command query and decorator pattern, I love them because the really help you breaking down your code in smaller pieces with single responsibility.
If interest look at this example project on github (.net core).
I am still working on the documentation but should be clear enough.

Sails.js: CRUD functions belong to services or controller?

I'm new to Sails.js (coming from a PHP background), and I believe it is widely accepted that it's good practice to keep your controllers thin and lean, while services are meant to "do the heavy lifting".
If one should want to perform CRUD functions (not like the blueprint shortcuts thing), and is not interacting with views of any sort, should these CRUD functions belong in api/services or api/controllers?
Because the structure of a model is inherently linked to the controller, whereas the service should be somewhat standalone and should not reference models by name/structure. Is that correct?
Is it right for a service to be creating objects for multiple models, if it is a secondary effect of a user request? Or should the service return the values to be created back to the controller, and let a single controller create objects for two different models?
Pardon me for my lack of knowledge - coming from PHP, this is a whole new world to me.
Use controller to do a specific things about your model. So your CRUD would be fit in controllers if it has specific function within Model(s).
Use service to do a less specific things, e.g. sending email. Assume that you want to send an email when some model is modified, so the logic that handle sending email should be in service, i.e. you can call it by someService.sendEmail(params) inside some model afterCreate and afterUpdate.
But after all it just a convention, you would learn it as long as you use Sails more. And deeper you get into Sails, you will have your development pattern and environment (not just controller vs. service) that fit to your preference, like using hooks, generator, installable hooks, etc.

What is the "model" in the MVC pattern?

So I did some Google searching on the MVC pattern and I'm still not exactly sure what the "Model" part is. What exactly does it deal with? I'm rather new to programming so all the explanations I can find go right over my head. I'd really appreciate it if you could give me an explanation in simple terms.
Thanks
The simplest way I can describe it is to call it the "Data" part. If it has to deal with getting or saving data, it's in the model. If you have a web application, the model is usually where you interact with a database or a filesystem.
Model in MVC is a place where data presented by the UI is located. Therefore, it shouldn't be confused with Domain Model which serves as a skeleton that holds the business logic.
Certainly, for a small application that serves as a service for CRUD operations backed by a database these two models can be the same. In a real world application they should be cleanly separated.
Controller is the one who talks to the application services and the Domain Model. It receives updates back from application services updating the Model which is then rendered by the View.
View renders the state hold by the Model, interprets User's input and it redirects it to the Controller. Controller then decides if the Model is going to be updated immediately or first the information is forwarded to application services.
The Model can represent your "Domain Model" in smaller projects. The Domain Model consists of classes which represent the real-world entities of the problem you're dealing with.
In larger projects, the Domain Model should be separated out of the actual MVC application, and given it's own project/assembly. In these larger projects, reserve the "Model" (i.e. the "Models folder in the MVC project") for UI presentation objects (DTOs - Data Transfer Objects)
The model is respomnsible for managing the data in the application. This might include stuff like database queries and file IO.
the view is obviously the template, with controller being the business logic.
The model is used to represent the data you are working with. The controller controls the data flow and actions that can be taken with the data. The view(s) visualize the data and the actions that can be requested of the controller.
Simple example:
A car is a model, it has properties that represent a car (wheels, engine, etc).
The controller defines the actions that can be taken on the car: view, edit, create, or even actions like buy and sell.
The controller passes the data to a view which both displays the data and sometimes lets the user take action on that data. However, the requested action is actually handled by the controller.

What exactly is the model in MVC

I'm slightly confused about what exactly the Model is limited to. I understand that it works with data from a database and such. Can it be used for anything else though? Take for example an authentication system that sends out an activation email to a user when they register. Where would be the most suitable place to put the code for the email? Would a model be appropriate... or is it better put in a view, controller, etc?
Think of it like this. You're designing your application, and you know according to the roadmap that version 1 will have nothing but a text based command line interface. version 2 will have a web based interface, and version 3 will use some kind of gui api, such as the windows api, or cocoa, or some kind of cross platform toolkit. It doesn't matter.
The program will probably have to go across to different platforms too, so they will have different email subsystems they will need to work with.
The model is the portion of the program that does not change across these different versions. It forms the logical core that does the actual work of whatever special thing that the program does.
You can think of the controller as a message translator. it has interfaces on two sides, one faces towards the model, and one faces towards the view. When you make your different versions, the main activity will be rewriting the view, and altering one side of the controller to interface with the view.
You can put other platform/version specific things into the controller as well.
In essense, the job of the controller is to help you decouple the domain logic that's in the model, from whatever platform specific junk you dump into the view, or in other modules.
So to figure out whether something goes in the model or not, ask yourself the question "If I had to rewrite this application to work on platform X, would I have to rewrite that part?" If the answer is yes, keep it out of the model. If the answer is no, it may go into the model, if it's part of the essential logic of the program.
This answer might not be orthodox, but it's the only way I've ever found to think of the MVC paradigm that doesn't make my brain melt out of my ear from the meaningless theoretical mumbo jumbo that discussions about MVC are so full of.
Great question. I've asked this same question many times in my early MVC days. It's a difficult question to answer succintly, but I'll do my best.
The model does generally represent the "data" of your application. This does not limit you to a database however. Your data could be an XML file, a web resource, or many other things. The model is what encapsulates and provides access to this data. In an OOP language, this is typically represented as an object, or a collection of objects.
I'll use the following simple example throughout this answer, I will refer to this type of object as an Entity:
<?php
class Person
{
protected $_id;
protected $_firstName;
protected $_lastName;
protected $_phoneNumber;
}
In the simplest of applications, say a phone book application, this Entity would represent a Person in the phone book. Your View/Controller (VC) code would use this Entity, and collections of these Entities to represent entries in your phone book. You may be wondering, "OK. So, how do I go about creating/populating these Entities?". A common MVC newbie mistake is to simply start writing data access logic directly in their controller methods to create, read, update, and delete (CRUD) these. This is rarely a good idea. The CRUD responsibilities for these Entities should reside in your Model. I must stress though: the Model is not just a representation of your data. All of the CRUD duties are part of your Model layer.
Data Access Logic
Two of the simpler patterns used to handle the CRUD are Table Data Gateway and Row Data Gateway. One common practice, which is generally "not a good idea", is to simply have your Entity objects extend your TDG or RDG directly. In simple cases, this works fine, but it bloats your Entities with unnecessary code that has nothing to do with the business logic of your application.
Another pattern, Active Record, puts all of this data access logic in the Entity by design. This is very convenient, and can help immensely with rapid development. This pattern is used extensively in Ruby on Rails.
My personal pattern of choice, and the most complex, is the Data Mapper. This provides a strict separation of data access logic and Entities. This makes for lean business-logic exclusive Entities. It's common for a Data Mapper implementation to use a TDG,RDG, or even Active Record pattern to provide the data access logic for the mapper object. It's a very good idea to implement an Identity Map to be used by your Data Mapper, to reduce the number of queries you are doing to your storage medium.
Domain Model
The Domain Model is an object model of your domain that incorporates behavior and data. In our simple phone book application this would be a very boring single Person class. We might need to add more objects to our domain though, such as Employer or Address Entities. These would become part of the Domain Model.
The Domain Model is perfect for pairing with the Data Mapper pattern. Your Controllers would simply use the Mapper(s) to CRUD the Entities needed by the View. This keeps your Controllers, Views, and Entities completely agnostic to the storage medium. This also allows for differing Mappers for the same Entity. For example, you could have a Person_Db_Mapper object and a Person_Xml_Mapper object; the Person_Db_Mapper would use your local DB as a data source to build Entities, and Person_Xml_Mapper could use an XML file that someone uploaded, or that you fetched with a remote SOAP/XML-RPC call.
Service Layer
The Service Layer pattern defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation. I think of it as an API to my Domain Model.
When using the Service Layer pattern, you're encapsulating the data access pattern (Active Record, TDG, RDG, Data Mapper) and the Domain Model into a convenient single access point. This Service Layer is used directly by your Controllers, and if well-implemented provides a convenient place to hook in other API interfaces such as XML-RPC/SOAP.
The Service Layer is also the appropriate place to put application logic. If you're wondering what the difference between application and business logic is, I will explain.
Business logic is your domain logic, the logic and behaviors required by your Domain Model to appropriately represent the domain. Here are some business logic examples:
Every Person must have an Address
No Person can have a phone number longer than 10 digits
When deleting a Person their Address should be deleted
Application logic is the logic that doesn't fit inside your Domain. It's typically things your application requires that don't make sense to put in the business logic. Some examples:
When a Person is deleted email the system administrator
Only show a maximum of 5 Persons per page
It doesn't make sense to add the logic to send email to our Domain Model. We'd end up coupling our Domain Model to whatever mailing class we're using. Nor would we want to limit our Data Mapper to fetch only 5 records at a time. Having this logic in the Service Layer allows our potentially different APIs to have their own logic. e.g. Web may only fetch 5, but XML-RPC may fetch 100.
In closing, a Service ayer is not always needed, and can be overkill for simple cases. Application logic would typically be put directly in your Controller or, less desirably, In your Domain Model (ew).
Resources
Every serious developer should have these books in his library:
Design Patterns: Elements of Reusable Object-Oriented Software
Patterns of Enterprise Application Architecture
Domain-Driven Design: Tackling Complexity in the Heart of Software
The model is how you represent the data of the application. It is the state of the application, the data which would influence the output (edit: visual presentation) of the application, and variables that can be tweaked by the controller.
To answer your question specifically
The content of the email, the person to send the email to are the model.
The code that sends the email (and verify the email/registration in the first place) and determine the content of the email is in the controller. The controller could also generate the content of the email - perhaps you have an email template in the model, and the controller could replace placeholder with the correct values from its processing.
The view is basically "An authentication email has been sent to your account" or "Your email address is not valid". So the controller looks at the model and determine the output for the view.
Think of it like this
The model is the domain-specific representation of the data on which the application operates.
The Controller processes and responds to events (typically user actions) and may invoke changes on the model.
So, I would say you want to put the code for the e-mail in the controller.
MVC is typically meant for UI design. I think, in your case a simple Observer pattern would be ideal. Your model could notify a listener registerd with it that a user has been registered. This listener would then send out the email.
The model is the representation of your data-storage backend. This can be a database, a file-system, webservices, ...
Typically the model performs translation of the relational structures of your database to the object-oriented structure of your application.
In the example above: You would have a controller with a register action. The model holds the information the user enters during the registration process and takes care that the data is correctly saved in the data backend.
The activation email should be send as a result of a successful save operation by the controller.
Pseudo Code:
public class RegisterModel {
private String username;
private String email;
// ...
}
public class RegisterAction extends ApplicationController {
public void register(UserData data) {
// fill the model
RegisterModel model = new RegisterModel();
model.setUsername(data.getUsername());
// fill properties ...
// save the model - a DAO approach would be better
boolean result = model.save();
if(result)
sendActivationEmail(data);
}
}
More info to the MVC concept can be found here:
It should be noted that MVC is not a design pattern that fits well for every kind of application. In your case, sending the email is an operation that simply has no perfect place in the MVC pattern. If you are using a framework that forces you to use MVC, put it into the controller, as other people have said.

Resources