I am building a Sales system for my dissertation and I keep debating with myself in my design, which class should be doing the work?
So from these 3 classes;
Facility Class - This class is a central class to coordinator between the others and the GUI
Product Class - Represents details of the product
Sales Class - Represents the sale of multiple items
When it comes to selling the products, my big question is:
"Which class should calculate the total price". The facility class or the Sales class?
Whats best practice?
Thanks in advance
if taking MVC into account, the Model is Product and Sales, the Controller is Facility and View is not mentioned.
If this should be a properly designed solution, you will add a service layer, that will do the actual work.
So the Model keeps the data, the view shows the data, the controller orchestrates the data between Model and View and a service layer that will do business logic on the data (booking).
There is also a variation of this, where the view has a specific view model class, that will do the preparation of data and collection of data specificially for the view. but for your case, this is not of importance.
My first impulse is to order these classes by their responsibility regarding Model-View-Controller design (because you mention a GUI and an interfacing class to it).
Facility - according to your statement it is a controller, it connects the GUI (view) to your data (models).
Product - this is a model class, since it holds data and business logic.
Sale - this class is connected to multiple Products and multiple Products share the same Sale, because a product can be sold more than once (this is an assumption) and a sale can include multiple products. It is also a model class.
Since the Sale class represents multiple products and you are interested in (e.g.) the sum of the individual prices of these products, this would be the place to store that method.
I think that, as a general rule, the Facility, or manager class should always act simply as a buffer between the user and the other classes, which leads me to say you should put the total price calculation in the sales class.
The sales class is the one that, in the first place, was designed to handle the sale of multiple items, meaning there should be a method that returns the price of all of the currently carted items combined, and then pass it to the interface class to be displayed.
Related
I am developing a Spring application that use Spring Data JPA to access to the data layer.
So basically I have n entity classes and n related repository classes to access to the data of the database table associated to the entity classes, something like this:
#Repository
#Transactional(propagation = Propagation.MANDATORY)
public interface EntityType1DAO extends JpaRepository<EntityType1, Long> {
//#Query("FROM Room WHERE accomodation = :id")
List<EntityType1> findByEntityType1(EntityType1 entityType1);
}
#Repository
#Transactional(propagation = Propagation.MANDATORY)
public interface EntityType2DAO extends JpaRepository<EntityType2, Long> {
List<EntityType2> findByEntityType2(EntityType2 entityType2);
}
...........................................................................
...........................................................................
...........................................................................
#Repository
#Transactional(propagation = Propagation.MANDATORY)
public interface EntityTypeNDAO extends JpaRepository<EntityTypeN, Long> {
List<EntityTypeN> findByEntityTypeN(EntityTypeN entityTypeN);
}
So basically in this way I have n domain classes accessed by **n repository classes.
I can divide these n domain classes into subsets belonging to a common concept.
For example I can have entity classes like: Room, RoomTipology RoomRate and RoomPicture that all belong to the Room concept.
So I will have the following services classes: RoomDAO, RoomTipologyDAO, RoomRateDAO and RoomPictureDAO.
It works fine but I want adopt a more DOMAIN-DRIVEN DESIGN architecture.
So I have found this interesting article about how to obtain a DOMAIN-DRIVEN DESIGN in Spring application: http://static.olivergierke.de/lectures/ddd-and-spring/
Reading the previous article it says that:
Repository - Spring component, usually a Spring Data repository
interface. Can depend on entities and value objects, are centered
around entities that are aggregate roots.
What exactly means? It means that I can create an aggregate roots class (for example RoomAggregation that aggregate together my Room, RoomTipology RoomRate and RoomPicture entity classes) using the #Embedded annotation.
Or what?
What could be a good architectural solution to obtain a DOMAIN-DRIVEN DESIGN in my application using Spring Data JPA?
You don't create a new class as the Aggregate. Instead you pick one of the exiting ones. Typically it presents itself, and in your example it might be the Room
So you would have a repository for rooms (RoomRepository or Rooms maybe). You use it to save and load rooms, including finding rooms by the various criteria you need.
In order to access (and manipulate) for example a RoomPicture you load the Room navigate to the RoomPicture manipulate it and save your JPA session, which essentially means you are modifying the Room.
If you choose simple navigation between entities (#OneToMany and the gang) or #Embedded ist not affected by your choice of Aggregates, except, that you don't have direct references from on Aggregate to another. So if you also have Booking as an AggregateRoot, that Booking would contai a roomId and you'd use the Room repository to look the Room up.
First of all, forget about Spring Data JPA or any other persistence mechanism. Domain Driven Design is about modelling the domain in analysis and your particular case is about modeling some kind of hotels sub-domain and do not worry about persistence at all. That is another completely different concern not related to hotels but to persistence (another domain or bounded context).
You must think in terms of use cases instead of concepts so we can identify behavior and this way detect invariants that allow us to think about establishing boundaries around what must remain consistent all the time.
Remember to model small aggregates as suggested by Vaughn so your idea of having a big aggregate does not sound good. The hotel manager might instantiate a Room to actually represent a Room and give it a number and some other stuff. Now what about the price and the pictures? Let's take the example of the price and let me ask you, does a Room actually know what its price is? Isn't the room price dynamic and totally affected by a lot of other variables such as dates? Then why to fix a rate inside the Room aggregate? We said a room is not responsable in the real world for such responsibility and the price is affected by several conditions that occur outside the boundary of a Room. So the Rate is totally accidental to a Room, not essential if we talk in philosophy terminology.
The other Aggregate is PriceList and it's Aggregate Root having the same name. So you can ask the price list, the price for an Room (standard, deluxe, ...) in a specific date and it will know the price :)
Depending on how you model all these stuff this might belong to the Pricing Bounded Context exposed as a Microservice, but don't worry
about it. The PriceList is another aggregate completely isolated from the Room and refering the rooms by its conceptual identity that is the Room Number.
The same applies for RoomPicture. In this particular case think that the department/area/employees dealing with the album picture might not be the Manager but someone else with a different role and creating a room album with its own lifecycle.
As conclusiong you would end up having these aggregates:
Room
PriceList
Album
And remember the all these have disconnected associations referring room numbers (not Rooms) and each having its own boundaries around invariants.
In a huge app you might have each of these living in its own bounded context.
Remember Room does not enforce any invariant neither over its album of picture nor its price list.
Hope it helps,
Sebastian.
As #Sebastian has elaborated it very well, when you are DDDing your application, persistance should be the last thing to worry about ever.
You do not couple your entities with the database or else you will end up with a very database driven application messed up with ddd and it will not be presentable in terms of clean code and aesthetic sense.
There is a good presentation on youtube named Domain Driven Design for Database Driven Mind please check it out.
Secondly most of your DAOs should be refactored to Value Objects and you dump al your business logic into Value Objects and Entities and in the end when you need to worry about storing the stuff, just go with a data mapper layer.
Speaking out of experience, value objects done right will offload your 90% weight of the proper app design.
I am trying to implement MVC for my Java desktop application and I am not very familiar with it. For the purpose of the question, I am considering a use case in which you click "refresh" button, it queries DB for list of students and update students lists. Here are my questions that have been confusing me:
1-For querying the DB, does it happen in the controller or in the model? My gut feeling says its controller who queries and once results are received, it updates the model. However I read in many posts that the Model is the one who knows its state transitions and does its updates!
2- Who creates the the view and model? Does the controller create them or are they created externally and passed to the controller?
3-In the above use case, does the model consists of an ArrayList of Students or is the model just a Student object but the Controller has and ArrayList of models?
Please help a fellow developer
For querying the DB, does it happen in the controller or in the model?
Short answer, querying the database happens in the model.
A List of Student is the model for the GUI, where Student is a Java object containing the student information. The list of students is also the model for the database.
There are different ways you can approach the interaction between the list of students and the database. One way is to read all of the student information at the beginning of your GUI initialization. As your users interact with the GUI, your GUI controller inserts, updates, and marks students for deletion in the GUI model. Finally, when the user closes the GUI, you write all of the changes in the list of students to the database. This way, while simple, exposes you to data corruption if your GUI abends. Also, only one person can make changes to the database at a time.
A better way is to read all of the student information at the beginning of your GUI initialization, as before. As your users interact with the GUI, the GUI controller updates the list of students in the GUI model. After each insert, update, or delete, you call the appropriate methods in the data access object to insert, update, or delete the student information, respectively.
Who creates the the view and model?
You do. :-)
The model / view / controller pattern is not just for organizing code. Generally, you create the first cut of the model first. Then you create the view, and add the fields to the model that you forgot when you created the first cut. Lastly, you create the controller. The controller(s) should do nothing but execute methods in the model to update the model and methods in the view to repaint / revalidate the view.
You pass an instance of the model and an instance of the view to your controller(s). You should only have one instance of the model and one instance of the view. However, they are not singletons.
In the above use case, does the model consists of an ArrayList of Students or is the model just a Student object but the Controller has and ArrayList of models?
Finally, an easy question. Neither.
Your model is a List of Student. The List interface will be implemented by the ArrayList class. Something like this.
List<Student> studentList = new ArrayList<>();
By using the interface, you can easily change the ArrayList to a LinkedList, or your own implementation of the List interface.
A general Java rule is to use the interface unless the methods you need are only defined in the concrete class.
I hope this was helpful.
In an example I got at school of the MVC pattern we had 3 classes Student, StudentView and StudentController. The controller has an instance of the model (Studentin this case) and an instance of the controller. The problem i have with this is that the controller only handles a single object.
You obviously can have more students so I have an ArrayList<Student> somewhere. where do I put it? and how do I handle the model and view then?
My initial thought was to put the list in StudentController but then I found out that the controller is no longer for a single instance of Student but for the list so do i need to make 2 seperate controllers? one for Student and one for the ArrayList<Student> called something like AllStudents?
Edit: The application is a simple grading system for students. Students follow Coursrs the and a Course can have a Grade. the View displays the data of the student, course or grade in the console. The data is hard coded in the programme (objects are made 'on-the-fly').
The Model is not necessarily just one class, it's a layer. Your Student Class as a Domain Object in your model layer now you need a Service and maybe some kind of a persistence/orm in your Model. A Service could be StudentService with methods like getAllStudents() returning a List. The StudentService may have an instance of a Connector to get the Data from a Database or a File.
That is a question leading to the much broader question of: what does the rest of the application do?
It is obviously totally fine to have a 1:1:1 relation between view, controller an model. wht you might be interested in is an event bus. When the model of interest changes, the controller gets notified and updated with a new Student reference.
Or the controller gets the whole list and the view sends an event to the controller indicating that a different instance from the collection should be displayed.
In many application you'll have a master and detail views. The master view displays a list of all students. When one student is selected to be displayed in the detail view, a notification/an event is dispatched. This is basically a publish/subscribe observer/subject model. The detail view controller will be notified and display the proper data accordingly.
we got: one abstract superclass containing one method, and two subclasses redefining this method according to their needs. Not sure how to sructure project following MVC modeling.
Like, what exactly class model should have inside, controller and view?
In the most simple possible implementation:
Your model class should do data access and no more; say for example that it should be the only one with an import java.sql.whatever, and return collections of beans fresh out from your repository.
Your controller class should call your model layer, extract information and take a decision about what to show the user and how to do it. For example: you can read a list of organization units and decide whether to send the user to a tree view of the units or, if there is only one unit, send them straight to an employee table with the people on that unit. Spring MVC controllers or Struts 1/2 action classes are nice examples of this. It should also leave the data available to the view in some accesible place (for example, as request attributes)
Your view should be a JSP (or whatever view technology you use) as simple and with as few decisions taken in it as possible; all data is retrieved and navigation decisions are taken beforehand for it, and its only mission is to paint.
I am having some troubles understanding and implementing the MVC pattern.
I have a singleton "model" class which contains all the datas of the application and extends Observable. When those data are modified, I want to update the views, and when one of the views receives some input from the user, I want to update the model. In between stands a Controller (implements Observer) which has an instance of both the view and the model.
I think that to do this, the views must have an instance of the controller. Whenever it receives an event from a button or any component, it calls the correct controller's method, which transmit the informations to the model. The model is updated and notifies the observer which in turn will update every components of all the views, even if they are not linked to the particular data which has been modified, since the Controller can't know what has been modified in the model. I am not sure this is a good design.
I looked a bit upon the PropertyChangeListener class, which seems to correct this issue but I am not so sure that I understand everything. Is there any preferred way to do this ?
Thanks in advance !
There are a few issues with what you're suggesting.
First of all, you're describing MVVM, not MVC.
The second problem is that the terms model and controller aren't suppose to describe singletons. They are merely terms to help you separate concerns by organizing your logic into classes with well-defined responsibilities.
The MVC structure is as follows:
The Model
This is your application logic/business rules. This basically means that if your application is about a phone book, then all logic and data structures that have to do with providing a phone book API is implemented here.
The View
This layer is completely separate from the model, in that it doesn't care about data structures or logic, but only on presenting simple values. Strings, integers, collections, you name it. But it doesn't care about the model's API, it only depends on the controller's.
The Controller
This is where things come together. The controller is the mediator. It speaks the language of the model, and that of the view, and it can make them work together. User requests are routed to the controller.
For example, a request might want to list all numbers in the phone book. What happens is:
The controller receives the request
Asks the model for all numbers that exist in the phone book via the model's API
[Optionally] converts the data into a data structure which the view is intended to display
Passes the data to the view
One last remark before we finish:
If the controller doesn't convert data from the model into something simple, then allegedly the view is now tightly-coupled with the model. However, that doesn't always have to be the case. Even if the model's API changes, then the controller might still be able to adapt the new API into the old API, which the view already understands.