I've started learning GWT about a week ago and here's the question I can't answer for sure.
Here's the server-side:
// business object - has logic
interface Article {
String getTitle(); // lazy
void setTitle();
String getText(); // lazy
void setText();
Set<Comment> getComments(); // lazy
}
// also has logic
interface Comment { ... }
I need to somehow create a GWT widget to visualize Article. Passing Article won't work, since it's not serializable and moreover, it has some BL. So, there are 2 ways:
The first one is to use DTOs like:
class ArticleDTO implements Serializable {
public int articleId;
public String title;
public String text;
}
class CommentDTO implements Serializable {
public int commentId;
public int articleId;
public String commentText;
}
The I'll have to implement a repository logic in my GWT RPC service:
class MyRPCRepository ... {
ArticleDTO getArticle(int id);
void saveArticle(ArticleDTO article);
void deleteArticle(ArticleDTO article);
...similar things for comments here...
}
The second way is to use DAOs:
class ArticleDAO implements Serializable {
private transitional MyRPC rpc;
private int articleId; // only this one is serializable
public ArticleDAO(MyRPC rpc, int articleId) { ... }
public String getTitle() {
// i know it would require more code in real
return rpc.getArticleTitle(articleId);
}
...
}
I like the first one, because it's really stupid. I like the second one because it's quite intellectual. Which one should I choose to make the code easier to understand and maintain?
In projects I've worked on, people seem to differ a lot in their opinions about the best approach to take with problems like this. There are pros and cons for both. The DTO approach is now supported by GWT in an API called RequestFactory, and is advertised as an alternative to "standard" GWT RPC usage (your DAO approach). You gain performance and integration with GWT's data binding framework, and the cost of maintaining the DTOs. I think it's a good trade-off, but for small projects it might be overkill.
Typically DAOs are objects that determine data access methods of your system, while DTOs define data that is used by DAOs. So your first method is quite good but it is actually DAO/DTO method with MyRPCRepository being actually DAO (Data Access Object).
Second method is totally weird to my taste. It is some kind of service that allows you to access some pieces of your data and yet it retains some state (usually you want DAOs to be stateless).
So I vote for the first method, but repository should probably be called ArticleDAO and similar DAOs would be there for other data objects.
The question to ask is "how do you intend to use any of the solutions?" Assuming you have a kind of table UI on the client side, where you always show articelId, title and text (knowing that you are describing a kind of "Online Forum" I can assume you don't show the text, but lets pretend I did not know that). Now, with a DTO you simply can transfer a bunsh (one page?) of objects to the client. That means the transfer is done in one chunk and there is only one request from the client to fullfill.
With your DAO approach (which I would not call DAO but "Service" in this case) you might still send a bunsh of objects in one request/response to the client, but a cascade of small requests to display title and text will come back from the client.
So the question to ask is: how does the user interact with your system? In your concrete example I always would transfer "id" and "title" and only use a second request/DAO approch for the text.
OTOH again, if only a few users are using the system (dozens or a few hundret) I would use the approach that is most easiest to develop or maintain.
Related
there. Please let me preface by saying that I have done quite a bit of research and reading around different design patterns within Java, but it is still unclear to me which is appropriate for what I am trying to achieve.
I am also completely open to learning so if the path I am on is poor engineering practice, please let me know and suggest a different path. I do not have any formal engineering background and am self-taught.
Here is what I am trying to achieve. Let's say we have a simple class that aggregates data throughout a request:
#NoArgsConstructor(access = PRIVATE)
public class MyHeaderDecorator {
private static final MyHeaderDecorator INSTANCE = new MyHeaderDecorator();
public MyHeaderDecorator getInstance() {
return INSTANCE;
}
#Getter
private final Map<String, String> customHeadersMap = new HashMap<>();
public MyHeaderDecorator withHeader(final String headerKey, final String headerValue) {
customHeadersMap.put(headerKey, headerValue);
return this;
}
}
Anywhere in our codebase, one can simply use the above Singleton to add more custom header values:
MyHeaderDecorator.getInstance().withHeader("newHeaderKey", "newHeaderValue");
Then, this gets aggregated in our Play filter as such:
public class MyCustomHeaderFilter extends Filter {
#Inject
public MyCustomHeaderFilter(Materializer mat) {
super(mat);
}
#Override
public CompletionStage<Result> apply(
Function<RequestHeader, CompletionStage<Result>> nextFilter, RequestHeader requestHeader) {
return nextFilter.apply(requestHeader).thenApply(result -> {
val customHeaders = MyHeaderDecorator.getInstance().getCustomHeadersMap();
// business logic to transform and insert custom headers into result
return result;
});
}
}
While the above achieves mostly what I am looking to do, these are the reasons why I think I am on the wrong path with the Singleton approach.
Since Singleton aggregates all of the calls ever made on the specific JVM, there are eventually unwanted headers being sent down.
I need the lifecycle of the Singleton to be more request-based and not an actual Singleton. I don't think Singleton fits this pattern.
Researching into different patterns says the pattern I am looking to use is basically a Builder pattern since the information needed to create a full MyHeaderDecorator is in different places. But I don't see a way that I can specify that this is supposed to be PER REQUEST.
I looked into Dependency Injection, but I am quite confused over this topic because I feel, many times, it is interweaved with having a Factory, as well. I'm having a hard time finding learning materials that are simple enough to understand what, exactly, Dependency Injection is doing. I know that it's a mechanism to pass objects and their dependencies without the receiving class having to construct something on their own. But I'm still having a hard time really understanding it. (Which is terrible because I have worked on code bases for 5+ years with the #Inject annotation and just use it because it "works".)
My end goal is to achieve something similar to what I have prototyped above, but have MyHeaderDecorator be scoped to each specific request. Is this even possible? Is it poor practice?
Any help would be much appreciated. Thank you in advance.
Assuming I have a class User with many fields:
public class User {
public Integer id;
public String name;
public String username;
public Integer age;
public Address address;
public String phoneNumber;
public String email;
}
But I will not always need all User attributes in frontend. Each screen needs only some of User's fields. Is it a good practice to make DTO classes for each screen, since they access different attributes? Like this:
class UserToScreenADTO implements Serializable {
public String name;
public String email;
}
class UserToScreenBDTO implements Serializable {
public String phoneNumber;
public Address address;
}
class UserToScreenCDTO implements Serializable {
public Integer id;
public String username;
public String email;
}
I would create just one DTO class but e.g. pass to its constructor
the list of the fields which I want to be pulled and set by the backend.
All other fields will be null.
The list of fields will be passed in by the front-end.
I find this approach pretty flexible/dynamic.
It also avoids multiple classes to maintain.
I don't know if this approach matches any best practices or enterprise patterns
but creating multiple DTO classes definitely sounds worse.
Using "just" one DTO or the entity directly comes with a high cost that you usually only pay later, so I would recommend anyone to create a DTO per use case just like you did here.
Here are some of the reasons/costs for this:
If the user of the API sees accessors for state that isn't loaded this will trigger lazy loading which will either result in bad performance or lazy initialization exceptions. If objects are passed through a session, you might lose the context how the object came to be, so you might not always be able to tell which state is loaded.
It might be inefficient to load all data all the time. If you have some text columns that contain lots of data this has to be transferred over the wire and materialized as Java Objects etc. If you don't use the data, it's just pointless to load it at all. One might say this is negligible, but it depends on your use case. The worst that can happen? The DBMS does a full table scan or a less efficient index scan rather than index only scan because you instruct the DBMS to load the value for a column.
Not all the state that you want to provide for a client should be in the relational representation. If you do aggregations or use expressions for e.g. concatenating columns together, you need a DTO.
Having said that, this is a perfect use case for Blaze-Persistence Entity Views.
I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.
A DTO model for your use case could look like the following with Blaze-Persistence Entity-Views:
#EntityView(User.class)
public interface UserToScreenADTO extends Serializable {
String getName();
String getEmail();
}
#EntityView(User.class)
public interface UserToScreenBDTO extends Serializable {
String getPhoneNumber();
Address getAddress();
}
#EntityView(User.class)
public interface UserToScreenCDTO extends Serializable {
Integer getId();
String getUsername();
String getEmail();
}
Querying is a matter of applying the entity view to a query, the simplest being just a query by id.
UserToScreenADTO u = entityViewManager.find(entityManager, UserToScreenADTO.class, id);
The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
Since OP said that the system is used from the same frontend and in the same context, I would consider it bad practice and not recommend using different DTOs.
Reasoning:
Modern frontends normally manage a store of all entites received by the backend. So the frontend can look up entities in the store and - depending on caching policies - load them from the store rather than requesting them from the server. Thus, instead of fetching users part-by-part, the user is transmitted once. This can be further improved by using ETags. While the usage of Etags will hardly improve latency, it can improve network load since the response to a matching ETag is a 304/Not Modified without a body (!) rather than a 200/OK with body. While ETags can be used with many Dto-Objects, more (partial) updates might occur. If, for example, the email and the phone number of a user changes, and the frontend first requests the UserToScreenADTO, it would get a response body that - among other things - contains the new email. When it then later requests a UserToScreenBDTO, it would - again - receive a response body containing the new phone number. With only one DTO, the frontend will receive one updated representation on the first request, and all successive request (made with the matching ETag) will result in a 304/Not Modified.
Furthermore, more classes normally mean higher complexity. Thus, I would recommend to keep the number of classes reasonably small. If using an ETag is not wanted and/or the frontend does not keep a store of server-sent entities, I would recommend the approach described in peter petrov's answer.
The representation should only change if the context changes. If the representations differ drastically between, for example, a user-frontend and an admin-frontend, then different DTOs may be justified.
I've a question about DIP Principle. One of the guidelines says that we should not hold references to a concrete class (if it changes then I'll have to modify all clients that use it). So, what can I follow this guideline when I use POJOs ? For Example:
I have a Bean 'Foo' with some attributes (it could represent a Domain object)
class Foo {
private String one;
private String two;
//getters and setters
}
Multiple clients instantiate this object, for example, to persist it in the Database
class Client1 {
private FooDao dao;
Client1(FooDao dao){
this.dao = dao;
}
public void persist() {
//hard coding
Foo foo = new Foo();
foo.setOne("something...");
dao.save(foo); }
}
class Client2 {
private FooDao dao;
Client2(FooDao dao){
this.dao = dao;
}
public void persist() {
Foo foo = new Foo();
foo.setOne("something...");
foo.setTwo("something...")
dao.save(foo);
}
}
If I add or change any attribute to 'Foo' class every client would have to change, so follow this guideline how can I avoid that?
Thanks!
The comment from #chrylis is spot on. Robert Martin covers this in chapter 6 of Clean Code: Objects and Data Structures.
Objects hide their data behind abstractions and expose functions that operate on that data. Data structures expose their data and have no meaningful functions. (page 95)
The definition of OOP where everything is an object, and there are no data structures, is naive.
Mature programmers know that the idea that everything is an object is a myth. Sometimes you really do want simple data structures with procedures operating on them. (page 97)
So what about classes that expose both data and behavior?
Confusion sometimes leads to unfortunate hybrid structures that are half object and half data structure. They have functions that do significant things, and they also have either public variables or public accessors and mutators that, for all intents and purposes, make the private variables public, tempting other external functions to use those variables the way a procedural program would use a data structure.
Such hybrids make it hard to add new functions but also make it hard to add new data structures. They are the worst of both worlds. Avoid creating them. (page 99)
To the original question: the Dependency Inversion Principle applies to objects, not to data structures like Java Beans.
I think you're taking this a little too literally.
I had the pleasure of attending a talk given by Venkat Subramaniam, which talked about DIP.
You're right when you say that you should be relying on abstractions, not concretions, but in my notes from that talk, I have the footnote, "take this with a grain of salt."
In your case, you're going to want to take this with a grain of salt, since there's a fairly strong code smell here - you're exposing the use of this bean to all consumers who need it, which implicitly create a dependency on it. This violates the Single Responsibility Principle since this bean is being used in more places than it probably should be.
Since it seems like you're talking about a database abstraction, perhaps you would want to look into a DTO which would be exposed between services to carry information between them, and let your bean handle the internals.
To your point...
if it change[s] then I'll have to modify all clients that use it
...this is true if you remove functionality. If you add new functionality, you can let your downstream clients just ignore that functionality. If you want to change existing functionality, you have to allow the clients a path to migration.
You need to define the functionality of the method you would like to add.
interface Functionality {
public void persist();
}
Each class except the manager need to implement the interface:
class Client1 implements Functionality{
//Your code..
}
Add a high level class high level classes that not working directly with low level classes:
Class ManageClients{
Functionality func;
public void setClient(Functionality f) {
func= f;
}
public void manage() {
func.persist();
}
};
ManageClients class doesn't require changes when adding Clients.
Minimized risk to affect old functionality present in ManageClients class since we don't change it.
No need to redo the unit testing for ManageClients class.
This question already has answers here:
Get and Set methods in Java. How do they work?
(5 answers)
Closed 7 years ago.
Can somebody tell me or show me something that would make me understand the get and set methods completely? I know some of it already but it still confuses me.
I am trying to learn the MVC Design Pattern but I find it hard because I haven't completely understand this. I thought it was easy but it's not really that easy. Well, at least for me.
Your own example would be appreciated. Thank you in advance guys :)
The Model, View, Controller design pattern is a useful way of decoupling the various components of an GUI driven application. It improves cohesion, which essentially emphasises the responsibility of discrete elements of your software and helps avoid unnecessary overlapping of functionality.
The Model stores what is referred to as 'business logic'. This means it houses all of the data which is core to your application.
The View is what handles the graphical interface. Everything responsible for managing how your graphics are rendered is defined here.
Finally, the Controller handles events. This includes asynchronous events such as whenever a key has been pressed, or the mouse has been moved, or the user has touched their screen. It receives these events and decides what to do with them.
So, how they come together is as follows; the Model defines what needs to be drawn. Any graphics the View needs to render is therefore housed in the Model. This means that any modifications to the Model's data will in turn effect what is drawn on the screen; however, the Model is only really defining what elements need to be drawn, it has no clue how to draw them; just how to manage them and manipulate them. It's the View which can take these elements and in turn use them within a graphical context. The controller on the other hand, handles events and in turn manipulates the contents of the Model. It does this by using a defined set of rules on how each input event will affect certain parts of the Model.
So, in this regard, the Model, View, Controller can be looked at like this:
final Model m = new Model();
final View v = new View(m);
final Controller c = new Controller(m);
Both the Controller and View need access to the Model in order to manage and render the application respectively, but the Model doesn't care about either of them. This is because the Model defines the core data dependencies of your application, which should be transferrable, and work independently of whether it's a component of a GUI or not.
In terms of getter and setter methods, all these do are provide access to a member variable sitting inside a class. So if we were to look inside the View, we would see something like this:
public final class View {
/* Member Variables. */
private final Model mModel;
public View(final Model pModel) {
/* Initialize Member Variables. */
this.mModel = pModel;
}
public final Model getModel() {
return this.mModel;
}
}
The method getModel() is referred to as a getter method; it's sole responsibility is to return a variable; in this case it returns the View's mModel variable. What's useful about getter and setter methods is that you can control access to that variable; the method can be declared public, protected and private for example, which all change just who else inside your application can get access to the Model. The same goes for a setter method, whose only responsibility should be to change the value of a specific variable belonging to the owning Object.
I know this should be a comment, but I currently don't have the reputation required to post a comment.
First of all, could you please provide more information about what specifically you'd like to know? Are you confused about how getters and setters work in general? Are you confused about how the work in an MVC pattern? (getters and setters work the same way in MVC as they do in other design patterns).
If the link posted in the comment above doesn't solve your answer, then hopefully I can help. Getters and setters (getVarName and setVarName) are used to provide additional functionality (like ensuring that a value fits a desired range, etc) and also to provide encapsulation of your code. Besides the additional functionality (like validation), encapsulation also helps avoid errors like accidentally changing the value of a class's variable when you don't mean to. Take a Customer class for example:
public class Customer {
private int empNo;
private int deptNo;
//additional class variables
public Customer() {
//default constructor }
public Customer (int emp, int dept) {
empNo = emp;
deptNo = dept;
}
public int getEmpNo() {
return empNo;
}
public void setEmpNo(int emp) {
empNo = emp;
}
//other methods
}
Let's say that all employee numbers must be 5 digits long and not start with a 0. If we don't use a setter, then there's no way to check if the number given is a valid number (or that it was even given). For that, we could write a simple validation requirement in our setEmpNo method.
public void setEmpNo(int emp) {
if(emp >= 10000 && emp <= 99999) {
empNo = emp;
}
//code to handle invalid numbers
}
Encapsulation also helps us avoid certain errors, like changing the value of empNo when we mean to just check the value in a condition, etc. For instance, if we don't use getters and setters and just have a public empNo, the following typo would change the value of the employee's employee number:
if(employee1.empNo = 12345) { //checking if this is employee 12345 would use ==
//perform action for specified employee
}
However, if we use getters and setters, we'd still run into a problem because we're not checking if the desired employee's employee number is 12345, but that employee's number would NOT be permanently changed to 12345 and would still retain his/her correct employee number. Does this make sense?
It looks like someone already posted a pretty good answer about MVC, so I won't repeat any info on that. One thing I will point out is that MVC is usually (if not always) used for server-based apps. If you have an app that contains a website that users interact with and a database, then there's a good chance you'll use some variant of the MVC pattern. However, you're not going to use MVC for something like a Hello World app.
I hope my answer isn't too basic. It's hard to judge a user's knowledge level without getting additional info. If you'd like me to clarify or give further explanation on anything I've posted, let me know.
Best of luck going forward.
Getter and setter methods used when we define instance variables private so from outside class we can't access private instance variables directly which is useful for encapsulation(hiding data from outside world). So for accessing private variables we required some methods which is basically getter and setter.
public class Employee
{
private int empNum;
public Employee(int empNum) {
this.empNum = empNum;
}
public int getEmpNum() {
return empNum;
}
public void setEmpNum(int empNum) {
this.empNum = empNum;
}
}
for more reasons why we use getter/setter read this answer
There is no direct relation between MVC and getter/setter methods.
MVC is basically design patter for software development where we divide task between different modules(model, view and controller)
model -> Data layer
view -> Representational layer
controller -> Controller layer between model and view
So when you create model class in mvc you define multiple instance variables(attributes) for model but from controller you don't want to access that variables directly so in that case you should use getter setter methods.
Actually getter/setter concept in not limited to just mvc it is use as a codding standard and for abstraction purposes.
I first thought about using ITDs to define the private static final Logger logger = ... for some unrelated cases, but it doesn't look enough like an obvious improvement to use that as a demonstration example.
Is there some standard/suggested example of ITD usage, which people should use for teaching purposes?
I'd like to add another example to Adam's answer.
Using aspects is a way to improve modularization of your software, as well as OOP is, except that OOP is applied "vertically", while AOP is applied "horizontally".
So, while advice can be used to modify "horizontally" the behavior of all methods responding to some criteria, aften code in advice will need also some data, and ITD makes it possible to add that fields "horizontally" while at the same time contain in a single compilation unit (the aspect) related data and code.
Since you are adding data via ITD fields, you'll probably also want to offer some method to manipulate those fields, like a setter/getter.
I tried to rephrase it a few times, I hope it's easy to understand.
To give you an example, suppose you have a graphical editing program, where the user can create, delete and display a number of Shapes (pretty canonical eh? :D ).
Shapes have a lot of data, for example they have a color, coordinates etc.. which correctly belong to the class itself. However, since this is a web 3.0 application, you want users to be able to cooperate on a single drawing, which means each shape must know when it is changed, if it has been communicated to other users that the shape is changed, wether it is locked by some user that is actually dragging it etc..
You can do it in simple OOP, implementing relevant parts in Shape or whatever your root class is, but you will the pollute all your setters with calls like "this.setDirty(true)" or similar stuff.
Instead, you decide to go AOP and implement it in an aspect. In this case, you can easily add an advice after all setters, but you'll also need to store a "dirty" boolean, or even a list of properties that changed if you want to optimize your network protocol sending only deltas of changes.
You could implement it like
public aspect ShapesAreDirtyThings {
private boolean Shape.dirty;
after(Shape s) : execution(* Shape+.set*(..)) {
s.dirty = true;
// Set some other global field, start a thread to communicate
// to other users about the change, whatever ..
}
public boolean Shape.isDirty() {
return s.dirty;
}
public boolean Shape.findDirtyChildren() { // whatever
}
This is nothing you cannot do with common AOP, is simply a matter of encapsulating in a single compilation unit advice, data needed by that advice, and methods that will eventually operate on that data.
Java does not support multiple inheritance or mixin. But with ITD's you can make Scala like Traits or Ruby like Mixins.
Here is an example taking advantage of JPA and Spring's Configurable:
Interface:
package com.evocatus.aop;
public interface DomainNotify {
public void postPersist();
public void postUpdate();
public void postRemove();
}
AspectJ ITD:
package com.evocatus.aop;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.Transient;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.springframework.beans.factory.annotation.Autowired;
import com.evocatus.service.DomainNotifyService;
privileged aspect DomainNotifyAdvice {
#JsonIgnore
#Transient
#Autowired
transient DomainNotifyService DomainNotify.domainNotifyService;
#PostPersist
public void DomainNotify.postPersist() {
this.domainNotifyService.publishSave(this);
}
#PostUpdate
public void DomainNotify.postUpdate() {
this.domainNotifyService.publishUpdate(this);
}
#PostRemove
public void DomainNotify.postRemove() {
this.domainNotifyService.publishRemove(this);
}
}
Now any class that implements DomainNotify will get the ITD methods weaved in.
#Entity
#Configurable
public class MyJPAObject implements DomainNotify {
}
Take a look at Spring ROO. It is a rapid dev. env using Spring. I see it as a Ruby on Rails but in java with Spring ;-)
It use ITD a lot to generate getter, setter, toString etc... based on the attributes you define when you create your Class.
Spring Roo