Places where JavaBeans are used? - java

What is a JavaBean and why do I need it? Since I can create all apps with the class and interface structure? Why do I need beans? And can you give me some examples where beans are essential instead of classes and interfaces?
Please explain the essentiality of a bean in the below context:
Wep apps
Standalone apps

They often just represent real world data. Here's a simple example of a Javabean:
public class User implements java.io.Serializable {
// Properties.
private Long id;
private String name;
private Date birthdate;
// Getters.
public Long getId() { return id; }
public String getName() { return name; }
public Date getBirthdate() { return birthdate; }
// Setters.
public void setId(Long id) { this.id = id; }
public void setName(String name) { this.name = name; }
public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
// Important java.lang.Object overrides.
public boolean equals(Object other) {
return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
}
public int hashCode() {
return (id != null) ? (getClass().hashCode() + id.hashCode()) : super.hashCode();
}
public String toString() {
return String.format("User[id=%d,name=%s,birthdate=%d]", id, name, birthdate);
}
}
Implementing Serializable is not per se mandatory, but very useful if you'd like to be able to persist or transfer Javabeans outside Java's memory, e.g. in harddisk or over network.
In for example a DAO class you can use it to create a list of users wherein you store the data of the user table in the database:
List<User> users = new ArrayList<User>();
while (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong("id"));
user.setName(resultSet.getString("name"));
user.setBirthdate(resultSet.getDate("birthdate"));
users.add(user);
}
return users;
In for example a Servlet class you can use it to transfer data from the database to the UI:
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
List<User> users = userDAO.list();
request.setAttribute("users", users);
request.getRequestDispatcher("users.jsp").forward(request, response);
}
In for example a JSP page you can access it by EL, which follows the Javabean conventions, to display the data:
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Birthdate</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td><c:out value="${user.name}" /></td>
<td><fmt:formatDate value="${user.birthdate}" pattern="yyyy-MM-dd" /></td>
</tr>
</c:forEach>
</table>
Does it make sense? You see, it's kind of a convention which you can use everywhere to store, transfer and access data.
See also:
JavaBeans specification

Beans themselves
JavaBeans are everywhere, they're a convention and just about every single slightly larger library out there uses those conventions to automate things. Just a few reasons why JavaBeans should be used:
They serialize nicely.
Can be instantiated using reflection.
Can otherwise be controlled using reflection very easily.
Good for encapsulating actual data from business code.
Common conventions mean anyone can use your beans AND YOU CAN USE EVERYONE ELSE'S BEANS without any kind of documentation/manual easily and in consistent manner.
Very close to POJOs which actually means even more interoperability between distinct parts of the system.
Also there's of course Enterprise JavaBeans which are a whole another matter and shouldn't be mixed with plain JavaBeans. I just wanted to mention EJB:s because the names are similar and it's easy to get those two confused.
Beans in web applications
If you consider "normal" JavaBeans in web app context, they make more sense than wearing shoes in your legs. Since the Servlet specification requires for sessions to be serializable, it means you should store your data in session as something that's serializable - why not make it a bean then! Just throw your SomeBusinessDataBean into the session and you're good to go, laughably easy, specification-compliant and convenient.
Also transferring that data around the application is easy too since JavaBeans help you to decouple parts of your application completely. Think JavaBeans as a letter and various subsystems of the application as departments within a very large corporation: Dept.A mails a bunch of data to Dept.B, Dept.B doesn't know -or even care- where the data came from just as it should be and can just open the letter, read stuff from it and do its thing based on that data.
Beans in standalone applications
Actually what's above applies to standalone apps too, the only difference is that you can mess up with the UI a bit more since standalone applications have stateful UI:s while web applications have statelss UI:s which in some cases only simulate stateful UI:s. Because of this difference, it's easier to make a mess with standalone application but that's worth a whole another topic and isn't directly related to JavaBeans at all.

A bean is nothing much, really. For a class to be a "bean", all it requires is:
to have a public, no argument constructor
to be serializable (to implement the Serializable interface, either directly or through one of its super classes).
To that, you can add getters and setters for properties of the class that conform to a specific naming convention if you want the fields to be discoverable in certain circumstances (e.g. making that class some object you can drag and drop from a visual editor in your IDE, for example).
You can find more directly from Sun here.

