When we develop using MVC pattern it happens to need to having additional methods that could achieve basic operations on our models.
An example is an agregate getter that return the total count of the user records on the persistence base.
int getUsersCount();
Where is the best place to put such of those methods? In the model? In the controller?
Is there any difference between specific SDK/languages?
Java EE
Android
Laravel
vanilla PHP
...
Thanks.
I found this article that discuss about it: here it is a overview comparison between Purist OOP and Anemic Domain Model .
The overview basically explains that there are two big difference in the way you can implement a MVC design pattern.
The first way is about concetrate the methods, like the aggregate getter in this case, in a model related controller class.
For example, in Android, when we persist models in local or remote database, or we have to serialize it, or to marshall it, we tend to create those kind of ModelController classes and have so an anemic MVC pattern with clean POJO models.
class User extends MySuperModel{
int id;
String username;
//getters and setters
}
class UserController{
User getUserById(int id);
int getUsersCount();
}
The other way, consists in concentrate all the methods in the model class itself, for example as in Laravel (where controllers are demand to mainly control the post-routing and pre-rendering of a view, but doesn't tends to have other methods and neither their easy to instantiate. In this case we have a controlled domain MVC, and the additional model related methods should be in the model class itself.
class User extends Eloquent\Model{
protected $fillable = ['id', 'username']
function getUserById($id);
function getUsersCount();
}
Related
We have a front-end service that uses a back-end service to get a list of Metric objects. We've written a Java ClientSDK for the back-end service to make life easier for development of client applications of that service.
We also expose a list of Metrics from the front-end service. For now, we're directly exposing and converting the back-end Metric objects to JSON.
My concern is that if changes are made to the back-end Metric object - say a developer adds a new secret ID field - we don't want to expose it from the front-end service.
We're also writing a clientSDK for the front-end service. We don't want to reference the Metric class from the back-end clientSDK, so the logical option is to define a similar Metric object in the front-end SDK.
I don't want to waste CPU cycles copying 1000's of Metrics from one class definition to another.
Is there a way to specify which fields I should expose from the back-end Metric to the front-end definition of Metric as I'm converting to JSON? Better yet, can I reference the front-end definition to the JSON converter as I ask it to marshal the back-end object?
We're using Jackson with the Spring rest framework for context, but I'd be happy to drop that in a heartbeat since marshaling objects via annotations seems to be the root cause of this problem.
Take a look at Jackson's JsonView construct.
I can see your example looking something like this:
class Views {
static class Client {}
static class Backend extends Client {}
}
public class Metric {
#JsonView(Views.Client.class) String metricName;
#JsonView(Views.Client.class) String count;
#JsonView(Views.Backend.class) String secretKey;
}
The #JsonView annotation is supported on Spring #ResponseBody annotated methods as of Spring 4.1.
As Nicholas Hausschild has suggested you can achieve this by annotations with your marshalling/unmarshalling framework.
However you can simply use inheritance and casting like this:
class SomeSuperClass {
String exposeThis;
String exposeThat;
// getters and setters...
}
class SomeSubClass extends SomeSuperClass {
String doNotExposeThis;
// getters and setters...
}
This way you can cast to the super class when returning an object to the JSON parser, and at the same time use the subclass internally to carry additional information which you don't really want to expose.
Another possibility is the use of Mixins, so you can define different scenarios without touching the original DTO.
I myself use a library I wrote to achieve this dynamically:
https://github.com/Antibrumm/jackson-antpathfilter
This works well for not too deep graphs, else someone wrote another approach in a similar way here which seems more performant for these scenarios, but behaves a bit different.
https://github.com/krishna81m/jackson-nested-prop-filter
Please consider below example:
A web application creates a user object for every logged in user. This object has simple String properties for firstName, lastName ...
Each user can have a car too. Consider that fetching the user car is very expensive, so we prefer not to set the users car when user logs in. Instead we want to get car when a use case needs it.
To implement this we have created a User pojo as:
public class User() {
private String FirstName;
private String LastName;
private Car car;
//Here we have the service object, this could be injected with spring or JEE
private CarServices carServices;
public Car getCar() {
//If the car is not fetched yet, go on and get it from your service
if (car == null) {
car = carServices.getCarFromDB(...)
}
return car;
}
}
To initial user after a login:
User newUser = new User();
newUser.setFirstName("foo");
newUser.setLastName("bar");
//We just let user have service, so he can use this service latter
newUser.setCarServices( new CarServices() );
And every use case which needs the user car can get it easily:
newUser.getCar()
However, I have been argued that in this way my User object is not a simple pojo any more and this is not a good approach.
How can I achieve this requirement in better way.
I have been argued that in this way my User object is not a simple pojo
To anwer your question I would first like to go back a bit in history.
Pojo is a plain old java object and means that you only use "standard" java. The term was created at a time when J2EE had it's hype. At this time developers coded business logic in enterprise beans and this EJBs needed a lot of infrastructure code. This fact coupled buisness logic to an implementation technology. So Rebecca Parsons, Josh MacKenzie and Martin Fowler came to the conclusion that business logic would be more reuseable and easier to test if you just use standard java. Thus they created the term pojo, because developers like fancy names.
Your User class just depends on standard java and therefore it is a pojo.
Some developers argue that a pojo should not contain any logic. These developer prefer anemic models. Others say that a rich model is the better approach. I belong to the developers who prefer a rich model over an anemic model.
If you want to remove the CarServices dependency from the User class you can implement a Car lazy loading proxy just like hibernate or a jpa implementation does.
At least here are some of my thoughts to beans, pojos, anemic and rich domain models.
The difference between pojos and java beans
Anemic vs. Rich Domain Models
Hopefully it helps you when you discuss wih other developers.
Instead of a reference to a car, you could use a reference to a car supplier object whose implementation could cache the first result obtained (see Guava's Supplier and MemoizingSupplier classes). By doing so, you hide from the User object the fact that its car might or might not be present at instantiation time, and therefore make its implementation simpler (no more logic in the getter method).
Another advantage of this solution would be to break the coupling between the User and the CarServices classes (no need for the carServices property anymore). One could inject a supplier whose implementation would return a reference to an already available Car object, while another could pass an implementation that forwards the call to a CarServices service.
It wouldn't make the User class more of a POJO though (as explained in the first answer above), but people who have argued with your solution might like this one better because of it being simpler and less tightly coupled.
In a project I am currently working on, HAL support through the REST API is obtained by extending Springs org.springframework.hateoas.ResourceSupport, in order that links can be added to an object.
A quick example:
public class MyDataRepresentation extends ResourceSupport {
private String name;
}
Now in the web layer, I can add links in to the representation:
MyDataRepresentation myData = someService.getTheData();
myData.add(new Link(someUrl, someRel));
All well and good.
The problem is that I would rather re-use the domain object (MyData) directly, and not create a separate class in the web representation layer in order to accomplish this. The reason for this, is that my application in this particular case is simple enough that the domain object can be used directly, and I wish to avoid having mapping logic to translate to/from the web layer, either hand-coded or using a mapping tool. A further argument against mapping logic is that business logic often creeps into mapping logic, making the business logic even harder to follow.
So here is the domain class:
public class MyData {
private String name;
}
Unfortunately this does not give me anywhere to attach my HAL links to.
So my question is, is there a HAL framework for Java, that lets me directly re-use domain objects in the web layer without resorting to using 'extends' and forcing my down the route of web/domain mapping logic?
Some other way of using HAL support in Spring that lets me do this? What about HAL support in Jersey, is that less obtrusive?
Background:
I have a design pattern problem that I was hoping someone may be able to solve. I program in PHP but I believe DAO/VO is popular in Java.
I have been using MVC for many years now. I designed a shopping that was MVC but used procedural programming. Thus recently I decided to develop the cart again, using OO.
Problem:
The problem I was faced with was that my Product class did not make sense to have a RetrieveAll() method.
E.g. If I had 10 products listed, from which instance would I call the RetrieveAll() method? I would have 10 choices.
Solution:
Thus, I found the DAO/VO pattern.
Unless I have not researched this pattern enough - I believe that each DB table must have a Model + DAO. No model or DAO should know about another set of models or DAO's. Thus being encapsulated.
The pattern makes perfect sense, pulling the database layer away from the Model.
However. In the shopping cart, my products are assigned categories.
A category could be electronics, clothing, etc.
There are 3 tables:
- Category (pid, name)
- Category Item (iid, name)
- Category Link (pid, iid)
From an MVC approach, it doesn't make sense of which DAO the controller should be talking to?
Should it be:
The controller talks to all 3 DAO's and then return the appropriate data structure to the View?
Or should the DAO's talk to one-another (somehow) and return a single structure back to the Controller?
Please see here for example (image)
I'm not sure what do you mean by VO. Is it value object?
I'm a huge fan of the DDD (domain driven design) approach (though I don't consider my self as guru in it). In DDD you have so called Services. Service Is an action that operates on your domain and returns data. Service encapsulates the manipulation with you Domain data.
Instead of having the controller to do all the domain logic like what items to retrieve, what DAO's to use and etc (why controller should care about the Domain anyway?), it should be encapsulated inside the Domain it self, in DDD case inside a Service.
So for example you want to retrieve all the Category items of the category "electronics".
You could write a controller that looks like this (forgive me if the code have invalid syntax, its for the sake of example):
public function showItemsByCategoryAction($categoryName) {
$categoryId = $categoryDAO->findByName($categoryName);
if(is_null($categoryId)) {
//#TODO error
}
$itemIds = $categoryLinkDAO->getItemsByCategoryId($categoryId);
if(empty($itemIds)) {
//#TODO show error to the user
}
$items = $categoryItemDAO->findManyItems($itemIds);
//#TODO parse, assign to view etc
}
This introduces at least two problems:
The controller is FSUC (Fat stupid ugly controller)
The code is not reusable. If you would like to add another presentation layer (like API for developers, mobile version of the website or etc), you would have to copy-paste the same code (expect the part of the view rendering), and eventually you will come to something that will encapsulate this code, and this is what Services are for.
With the Services layer the same controller could look like
public function showItemsByCategoryAction($categoryName) {
$service = new Item_CategoryName_Finder_Service();
$items = $service->find($categoryName);
if(empty($items)){
//#TODO show empty page result, redirect or whatever
}
$this->getView()->bind('items', $items);
}
The controller is now clean, small, and all the Domain logic is encapsulated inside a service that can be reused anywhere in the code.
Now some people believe that the controller should know nothing about DAOs and communicate with the Domain only by using Services, other says that its ok to make calls to DAOs from the controller, there are no strict rules, decide what suits better for you.
I hope this helps you!
Good luck :)
I'm not an expert in DDD either , but this is my opinion. This is the situation where the repository patern is applied. Basically, the Domain doesn't know nor care about DAO or anything else rpesistence related. At most knows about the repository inteface (which should be implemented at the infrastructure level).
The controller knows about the domain and the repository. The repository encapsulates everything db related, the application knows only about the repository itself (in fact the interface as the actual implementation should be injected). Then within the repository you have DAOs however you see fit. The repository receives and sends back only application/domain objects, nothing related to db acess implementation.
In a nutshell, anything db related is part and it's an implementation detail of the repository.
return type can be considered when deciding which dao method should go to which dao class, hence which dao should the controller talk to:
Implement one DAO class per Data Entity is more cleaner,
CRUD operations should go in to Dao classes,
C-Create, R-Read, U-Update, D-Delete
Read operations are not like Create, Update, Delete, most of the time Read operations have different flavors when considering what they return.
for Read operations, return type can be considered when deciding which dao method should go to which dao class
following are some Business Entities and there Dao
Exchange -> ExchangeDao
Company -> CompanyDao
Stock -> StockDao
In my java program, I had a book class and a library class.
The library stores the book object in an array list and then I display it on the screen.
I can add the book and remove the books using functions.
I also use AbstractJtableModel for adding and removing the books.
But now I want to use a database, MySQL, instead of an array list.
How should I change my program?
well, you need to write the whole application :)
you need to create a db, with at least one table, you need to add mysql jdbc library to classpath and using jdbc you can insert/select/update/delete data from DB.
Alternatively, you need to add jdbc and use ORM framework like Hibernate, but depending on your Java knowledge this way can be harder (but easier to maintain in future, if you create big application). Here you can download simple hibernate application, which does CRUD operations with Honey :), you can extract interface similar to suggested by Javid Jamae from TestExample class, and exchange Honey class with Book according to your needs
You might consider using the Data Access Object (DAO) pattern. Just do a Google search and you'll find tons of articles on the topic. Essentially, you'll create a LibraryDao interface with methods like:
public interface LibraryDao {
public void storeLibrary(Library library)
public Library loadLibrary(long id)
public List<Library> searchByTitle(String title)
//...
}
You can implement this interface with straight SQL, or you can use an Object Relational Mapping (ORM) tool to implement it. I highly recommend reading up on Hibernate and the JPA specification.
Abstract the retrieval and storage of the books into a class by itself - you don't want that persistence logic intermingled with your business logic. I'd suggest creating an interface called something like "BookStorageDAO" and then you can have various implementations of that interface. One implementation may be to store the books in an ArrayList while another may be to store the books in a Database.
In this way, you can utilize the interface in your business logic and swap out the implementation at any time.
You would still use the ArrayList in your GUI to persist and display the data. The difference would be you need logic to save and load that ArrayList from a database so that the data is stored even after the program ends.
Side note, extends DefaultTableModel as opposed to AbstractJtabelModel. It completes some of the methods for you.
You don't need a DAO per se, but those answers aren't wrong.
Separation of Concern
What you need to do is separate your application based on concern, which is a pattern called separation of concern. It's a leak to have concerns overlap, so to combat this, you would separate your application into layers, or a stack, based on concern. A typical stack might be include:
Data Access Layer (read/write data)
Service Layer (isolated business logic)
Controller (Link between view and model)
Presentation (UI)
etc., but this will only partly solve your problem.
Program To The Interface
You also (as the others have mentioned) need to abstract your code, which will allow you to make use of dependency injection. This is extremely easy to implement. All you have to do is program to the interface:
public interface PersonService {
public List<Person> getAllPersons();
public Person getById(String uuid);
}
So your application would look like this:
public class PersonApp {
private final PersonService personService;
public PersonApp(PersonService personService) {
this.personService = personService;
}
}
Why is this better?
You have defined the contract for interacting with the Person model in the interface, and your application adheres to this contract without having any exposure to the implementation details. This means that you can implement the PersonService using Hibernate, then later decide you want to use JPA, or maybe you use straight JDBC, or Spring, etc. etc., and even though you have to refactor the implementation code, your application code stays the same. All you have to do is put the new implementation on the classpath and locate it (tip: the Service Locator pattern would work well for that).