Should Service Class be part of the class diagram? - java

Let's say,
we want to build some system like Ticket Booking (ticket booking is not the key thing here, it's just an example)
So we have a User class, Ticket class etc
We also have a TicketService class which provides methods for bookTicket() cancelTicket() etc etc
In the class diagram, TicketService should be included or not?
If not, where should the bookTicket() or cancelTicket() be shown on the class diagram,
in the Ticket class or the User class(since user creates the ticket)

This depends on what you want to represent. If you are wanting a faithful representation of your code in a Class Diagram then yes; if you are simply wanting to explain the logic of your business domain (i.e. the business entities in the domain) and you don't want the clutter then no you could drop the service class. This is subjective/opinion based and depends on what you need to do.
If you want to avoid the service class but you want to represent the logic of the domain with behaviour, then you could simply add a "book ()" and "cancel ()" operation to the Ticket class. This would be the standard approach in object orientation -- i.e. encapsulation of behaviour (and data) within the object that is responsible for it.

Related

Do I need another association in my UML diagram?

I have made this simple UML diagram.
I want to have a list of treatments inside class Customer.
My question is if I need another association to make this possible.
A class diagram describes classes and not objects. A TreatmentList is a TreatmentList, regardless if you look at it from the Menu or the Customer persepective.
So indeed, if you want a list of treatment "inside" the class Customer, you'll need just to add another association between the classes you want to connect.
Now I wonder if you did not try to design user interface using a class diagram:
Main -> Menu -> List 1 or List 2 looks terribly like a flow in the user interface, more than a set of related classes. You don't need this. And lass diagrams are not meant for this purpose. If you want to model an UI Menu, you'd model a menu class, i.e a general class that could instantiate any kind of menus, with a one-to-many association with MenuAction. Perhaps ShowTreamtmentList would be a specialization of such an action.
The TreatmentList and CustomerList only make sense if these are classes, i.e. they could be instantiated into one or several objects that each represent a different list. If, for an association, you'd have a multiplicity of * on the side of customer or treatment, you would not need to add a special list/set/bag in the middle.
You don't need to use an aggregate instead of an association. Aggregate are not very uselful and appear to be overused. Prefer a simple association.

Java MVC, what model to use for add screens?

I have a class called Member which I use as the model for one of my views. This view allows the user to view and edit details of a particular Member. My question is what model should I use for a different view that allows the user to add new members? Should I use the existing Member class and adapt it for this use, or should I create a new model class dedicated to adding new Members, and if so what should it be called?
If I understand you right, you have a class Member which does, contrary to what one might expect reading the class name, not represent a single Member but rather a MemberModel. This could be a mere naming issue.
Suppose your class Member has the capability to add, edit and grant access to particular members (directly or indirectly), it would make sense to adapt your existing model class so that it supports adding new members- for example by adding a method addMember() which can be called by the corresponding views.
It is fine to manage the functionality of accessing, editing and adding members via a single model. The model provides methods to your views which enables them to access, edit and add members and makes it possible for views to listen to changes of the model they are interested in (e.g. via listeners).
Depending on factors like the complexity of your project it could in principle make sense to divide your model into submodels, so that your model will be a composition of submodels (represented by individual classes). However, the role of serving as an interface to the functionality of accessing and editing members and the functionality of adding members should be fulfilled by the same class in my opinion.
What i can understand is that you have a class Member which is a model. If you want to use a model to add a member, exposing it in top layers like controller is not appreciated. What you can do is to have a Criteria class or DTO. These classes could carry all the data that is required from the top level to DAO layer.
If this is not what you are expecting, can you elaborate more on your query.
On MVC you normaly use the same model for all the actions that depends on that model. So if you have a member model, it'll be used to create, read, update and delete The famous four operations that are called CRUD.
So yes, the best option is to use the same class, once it will do the conection with the DAO layer of your project. You can fill a member object with information and send it foward to the DAO class that will register it on your dataBase, and then the DataBase can return it empty again for the next use, or don't even return it at all since you probably won't be needing it anymore. It's simple and easy to use.
Some tip about how to best manage the Adding, Editing and Deleting.
Your best option is:
Create a screen that show the user all members and one "New", "Edit" and "Delete" button, on which the New creates a new Member, the Edit edits the selected member, and the delete deletes the selected member.
For this you can create three views (not recommended) or just one, since member will always have the same fields (right? something like "name", "id"...). But one that requires operation as parameter. So you can do something like this:
try {
View frame = new frame("add");
frame.setVisible(true);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
}
catch (Exception e) {
e.printStackTrace();
}
And change "add" to "edit" or "delete" as requisitation. And on the frame called, you can just configure it to as the operation requires.

Hibernate modeling and fetching strategies: what to do with sparse little pieces of information

Environment:
Java
Spring
MVC pattern
Hibernate
Description:
Ok, let's say I have a web application with two domain objects:
User
Report
a User can have a lot of Reports (one to many relation). Please consider that a Report is a very complex object, with a lot of attributes.
User class:
public class User {
private Set<Report> reports = new HashSet<Report>();
}
Report class:
public class Report {
//...so maaaaaaany attributes
private String name;
}
Let's say I need to show an html page displaying a User profile with the list of associated Reports. Only reports' names appear in the list. Please comment these considerations:
I don't think to eagerly load the Reports because of memory saving issues, so I'll go lazy.
Even if I go lazy, the point is that I actually need the reports'name only. I don't want to load tons of information just to cherry-pick the report name!
So a possible solution is to modify the User class as follows:
public class User {
private Set<Report> reports = new HashSet<Report>();
private List<String> reportNames;
}
taking the needed information from the report to the user. In my opinion, it brings two consequences:
the list of report names must be kept updated
i break the separation between objects domain, filling the User with information I can't easily retrieve. This approach might even be effective, but it is very ugly.
So is there a nice solution to cope with this problem? I think it is common issue for developers.
One way would be to use the following pattern:
Create a view object which represents exactly what you want to be displayed, let's call it UserViewObject. I would not modify the domain objects just to adapt them for the view, that would break the MVC design.
Implements a service method in a service class which returns a list of UserViewObject.
Let the service method call a DAO method in a DAO class that actually does the job.
The DAO method could make sure to only read the required data, or you could do that transformation in the service layer. It is really a bit of what you prefer, and how it fits in. But do not make the DAO layer aware of your UserViewObject.

Which functions or what things to write in service layer Java Spring MVC

Suppose i have class USER with attributes.
In some examples i see UserService class defined for some functions.
I am confused which things or functions should written in User Class and which things in UserService.
For e,g If i want to write some function To Validate users in database like
validate(user,pass)
Where should write those function
Also if i have class ShoppingProducts
and i want to get all prodcuts shopped by particular user in which class should i write that function i mean in product class or UserService or ProductService
This is a typical example of domain model vs anemic model.
There's a lot of theory in this discussion, but a practical advice from me is to:
put all methods that can operate on the User properties only in the User class.
put all methods that require database access, accessing web services, or other layers, in the service.
See this related article of mine.
I won't go into the battle of domain vs anemic or SOA data separate from behavior.
I will say that I think of service's as behavior that spreads across multiple domains (multiple domain objects) and deals with data transfer objects (ie don't put the DTOs in your domain objects).
With REST being so popular these days and the fact the Resources (REST since) are not Models you always seem to need DTOs and Service classes.
On other hand with AspectJ, Annotations and some other magic you can really push the edge of Domain Driven design but I still think you should not reference other domain objects in a domain object.