A Java Bean is a software component that has been designed to be reusable in a variety of different environments. There is no restriction on the capability of a Bean. It may perform a simple function, such as checking the spelling of a document, or a complex function, such as forecasting the performance of a stock portfolio. A Bean may be visible to an end user. One example of this is a button on a graphical user interface. A Bean may also be invisible to a user. Software to decode a stream of multimedia information in real time is an example of this type of building block. Finally, a Bean may be designed to work autonomously on a user's workstation or to work in cooperation with a set of other distributed components. Software to generate a pie chart from a set of data points is an example of a Bean that can execute locally. However, a Bean that provides real-time price information from a stock or commodities exchange would need to work in cooperation with other distributed software to obtain its data.
We will see shortly what specific changes a software developer must make to a class so that it is usable as a Java Bean. However, one of the goals of the Java designers was to make it easy to use this technology. Therefore, the code changes are minimal.
Advantages of Java Beans
A software component architecture provides standard mechanisms to deal with software building blocks. The following list enumerates some of the specific benefits that Java technology provides for a component developer:
A Bean obtains all the benefits of Java's "write-once, run-anywhere" paradigm.
The properties, events, and methods of a Bean that are exposed to an application
builder tool can be controlled.
A Bean may be designed to operate correctly in different locales, which makes it
useful in global markets.
Auxiliary software can be provided to help a person configure a Bean. This software is
only needed when the design-time parameters for that component are being set. It
does not need to be included in the run-time environment.
The configuration settings of a Bean can be saved in persistent storage and restored
at a later time.
A Bean may register to receive events from other objects and can generate events that
are sent to other objects.
Here's a simple example of a Javabean:
public class MyBean implements java.io.Serializable
{
protected int theValue;
public MyBean()
{
}
public void setMyValue(int newValue)
{
theValue = newValue;
}
public int getMyValue()
{
return theValue;
}
}
This is a real Bean named MyBean that has state (the variable theValue) that will automatically be saved and restored by the JavaBeans persistence mechanism, and it has a property named MyValue that is usable by a visual programming environment. This Bean doesn't have any visual representation, but that isn't a requirement for a JavaBean component.

Related

Trying to understand SRP when we seggregate responsibilities into different classes