How can I resolve the conflict between loose coupling/dependency injection and a rich domain model?

Edit: This is not a conflict on the theoretical level but a conflict on an implementation level.
Another Edit:
The problem is not having domain models as data-only/DTOs versus richer, more complex object map where Order has OrderItems and some calculateTotal logic. The specific problem is when, for example, that Order needs to grab the latest wholesale prices of the OrderItem from some web service in China (for example). So you have some Spring Service running that allows calls to this PriceQuery service in China. Order has calculateTotal which iterates over every OrderItem, gets the latest price, and adds it to the total.
So how would you ensure that every Order has a reference to this PriceQuery service? How would you restore it upon de-serializations, loading from DBs, and fresh instantiations? This is my exact question.
The easy way would be to pass a reference to the calculateTotal method, but what if your Object uses this service internally throughout its lifetime? What if it's used in 10 methods? It gets messy to pass references around every time.
Another way would be to move calculateTotal out of the Order and into the OrderService, but that breaks OO design and we move towards the old "Transaction Script" way of things.
Original post:
Short version:
Rich domain objects require references to many components, but these objects get persisted or serialized, so any references they hold to outside components (Spring beans in this case: services, repositories, anything) are transient and get wiped out. They need to be re-injected when the object is de-serialized or loaded from the DB, but this is extremely ugly and I can't see an elegant way to do it.
Longer version:
For a while now I've practiced loose coupling and DI with the help of Spring. It's helped me a lot in keeping things manageable and testable. A while ago, however, I read Domain-Driven Design and some Martin Fowler. As a result, I've been trying to convert my domain models from simple DTOs (usually simple representations of a table row, just data no logic) into a more rich domain model.
As my domain grows and takes on new responsibilities, my domain objects are starting to require some of the beans (services, repositories, components) that I have in my Spring context. This has quickly become a nightmare and one of the most difficult parts of converting to a rich domain design.
Basically there are points where I am manually injecting a reference to the application context into my domain:
when object is loaded from Repository or other responsible Entity since the component references are transient and obviously don't get persisted
when object is created from Factory since a newly created object lacks the component references
when object is de-serialized in a Quartz job or some other place since the transient component references get wiped
First, it's ugly because I'm passing the object an application context reference and expecting it to pull out by name references to the components it needs. This isn't injection, it's direct pulling.
Second, it's ugly code because in all of those mentioned places I need logic for injecting an appContext
Third, it's error prone because I have to remember to inject in all those places for all those objects, which is harder than it sounds.
There has got to be a better way and I'm hoping you can shed some light on it.
I would venture to say that there are many shades of gray between having an "anemic domain model" and cramming all of your services into your domain objects. And quite often, at least in business domains and in my experience, an object might actually be nothing more than just the data; for example, whenever the operations that can be performed on that particular object depend on multitude of other objects and some localized context, say an address for example.
In my review of the domain-driven literature on the net, I have found a lot of vague ideas and writings, but I was not unable to find a proper, non-trivial example of where the boundaries between methods and operations should lie, and, what's more, how to implement that with current technology stack. So for the purpose of this answer, I will make up a small example to illustrate my points:
Consider the age-old example of Orders and OrderItems. An "anemic" domain model would look something like:
class Order {
Long orderId;
Date orderDate;
Long receivedById; // user which received the order
}
class OrderItem {
Long orderId; // order to which this item belongs
Long productId; // product id
BigDecimal amount;
BigDecimal price;
}
In my opinion, the point of the domain-driven design is to use classes to better model the relationships between entities. So, an non-anemic model would look something like:
class Order {
Long orderId;
Date orderDate;
User receivedBy;
Set<OrderItem> items;
}
class OrderItem {
Order order;
Product product;
BigDecimal amount;
BigDecimal price;
}
Supposedly, you would be using an ORM solution to do the mapping here. In this model, you would be able to write a method such as Order.calculateTotal(), that would sum up all the amount*price for each order item.
So, the model would be rich, in a sense that operations that make sense from a business perspective, like calculateTotal, would be placed in an Order domain object. But, at least in my view, domain-driven design does not mean that the Order should know about your persistence services. That should be done in a separate and independent layer. Persistence operations are not part of the business domain, they are the part of the implementation.
And even in this simple example, there are many pitfalls to consider. Should the entire Product be loaded with each OrderItem? If there is a huge number of order items, and you need a summary report for a huge number of orders, would you be using Java, loading objects in memory and invoking calculateTotal() on each order? Or is an SQL query a much better solution, from every aspect. That is why a decent ORM solution like Hibernate, offers mechanisms for solving precisely these kind of practical problems: lazy-loading with proxies for the former and HQL for the latter. What good would be a theoretically sound model be, if report generation takes ages?
Of course, the entire issue is quite complex, much more that I'm able to write or consider in one sitting. And I'm not speaking from a position of authority, but simple, everyday practice in deploying business apps. Hopefully, you'll get something out of this answer. Feel free to provide some additional details and examples of what you're dealing with...
Edit: Regarding the PriceQuery service, and the example of sending an email after the total has been calculated, I would make a distinction between:
the fact that an email should be sent after price calculation
what part of an order should be sent? (this could also include, say, email templates)
the actual method of sending an email
Furthermore, one has to wonder, is sending of an email an inherent ability of an Order, or yet another thing that can be done with it, like persisting it, serialization to different formats (XML, CSV, Excel) etc.
What I would do, and what I consider a good OOP approach is the following. Define an interface encapsulating operations of preparing and sending an email:
interface EmailSender {
public void setSubject(String subject);
public void addRecipient(String address, RecipientType type);
public void setMessageBody(String body);
public void send();
}
Now, inside Order class, define an operation by which an order "knows" how to send itself as an email, using an email sender:
class Order {
...
public void sendTotalEmail(EmailSender sender) {
sender.setSubject("Order " + this.orderId);
sender.addRecipient(receivedBy.getEmailAddress(), RecipientType.TO);
sender.addRecipient(receivedBy.getSupervisor().getEmailAddress(), RecipientType.BCC);
sender.setMessageBody("Order total is: " + calculateTotal());
sender.send();
}
Finally, you should have a facade towards your application operations, a point where the actual response to user action happens. In my opinion, this is where you should obtain (by Spring DI) the actual implementations of services. This can, for example, be the Spring MVC Controller class:
public class OrderEmailController extends BaseFormController {
// injected by Spring
private OrderManager orderManager; // persistence
private EmailSender emailSender; // actual sending of email
public ModelAndView processFormSubmission(HttpServletRequest request,
HttpServletResponse response, ...) {
String id = request.getParameter("id");
Order order = orderManager.getOrder(id);
order.sendTotalEmail(emailSender);
return new ModelAndView(...);
}
Here's what you get with this approach:
domain objects don't contain services, they use them
domain objects are decoupled from actual service implementation (e.g. SMTP, sending in separate thread etc.), by the nature of the interface mechanism
services interfaces are generic, reusable, but don't know about any actual domain objects. For example, if order gets an extra field, you need change only the Order class.
you can mock services easily, and test domain objects easily
you can test actual services implementations easily
I don't know if this is by standards of certain gurus, but it a down-to-earth approach that works reasonably well in practice.
Regardinig
What if your Order needs to send out
an e-mail every time the total is
calculated?
I would employ events.
If it has some meaning for you when an order computes its total, let it raise an event as eventDispatcher.raiseEvent(new ComputedTotalEvent(this)).
Then you listen for this type of events, and callback your order as said before to let it format an email template, and you send it.
Your domain objects remains lean, with no knowledge about this your requirement.
In short, split your problem into 2 requirements:
- I want to know when an order computes its total;
- I want to send an email when an order has a (new and different) total;
I've found the answer, at least for those using Spring:
6.8.1. Using AspectJ to dependency inject domain objects with Spring
The simplest approach that I can think is to add some logic into your data access layer that will inject a domain object with its dependencies before returning it to a higher layer (usually called the service layer). You could annotate each class's properties to indicate what needs to get wired up. If you're not on Java 5+, you could implement an interface for each component that needs to be injected, or even declare this all in XML and feed that data to the context that will do the wiring. If you wanted to get fancy, you could pull this out into an aspect and apply it globally across your data access layer so all methods that pull out domain objects will wire up them up just after they are returned.
Perhaps what you want is a kind on reference object, that would serialize as a global reference (an URI for instance) and that would be able to resurrect as a proxy when de-serialized elsewhere.
The Identity Map pattern may help with your scenario. Check the article Patterns In Practice written by Jeremy Miller where he discuss about this pattern.

Categories