I'm trying to understand SRP principle and most of the sof threads didn't answer this particular query I'm having,
Use-case
I'm trying to send an email to the user's email address to verify himself whenever he tries to register/create an user-account in a website.
Without SRP
class UserRegistrationRequest {
String name;
String emailId;
}
class UserService {
Email email;
boolean registerUser(UserRegistrationRequest req) {
//store req data in database
sendVerificationEmail(req);
return true;
}
//Assume UserService class also has other CRUD operation methods()
void sendVerificationEmail(UserRegistrationRequest req) {
email.setToAddress(req.getEmailId());
email.setContent("Hey User, this is your OTP + Random.newRandom(100000));
email.send();
}
}
The above class 'UserService' violates SRP rule as we are clubbing 'UserService' CRUD operations and triggering verification email code into 1 single class.
Hence I do,
With SRP
class UserService {
EmailService emailService;
boolean registerUser(UserRegistrationRequest req) {
//store req data in database
sendVerificationEmail(req);
return true;
}
//Assume UserService class also has other CRUD operation methods()
void sendVerificationEmail(UserRegistrationRequest req) {
emailService.sendVerificationEmail(req);
}
}
class EmailService {
void sendVerificationEmail(UserRegistrationRequest req) {
email.setToAddress(req.getEmailId());
email.setContent("Hey User, this is your OTP + Random.newRandom(100000));
email.send();
}
But even 'with SRP', UserService as a class again holds a behaviour of sendVerificationEmail(), though this time it didn't hold the entire logic of sending the email.
Isn't it again we are clubbing crud operation's and sendVerificationEmail() into 1 single class even after applying SRP?
Your feeling is absolutely right. I agree with you.
I think your problem starts with your naming style, since you seem to be quite aware what SRP means. Class names like '...Service' or '...Manager' carry a very vague meaning or semantics. They describe a more generalized context or concept. In other words a '...Manager' class invites you to put everything inside and it still feels right, because it's a manager.
When you get more concrete by trying to focus on the true concepts of your classes or their responsibilities, you will automatically find bigger names with a stronger meaning or semantics. This will really help you to split up classes and to identify responsibilities.
SRP:
There should never be more than one reason to change a certain module.
You could start with renaming the UserService to UserDatabaseContext. Now this would automatically force you to only put database related operations into this class (e.g. CRUD operations).
You even can get more specific here. What are you doing with a database? You read from and write to it. Obviously two responsibilities, which means two classes: one for read operations and another responsible for write operations. This could be very general classes that can just read or write anything. Let's call them DatabaseReader and DatabaseWriter and since we are trying to decouple everything we are going to use interfaces everywhere. This way we get the two IDatabaseReader and IDatabaseWriter interfaces. This types are very low level since they know the database (Microsoft SQL or MySql), how to connect to it and the exact language to query it (using e.g. SQL or MySql):
// Knows how to connect to the database
interface IDatabaseWriter {
void create(Query query);
void insert(Query query);
...
}
// Knows how to connect to the database
interface IDatabaseReader {
QueryResult readTable(string tableName);
QueryResult read(Query query);
...
}
On top, you could implement a more specialized layer of read and write operations, e.g. user related data. We would introduce a IUserDatabaseReader and a IUserDatabaseWriter interface. This interfaces don't know how to connect to the database or what type of database is used. This interfaces only know what information is required to read or write user details (e.g. using a Query object that is transformed into a real query by the low level IDatabaseReader or IDatabaseWriter):
// Knows only about structure of the database (e.g. there is a table called 'user')
// Implementation will internally use IDatabaseWriter to access the database
interface IUserDatabaseWriter {
void createUser(User newUser);
void updateUser(User user);
void updateUserEmail(long userKey, Email emailInfo);
void updateUserCredentials(long userKey, Credential userCredentials);
...
}
// Knows only about structure of the database (e.g. there is a table called 'user')
// Implementation will internally use IDatabaseReader to access the database
interface IUserDatabaseReader {
User readUser(long userKey);
User readUser(string userName);
Email readUserEmail(string userName);
Credential readUserCredentials(long userKey);
...
}
We are still not done with the persistence layer. We can introduce another interface IUserProvider. The idea is to decouple the database access from the rest of our application. In other words we consolidate the user related data query operations into this class. So, IUserProvider will be the only type that has direct access to the data layer. It forms the interface to the application's persistence layer:
interface IUserProvider {
User getUser(string userName);
void saveUser(User user);
User createUser(string userName, Email email);
Email getUserEmail(string userName);
}
The implementation of IUserProvider. The only class in the whole application that has direct access to the data layer by referencing IUserDatabaseReader and IUserDatabaseWriter. It wraps reading and writing of data to make data handling more convenient. The responsibility of this type is to provide user data to the application:
class UserProvider {
IUserDatabaseReader userReader;
IUserDatabaseWriter userWriter;
// Constructor
public UserProvider (IUserDatabaseReader userReader,
IUserDatabaseWriter userWriter) {
this.userReader = userReader;
this.userWriter = userWriter;
}
public User getUser(string userName) {
return this.userReader.readUser(username);
}
public void saveUser(User user) {
return this.userWriter.updateUser(user);
}
public User createUser(string userName, Email email) {
User newUser = new User(userName, email);
this.userWriter.createUser(newUser);
return newUser;
}
public Email getUserEmail(string userName) {
return this.userReader.readUserEmail(userName);
}
}
Now that we tackled the database operations we can focus on the authentication process and continue to extract the authentication logic from the UserService by adding a new interface IAuthentication:
interface IAuthentication {
void logIn(User user)
void logOut(User);
void registerUser(UserRegistrationRequest registrationData);
}
The implementation of IAuthentication implements the special authentication procedure:
class EmailAuthentication implements IAuthentication {
EmailService emailService;
IUserProvider userProvider;
// Constructor
public EmailAuthentication (IUserProvider userProvider,
EmailService emailService) {
this.userProvider = userProvider;
this.emailService = emailService;
}
public void logIn(string userName) {
Email userEmail = this.userProvider.getUserEmail(userName);
this.emailService.sendVerificationEmail(userEmail);
}
public void logOut(User user) {
// logout
}
public void registerUser(UserRegistrationRequest registrationData) {
this.userProvider.createNewUser(registrationData.getUserName, registrationData.getEmail());
this.emailService.sendVerificationEmail(registrationData.getEmail());
}
}
To decouple the EmailService from the EmailAuthentication class, we can remove the dependency on UserRegistrationRequest by letting sendVerificationEmail() take an Email` parameter object instead:
class EmailService {
void sendVerificationEmail(Email userEmail) {
email.setToAddress(userEmail.getEmailId());
email.setContent("Hey User, this is your OTP + Random.newRandom(100000));
email.send();
}
Since the authentication is defined by an interface IAuthentication, you can create a new implementation at any time when you decide to use a different procedure (e.g. WindowsAuthentication), but without modifying existing code. This will also work with the IDatabaseReader and IDatabaseWriter once you decide to switch to a different database (e.g. Sqlite). The IUserDatabaseReader and IUserDatabaseWriter implementations will still work without any modification.
With this class design, you now have exactly one reason to modify each existing type:
EmailService when you need to change the implementation (e.g. use
different email API)
IUserDatabaseReader or IUserDatabaseWriter when you want to add additional user related read or write operations (e.g. to handle user role)
provide new implementations of IDatabaseReader or IDatabaseWriter when you want to switch underlying database or you need to modify database access
implementations of IAuthentication when the procedure changes (e.g. using build in OS authentication)
Now everything is cleanly separated. Authentication doesn't mix with CRUD operations. We have an additional layer between application and persistence layer to add flexibility regarding the underlying persistence system. So CRUD operations don't mix with the actual persistence operations.
As a tip: in future you better start with the thinking (design) part first: what must my application do?
handle authentication
handle users
handle a database
handle email
create user responses
show view pages to the user
etc.
As you can see, you can start to implement each step or requirement separately. But this doesn't mean each requirement is realized by exactly one class. As you remember, we split up database access into four responsibilities or classes: read and write to real database (low level), read and write to database abstraction layer, to reflect concrete use cases (high level). Using interfaces adds flexibility and testability to the application.
There is already a great answer to this question by #BionicCode. I just wan't to add a short summary and some of my thoughts on the matter.
The SRP can be a tricky one.
In my experience the granularity of the responsibilities and the number of abstactions that you place in your system will affect it's ease of use and it's size.
You can add a-lot of abstractions and break everything down to very small components. This indeed is something that we should strive for.
Now the question then is: When to stop?
This will depend on:
The size of your application
What parts of it will change more frequently than others
Do you need to compose objects together, or most of the time your modules are independent of one another and you don't reause many objects.
What time do you have
What is the size of your team
A lot of other stuff...
Let's start with how big is the team.
One reason we break our code into separate modules and classes into seprate files is so that we can work in a team and avoid too many merges in our favorite source control system. If you need to change a file that contains a component of your system and someone else needs to change it too, this may get ugly pretty fast. Now if you do separate modules using SRP you get more but smaller modules that most of the time will change independent of one another.
What if the team isn't that big and our modules are not that big too? Do you need to generate more of them?
Here's an example.
Let's say that you have a mobile application that has setings. We may say that containg these settigns in one responsibility and add it to one interface IApplicationSettings to hold all of them.
In the case where we have 30 settings this interface will be huge and that's bad. It also means that we are probably violating the SRP again as this interface will probably hold settings for multiple different categories.
So we decide to apply Interface seggregation principle and SRP and divide the settings to multiple interfaces ISomeCategorySettings, IAnotherCategorySettings etc.
Now let's say that our applications isn't too big (yet) and we have 5 settings. Even if they are from different categories, is it bad to keep these settings in one interface?
I would say that it's fine to have all settigns in one interface as long as it doesn't start to slow us down or start to get ugly (30 or more settigns!).
Is it that bad to construct an email and send it from your service object? This indeed is something that can get ugly pretty quickly, so you better move this responsibility from the service object to an EmailSender fast.
If you have a service object that contains 5 methods, do you realy need to break this into 5 different objects for every operation? If these methods are big, yes. If they small, keeping them in one object it's that big of a problem.
SRP is great, but take granularity into account and choose it wisely based on code size, team size etc.

Ways to pass additional data to Custom RevisionEntity in Hibernate Envers?

It's RESTful web app. I am using Hibernate Envers to store historical data. Along with revision number and timestamp, I also need to store other details (for example: IP address and authenticated user). Envers provides multiple ways to have a custom revision entity which is awesome. I am facing problem in setting the custom data on the revision entity.
#RevisionEntity( MyCustomRevisionListener.class )
public class MyCustomRevisionEntity extends DefaultRevisionEntity {
private String userName;
private String ip;
//Accessors
}
public class MyCustomRevisionListener implements RevisionListener {
public void newRevision( Object revisionEntity ) {
MyCustomRevisionEntity customRevisionEntity = ( MyCustomRevisionEntity ) revisionEntity;
//Here I need userName and Ip address passed as arguments somehow, so that I can set them on the revision entity.
}
}
Since newRevision() method does not allow any additional arguments, I can not pass my custom data (like username and ip) to it. How can I do that?
Envers also provides another approach as:
An alternative method to using the org.hibernate.envers.RevisionListener is to instead call the getCurrentRevision( Class revisionEntityClass, boolean persist ) method of the org.hibernate.envers.AuditReader interface to obtain the current revision, and fill it with desired information.
So using the above approach, I'll have to do something like this:
Change my current dao method like:
public void persist(SomeEntity entity) {
...
entityManager.persist(entity);
...
}
to
public void persist(SomeEntity entity, String userName, String ip) {
...
//Do the intended work
entityManager.persist(entity);
//Do the additional work
AuditReader reader = AuditReaderFactory.get(entityManager)
MyCustomRevisionEntity revision = reader.getCurrentRevision(MyCustomRevisionEntity, false);
revision.setUserName(userName);
revision.setIp(ip);
}
I don't feel very comfortable with this approach as keeping audit data seems a cross cutting concern to me. And I obtain the userName and Ip and other data through HTTP request object. So all that data will need to flow down right from entry point of application (controller) to the lowest layer (dao layer).
Is there any other way in which I can achieve this? I am using Spring.
I am imagining something like Spring keeping information about the 'stack' to which a particular method invocation belongs. So that when newRevision() in invoked, I know which particular invocation at the entry point lead to this invocation. And also, I can somehow obtain the arguments passed to first method of the call stack.
One good way to do this would be to leverage a ThreadLocal variable.
As an example, Spring Security has a filter that initializes a thread local variable stored in SecurityContextHolder and then you can access this data from that specific thread simply by doing something like:
SecurityContext ctx = SecurityContextHolder.getSecurityContext();
Authorization authorization = ctx.getAuthorization();
So imagine an additional interceptor that your web framework calls that either adds additional information to the spring security context, perhaps in a custom user details object if using spring security or create your own holder & context object to hold the information the listener needs.
Then it becomes a simple:
public class MyRevisionEntityListener implements RevisionListener {
#Override
public void newRevision(Object revisionEntity) {
// If you use spring security, you could use SpringSecurityContextHolder.
final UserContext userContext = UserContextHolder.getUserContext();
MyRevisionEntity mre = MyRevisionEntity.class.cast( revisionEntity );
mre.setIpAddress( userContext.getIpAddress() );
mre.setUserName( userContext.getUserName() );
}
}
This feels like the cleanest approach to me.
It is worth noting that the other API getCurrentRevision(Session,boolean) was deprecated as of Hibernate 5.2 and is scheduled for removal in 6.0. While an alternative means may be introduced, the intended way to perform this type of logic is using a RevisionListener.

I can't unit test my class without exposing private fields -- is there something wrong with my design?

I have written some code which I thought was quite well-designed, but then I started writing unit tests for it and stopped being so sure.
It turned out that in order to write some reasonable unit tests, I need to change some of my variables access modifiers from private to default, i.e. expose them (only within a package, but still...).
Here is some rough overview of my code in question. There is supposed to be some sort of address validation framework, that enables address validation by different means, e.g. validate them by some external webservice or by data in DB, or by any other source. So I have a notion of Module, which is just this: a separate way to validate addresses. I have an interface:
interface Module {
public void init(InitParams params);
public ValidationResponse validate(Address address);
}
There is some sort of factory, that based on a request or session state chooses a proper module:
class ModuleFactory {
Module selectModule(HttpRequest request) {
Module module = chooseModule(request);// analyze request and choose a module
module.init(createInitParams(request)); // init module
return module;
}
}
And then, I have written a Module that uses some external webservice for validation, and implemented it like that:
WebServiceModule {
private WebServiceFacade webservice;
public void init(InitParams params) {
webservice = new WebServiceFacade(createParamsForFacade(params));
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
So basically I have this WebServiceFacade which is a wrapper over external web service, and my module calls this facade, processes its response and returns some framework-standard response.
I want to test if WebServiceModule processes reponses from external web service correctly. Obviously, I can't call real web service in unit tests, so I'm mocking it. But then again, in order for the module to use my mocked web service, the field webservice must be accessible from the outside. It breaks my design and I wonder if there is anything I could do about it. Obviously, the facade cannot be passed in init parameters, because ModuleFactory does not and should not know that it is needed.
I have read that dependency injection might be the answer to such problems, but I can't see how? I have not used any DI frameworks before, like Guice, so I don't know if it could be easily used in this situation. But maybe it could?
Or maybe I should just change my design?
Or screw it and make this unfortunate field package private (but leaving a sad comment like // default visibility to allow testing (oh well...) doesn't feel right)?
Bah! While I was writing this, it occurred to me, that I could create a WebServiceProcessor which takes a WebServiceFacade as a constructor argument and then test just the WebServiceProcessor. This would be one of the solutions to my problem. What do you think about it? I have one problem with that, because then my WebServiceModule would be sort of useless, just delegating all its work to another components, I would say: one layer of abstraction too far.
Yes, your design is wrong. You should do dependency injection instead of new ... inside your class (which is also called "hardcoded dependency"). Inability to easily write a test is a perfect indicator of a wrong design (read about "Listen to your tests" paradigm in Growing Object-Oriented Software Guided by Tests).
BTW, using reflection or dependency breaking framework like PowerMock is a very bad practice in this case and should be your last resort.
I agree with what yegor256 said and would like to suggest that the reason why you ended up in this situation is that you have assigned multiple responsibilities to your modules: creation and validation. This goes against the Single responsibility principle and effectively limits your ability to test creation separately from validation.
Consider constraining the responsibility of your "modules" to creation alone. When they only have this responsibility, the naming can be improved as well:
interface ValidatorFactory {
public Validator createValidator(InitParams params);
}
The validation interface becomes separate:
interface Validator {
public ValidationResponse validate(Address address);
}
You can then start by implementing the factory:
class WebServiceValidatorFactory implements ValidatorFactory {
public Validator createValidator(InitParams params) {
return new WebServiceValidator(new ProdWebServiceFacade(createParamsForFacade(params)));
}
}
This factory code becomes hard to unit-test, since it is explicitly referencing prod code, so keep this impl very concise. Put any logic (like createParamsForFacade) on the side, so that you can test it separately.
The web service validator itself only gets the responsibility of validation, and takes in the façade as a dependency, following the Inversion of Control (IoC) principle:
class WebServiceValidator implements Validator {
private final WebServiceFacade facade;
public WebServiceValidator(WebServiceFacade facade) {
this.facade = facade;
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
Since WebServiceValidator is not controlling the creation of its dependencies anymore, testing becomes a breeze:
#Test
public void aTest() {
WebServiceValidator validator = new WebServiceValidator(new MockWebServiceFacade());
...
}
This way you have effectively inverted the control of the creation of the dependencies: Inversion of Control (IoC)!
Oh, and by the way, write your tests first. This way you will naturally gravitate towards a testable solution, which is usually also the best design. I think that this is due to the fact that testing requires modularity, and modularity is coincidentally the hallmark of good design.

Best design pattern to implement upload feature

I am working on a web application which is based on spring MVC. We have various screens for adding different domain components(eg. Account details, Employee details etc). I need to implement an upload feature for each of these domain components i.e. to upload Account, upload employee details etc which will be provided in a csv file (open the file, parse its contents, validate and then persist).
My question is, which design pattern should i consider to implement such a requirement so that upload (open the file, parse its contents, validate and then persist) feature becomes generic. I was thinking about using the template design pattern. Template Pattern
Any suggestions,pointers,links would be highly appreciated.
I am not going to answer your question. That said, let me answer your question! ;-)
I think that design patterns should not be a concern in this stage of development. In spite of their greatness (and I use them all the time), they should not be your primary concern.
My suggestion is for you to implement the first upload feature, then the second and then watching them for what they have that is equal and create a "mother" class. Whenever you come to a third class, repeat the process of generalization. The generic class will come naturally in this process.
Sometimes, I believe that people tend to over engineer and over plan. I am in good company: http://www.joelonsoftware.com/items/2009/09/23.html. Obviouslly, I am not advocating for no design software - that never works well. Nevertheless, looking for similarities after some stuff has been implemented and refactoring them may achieve better results (have you already read http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=sr_1_1?ie=UTF8&qid=1337348138&sr=8-1? It is old but stiil great!).
A strategy pattern my be useful here for the uploader. The Uploader class would be a sort of container/manager class that would simply contain a parsing attribute and a persistance attribute. Both of these attributes would be defined as an abstract base class and would have multiple implementations. Even though you say it will always be csv and oracle, this approach would be future-proof and would also separate the parsing/verifying from the persistence code.
Here's an example:
class Uploader
{
private:
Parser parser_;
Persistence persistence_;
void upload() {
parser_.read();
parser_.parse();
parser_.validate();
persistence_.persist(parser_.getData());
}
public:
void setParser(Parser parser) {parser_ = parser;}
void setPersister(Persistence persistence) {persistence_ = persistence;}
};
Class Parser
{
abstract void read();
abstract void parse();
abstract void validate();
abstract String getData();
};
class Persistence
{
abstract persist(String data);
};
class CsvParser : public Parser
{
// implement everything here
};
// more Parser implementations as needed
class DbPersistence : public Persistence
{
// implement everything here
};
class NwPersistence : public Persistence
{
// implement everything here
};
// more Persistence implementations as needed
You could use an Abstract Factory pattern.
Have an upload interface and then implement it for each of the domain objects and construct it in the factory based on the class passed in.
E.g.
Uploader uploader = UploadFactory.getInstance(Employee.class);

Good practice to validate immutable values objects

Suppose a MailConfiguration class specifying settings for sending mails :
public class MailConfiguration {
private AddressesPart addressesPart;
private String subject;
private FilesAttachments filesAttachments;
private String bodyPart;
public MailConfiguration(AddressesPart addressesPart, String subject, FilesAttachments filesAttachements,
String bodyPart) {
Validate.notNull(addressesPart, "addressesPart must not be null");
Validate.notNull(subject, "subject must not be null");
Validate.notNull(filesAttachments, "filesAttachments must not be null");
Validate.notNull(bodyPart, "bodyPart must not be null");
this.addressesPart = addressesPart;
this.subject = subject;
this.filesAttachements = filesAttachements;
this.bodyPart = bodyPart;
}
// ... some useful getters ......
}
So, I'm using two values objects : AddressesPart and FilesAttachment.
Theses two values objects have similar structures so I'm only going to expose here AddressesPart :
public class AddressesPart {
private final String senderAddress;
private final Set recipientToMailAddresses;
private final Set recipientCCMailAdresses;
public AddressesPart(String senderAddress, Set recipientToMailAddresses, Set recipientCCMailAdresses) {
validate(senderAddress, recipientToMailAddresses, recipientCCMailAdresses);
this.senderAddress = senderAddress;
this.recipientToMailAddresses = recipientToMailAddresses;
this.recipientCCMailAdresses = recipientCCMailAdresses;
}
private void validate(String senderAddress, Set recipientToMailAddresses, Set recipientCCMailAdresses) {
AddressValidator addressValidator = new AddressValidator();
addressValidator.validate(senderAddress);
addressValidator.validate(recipientToMailAddresses);
addressValidator.validate(recipientCCMailAdresses);
}
public String getSenderAddress() {
return senderAddress;
}
public Set getRecipientToMailAddresses() {
return recipientToMailAddresses;
}
public Set getRecipientCCMailAdresses() {
return recipientCCMailAdresses;
}
}
And the associated validator : AddressValidator
public class AddressValidator {
private static final String EMAIL_PATTERN
= "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*#[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
public void validate(String address) {
validate(Collections.singleton(address));
}
public void validate(Set addresses) {
Validate.notNull(addresses, "List of mail addresses must not be null");
for (Iterator it = addresses.iterator(); it.hasNext(); ) {
String address = (String) it.next();
Validate.isTrue(address != null && isAddressWellFormed(address), "Invalid Mail address " + address);
}
}
private boolean isAddressWellFormed(String address) {
Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);
Matcher matcher = emailPattern.matcher(address);
return matcher.matches();
}
}
Thus, I have two questions :
1) If for some reasons, later, we want to validate differently an address mail (for instance to include/exclude some aliases matching to existing mailingList), should I expose a kind of IValidator as a constructor parameter ? like the following rather than bringing concrete dependence (like I made):
public AddressValidator(IValidator myValidator) {
this.validator = myValidator;
}
Indeed, this will respect the D principle of SOLID principle : Dependency injection.
However, if we follow this logical, would a majority of Values Objects own an abstract validator or it's just an overkill the most of time (thinking to YAGNI ?) ?
2) I've read in some articles than in respect of DDD, all validations must be present and only present in Aggregate Root, means in this case : MailConfiguration.
Am I right if I consider that immutable objects should never be in an uncohesive state ? Thus, would validation in constructor as I made be preferred in the concerned entity (and so avoiding aggregate to worry about validation of it's "children" ?
There's a basic pattern in DDD that perfectly does the job of checking and assembling objects to create a new one : the Factory.
I've read in some articles than in respect of DDD, all validations
must be present and only present in Aggregate Root
I strongly disagree with that. There can be validation logic in a wide range of places in DDD :
Validation upon creation, performed by a Factory
Enforcement of an aggregate's invariants, usually done in the Aggregate Root
Validation spanning accross several objects can be found in Domain Services.
etc.
Also, I find it funny that you bothered to create an AddressesPart value object -which is a good thing, without considering making EMailAddress a value object in the first place. I think it complicates your code quite a bit because there's no encapsulated notion of what an email address is, so AddressesPart (and any object that will manipulate addresses for that matter) is forced to deal with the AddressValidator to perform validation of its addresses. I think it shouldn't be its responsibility but that of an AddressFactory.
I'm not quite sure if I follow you 100%, but one way to handle ensuring immutable objects are only allowed to be created if they are valid is to use the Essence Pattern.
In a nutshell, the idea is that the parent class contains a static factory that creates immutable instances of itself based on instances of an inner "essence" class. The inner essence is mutable and allows objects to be built up, so you can put the pieces together as you go, and can be validated along the way as well.
The SOLID principals and good DDD is abided by since the parent immutable class is still doing only one thing, but allows others to build it up through it's "essence".
For an example of this, check out the Ldap extension to the Spring Security library.
Some observations first.
Why no generics? J2SE5.0 came out in 2004.
Current version of Java SE has Objects.requiresNonNull as standard. Bit of a mouthful and the capitalisation is wrong. Also returns the passed object so doesn't need a separate line.
this.senderAddress = requiresNonNull(senderAddress);
Your classes are not quite immutable. They are subclassable. Also they don't make a safe copy of their mutable arguments (Sets - shame there aren't immutable collection types in the Java library yet). Note, copy before validation.
this.recipientToMailAddresses = validate(new HashSet<String>(
recipientToMailAddresses
));
The use of ^ and $ in the regex is a little misleading.
If the validation varies, then there's two obvious (sane) choices:
Only do the widest variation in this class. Validate more specifically in the context it is going to be used.
Pass in the validator used and have this as a property. To be useful, client code would have to check and do something reasonable with this information, which is unlikely.
It doesn't make a lot of sense to pass the validator into the constructor and then discard it. That's making the constructor overcomplicated. Put it in a static method, if you must.
The enclosing instance should check that its argument are valid for that particular use, but should not overlap with classes ensuring that they are generally valid. Where would it end?
Although an old question but for anyone stumbling upon the subject matter, please keep it simple with POJOs (Plain Old Java Objects).
As for validations, there is no single truth because for a pure DDD you need to keep the context always in mind.
For example a user with no credit card data can and should be allowed to create an account. But credit card data is needed when checking out on some shopping basket page.
How this is beautifully solved by DDD is by moving the bits and pieces of code to the Entities and Value Objects where it naturally belong.
As a second example, if address should never be empty in the context of a domain level task, then Address value object should force this assertion inside the object instead of using asking a third party library to check if a certain value object is null or not.
Moreover Address as a standalone value object doesn't convey much at its own when compared with ShippingAddress, HomeAddress or CurrentResidentialAddress ... the ubiquitous language, in other words names convey their intent.

Categories

Resources