Should i validate parameters in constructor? - java

I am creating a web application following the MVC pattern.
In effective Java the author mentions to validate the parameters in the constructor of the class when creating a new object.
However i am not creating some API that will be used by third parties. My classes just accept parameters from input fields of a form which are validated before beeing submited to the server.
So in this case should i create my classes the way the author mentions in Effective java or it is useless?

It is not as clear cut as reading a book and implementing what it says. You need to think and apply the knowledge to your specific situation.
It really depends on how you are initializing the variables in your class and using them right after object construction:
Some pointers:
If the variables are going to be used by some methods in the class or the object is going to be re-used right after constructions (which in most cases will), you should validate that the values that are required are not empty or null, to avoid getting nasty exceptions.
The second time to validate input parameters is when you expect the correct values to be set to specific internal variables. If you require that a parameter be constrained to a specific value range, then it is important that you validate.
Example:
Say we have a salary cap in the object:
int salary = 0;
int salaryCap = 1000;
During creation, you can validate the passed in salary amount:
public Employee(int salary) {
if(salary >= this.salaryCap)
this.salary = salary;
}
The class relationship also determines whether you want to validate the values or not. If the parameters will be passed up the inheritance chain for-example, I would take the time to validate them, especially if they will affect the state of other objects in the inheritance chain.
Example:
Whenever I have to call the super constructor, I am tempted to validated the input:
public Employee(int salary) {
super(salary); //validate salary against known constraints
}
Where are the variables coming from? If you do not trust the source (like sql parameters etc), then you should validate them and possibly sanitize the input before executing further code. This prevents security attacks.
I am always weary to do validation and parameter checking in the constructor. I prefer to have getters and setters to validate input. That way, if something happens at object creation, at least I have the guarantee of semi-working object than a complete inconsistent object whose state cannot be readily determined. Of course this depends on your context, if you constraints are strict, you can stop the object creation and prompt the client (user, calling object etc) for valid input parameters.
The advantage that using getters/setters affords me is that the object is really constructed step by step by calling on the external interface the object gives, other than constraining the validation during creation, which when an exception occurs, renders the object unusable/unstable.
So instead of this:
public Employee(int salary) {
if(salary >= this.salaryCap)
this.salary = salary;
}
I prefer this:
public class Employee {
public void setSalary(int salary) {
if(salary >= this.salaryCap)
this.salary = salary;
}
}
The latter gives me the ability to cleanly exit with a valid exception to the caller, which will not affect object creation (I don't like throwing exceptions in the constructor).
In a nutshell, do your variable have constraints? If yes, validate those constraints before setting them to internal data properties.

I would suggest validating the data in your domain and returning a (custom) exception when fields aren't filled in correctly. This way you'll be able to implement a different UI without having to do the entire validating process again, it's best to separate this as much as possible.

At the first sight it is not necessary to validate the parameters since the validation was done before. But you should take into consideration that your class will be used in other circumstances, you cannot be sure that every time the input of your constructor is valid.

It sounds like you are validating fields which have already been previously validated.
In that case, it is just a waste of time (both writing it and in run-time). If your form (client-side javascript) have not validated the fields then it would make sense. Otherwise you can skip it.

Related

Opinions on using a domain object for a single string

I am looking for some opinions when it comes to a small design decision.
I looked for other similar questions but I couldn't find any.
So here's the situation, the database contains a table with names of cities. The application retrieves these names and uses them somewhere.
Normally when it comes to database objects I would (and I believe you should) create a domain object in which you store all the related variables.
Ex:
public class City {
private String name;
public City(String _name){
this.name = _name;
}
public String getName() {
return name;
}
}
But in this case, I think that this is unnecessarily complex since there is only a single string for each database object. So I saved the city name in a String. The main reason for this is because I think it uses less memory (although the difference is small (I think, I'm not an expert)), it also removes one class and a small number of lines from the codebase. And it saves me from typing said lines ;)
I would love to hear your thoughts on this, what you would personally do and what are potential advantages or disadvantages of both methods.
In my opinion, it is better to use a domain object because it will give you more flexibility if you decide to add some more attributes. Let's say for example you pass this value to some methods in your code, next time you want to add some attribute to your city object it will be easier because all of the methods are already getting an object and not a single string.

domain driven design depends on static methods?

I have been reading a lot online/offline about where to put validation and business rules in general for domain driven design. What I could not understand is how can an entity provides methods that does validation and business rules without resorting to static methods or having a service? This is especially important for cases where the domain object does not need to be instantiate yet, but we need to validate a value that will eventually used to set the object's attribute.
I noticed blog postings such as http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/ relies on .NET's specific extension method, which is not available in programming languages such as Java. I personally don't like static methods are they cannot be overridden and hard to test.
Is there anyway I could do this without static methods or having to instantiate an unnecessary domain object just to use its validation and business rules methods. If not, does that mean domain driven design is very dependent on static methods?
Thanks
Use ValueObjects Not Entity.
In the registration case, a UserName value object could be introduced. Create a Username object when receiving the registration. Implement validation in the constructor of the UserName.
See this question and this presentation for more detail.
Edit1:
1.How to handle cases where different validation rules applied for different context. For example: The username must not have numbers for certain type of members, but it is required for other types of members?
Maybe different factory methods could do that. like UserName.forGoldenCardMember(...) or UserName.forPlainMember(...). Or make MemberType (a hierachy maybe) to validate UserName.
Another alternative solution is use AggregateFactory(AccountFactory in this case).
2.Is constructor the only place to put the validation code? I did read online about two points of view: an object must always be valid vs. not always. Both present good arguments, but any other approach?
I prefer valid approach personally. Passing an maybe invalid value object harms encapsulabilty.
Edit2:
Require
a) validation business rule based on context(different username rules for member types)
b) keep validating all business rules even if one of them fail
Stick with Single responsibility principle by using Value Object(MemberType this case).
AggregateFactory could be introduced to ease the application layer(coarser granularity).
class AccoutFactory {
Account registerWith(Username username, MemberType type, ....) {
List<String> errors = new ArrayList<String>();
errors.addAll(type.listErrorsWith(username));
errors.add(//other error report...
if (CollectionUtils.isEmpty(errors)) {
return new Account(username,....);
} else {
throw new CannotRegisterAccountException(errors);
}
}
}
Edit3:
For questions in the comments
a) Shouldn't the Username object be the one that has a method that returns the error like
the listErrorsWith()? After all, it is the username that has different rules for different member type?
We could check this question from another perspective: MemberTypes have different rules for username. This may replace if/else block in the Username.listErrosWith(String, MemeberType) with polymorphism;
b) If we have the method in the MemberType, the knowledge will not be encapsulated in the Username.Also, we are talking about making sure Username is always valid.
We could define the validity of Username without MemberType rules. Let’s say "hippoom#stackoverflow.com" is a valid username, it is a good candidate for GoldenCard member but not good for SilverCard member.
c) I still can't see how performing validation that returns a list of errors without getting the list from exception thrown by the constructor or static method. Both does not look ideal IMHO.
Yes, the signature of listErrorsWith():List looks weired, I'd rather use validate(username) with no returning value(throw exception when fails). But this will force the cilent to catch every validation step to run validations all at once.
If you decided to use DDD in your application you need to build more complex solution. I agree with #Hippoom, you shouldn't use Entity for this purpose.
I would suggest this solution:
DTO -> Service Layer (ValidationService -> Converter) -> Persistence Layer (Repository)
Some explanation:
When you received DTO from client side with all necessary parameters, you should validate it in you service layer (e.g. Use another service like ValidationService) which can throw exception if something wrong. If all Ok, you can create Entity from your DTO in Converter and persist it in Repository.
If you want flexible solution for ValidationService I'd suggest Drools

What goes into Spring Security's ACL_OBJECT_IDENTITY table?

I'm attempting to integrate Spring Security with ACL support into an existing GWT application, and if I click another unhelpful link I swear will need a new mouse and keyboard. I've worked through what will be needed to use Spring to authenticate against Active Directory via LDAP, and I've worked out how we can assign custom permissions based on AD attributes (i.e. group membership), and I've even worked out how to perform a custom check against permissions (a true bitmask operation) using a custom ACL schema. What I haven't figured out is just what goes into the ACL tables.
ACL_SID
id:bigint (pk)
principal:boolean (ak)
sid:varchar (ak)
This table is pretty self-explanatory; we'll be using non-principal entries here only.
ACL_CLASS
id:bigint (pk)
class:varchar (ak)
This table is also pretty self-explanatory. As I understand it, we simply create an entry for every class/interface we wish to secure.
ACL_ENTRY
id:bigint (pk)
acl_object_identity:bigint (fak)
ace_order:int (ak)
sid:bigint (fk)
mask:bigint
granting:boolean
audit_success:boolean
audit_failure:boolean
This table is also mostly self-explanatory; we've customized the schema with a bigint/long in the mask field, but the question stems from just what acl_object_identity is referencing. Obviously, it points to the field in ACL_OBJECT_IDENTITY, but...
ACL_OBJECT_IDENTITY
id:bigint (pk)
object_id_class:bigint (fak)
object_id_identity:bigint (ak)
parent_object_identity:bigint (fk)
owner_sid:bigint (fk)
entries_inheriting:boolean
The object_id_identity is, what? A method? How is it referenced by way of Spring Security's annotations?
MyClass.java
#PreAuthorize("hasPermission(#someInput, 'READ')")
public boolean myMethod(String someInput) {
return true;
}
Presumably, #someInput refers somehow to the ACL_OBJECT_IDENTITY.object_id_identity field, but how?
First you need some kind of domain object class to store your data. This class must have a getId() method. For example:
public class DomainObject {
private Long id;
private String data;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
Change your secured method to:
#PreAuthorize("hasPermission(#someInput, 'READ')")
public boolean myMethod(DomainObject someInput) {
return true;
}
Now, someInput.getId() is the same as ACL_OBJECT_IDENTITY.object_id_identity.
have a look at the Grails Spring Security ACL Plugin Documentation.
It explains the domain classes used for the specific plugin, but it might help you. Look for AclObjectIdentity and AbstractAclObjectIdentity.
The ACL_OBJECT_IDENTITY.object_id_identity field is the instance id and uniquely identify the instance (together with object_id_class)
In your example, 'someInput' would be that instance.
this piece of code is taken from the beforementioned documentation:
#PreAuthorize("hasPermission(#report, delete) or hasPermission(#report, admin)")
void deleteReport(Report report) {
report.delete()
}
It explains itself immo. The report is deleted if the currently authenticated user has permission 'admin' or 'delete' for the given Report instance. Report is someInput in your code snippet.
Hope this helps.
The question seems to suggest a slight misunderstanding of Spring ACL. In the question, we are asked how to register an ACL for a String object, so that this method protection will work:
#PreAuthorize("hasPermission(#someInput, 'READ')")
public boolean myMethod(String someInput) {
return true;
}
As mentioned in this answer, it doesn't really make sense to protect a String object. When you think about it, this makes sense. Loosely speaking, we can divide all objects into two categories:
Objects that are persisted to the DB - let's call them entities
Objects that are not persisted to the DB - let's call them transients
In any real-life use case I can think of, it only makes sense to protect access to an entity, not a transient; I'll argue for this case in general later. To start with though, let's stick with a use case related to that of the question to see why protection of a transient probably isn't what's desired in this case.
Use Case
It's not 100% clear what the use case is in the question e.g. what someInput represents. But I'm assuming the use case is similar to the following. Suppose there are BankAccount entities and some operation on those entities e.g. readAccount. Only users who have read access to a BankAccount should be allowed to call readAccount. Now, BankAccount entities may be uniquely identifiable by their accountNumber, which is of type String. So we may be mistakenly led to try something like this, which is similar to the code in the question:
#PreAuthorize("hasPermission(#accountNumber, 'READ')")
public Account readAccount(String accountNumber) {
//CODE THAT RETRIEVES THE ENTITY FROM THE DB AND RETURNS IT
}
OK, it's not a bad assumption to make. I suppose the idea in our minds at this stage is that Spring ACL stores a table of account numbers, and for each account number, a list of people who have READ access to it. The problem is, Spring ACL doesn't work like that. As mentioned in this answer, Spring ACL identifies an objects in the following way:
What is the class of the object? In this case, it would be java.lang.String
What is the ID of the object? In this case, Spring ACL requires that the object needs a getId() method. Luckily, if you're using Hibernate, all your entities will have this by default, so you don't need to do anything extra to implement it. But what about String? Well, this doesn't have a getId() method. So Spring ACL won't be able to register an ACL for it and you won't be able to set up any permissions for Strings.
When you think about it, it actually makes sense that Spring ACL is designed this way. The getId() method allows us to associate the persisted ACL permissions entries with the persisted entities. This is the typical use case. So in the above example, what we're really trying to do is restrict access to Account objects, not account numbers. In that case, we have two options: preauthorize or postuathorize.
With pre-authorize, we'd need the fully-qualified path to the Account class. So let's say it's in the package X.Y, we'd have:
#PreAuthorize("hasPermission(#accountId, 'X.Y.Account', 'READ')")
public Account readAccount(Long accountId) {
//CODE THAT RETRIEVES THE ENTITY FROM THE DB AND RETURNS IT
}
Notice that in the above, we are using the ID, not the account number, to identify the account. This is the only way you are allowed identify an entity with Spring ACL, because the getId() is the link between the ACLs and their associated objects. Of course, you're free to write whatever code you like to retrieve the object by the given ID e.g. you could do something silly like increment the ID before retrieving it. So the object returned isn't guaranteed to be the same one that's authorized in this case: that's up to you to write the correct retrieval code.
The other way we can protect the method is with post authorize, as follows:
#PostAuthorize("hasPermission(returnObject, 'READ')")
public Account readAccount(String accountNumber) {
//CODE THAT RETRIEVES THE ENTITY FROM THE DB AND RETURNS IT
}
In this case, the code that retrieves the account entity is actually called, and then only after it's retrieved, the account, which is the object returned, is checked by the ACL framework against the current user and the READ permission. An advantage here is that we can retrieve the account any way we like e.g. by accountNumber in this case. Another advantage is that the object that's authorized is guaranteed to be the same as the one returned. The disadvantage is that we have to actually do the retrieval before we can make the call as to whether the user has permission or not. And if they don't have permission, then the retrieved object is effectively thrown away and so it may be a bit less performant than #PreAuthorize if the retrieval code is expensive to run.
Why Protecting Strings with Spring ACL Doesn't Make Sense Anyway
Technically speaking, I suppose you might be able to protect Strings, or indeed any other transient as long as it has a getId() method. With Strings, we could maybe add an extension function getId() for example. But I can't think of a practical use case for why we'd want to do that. For example, imagine we not only have Account objects but we also have Customer objects. And let's say Customer objects are uniquely identifiable by a customerNumber field, which is a String. And suppose we want to restrict access to customers in a similar way to accounts. Then what if coincidentally a customerNumber matched an accountNumber? In Spring ACL, we are only allowed one entry in the object identity table for every combination of object class plus ID, as per the Spring docs:
CONSTRAINT uk_acl_object_identity UNIQUE (object_id_class, object_id_identity)
So, suppose the String "fadfads389" happens to be both a customerNumber for some Customer and an accountNumber for some Account. If we were to restrict access to it via Spring ACL, what would that mean? Would it mean that a user has access to the account? The customer? Both?
Hopefully this example demonstrates why it doesn't really make sense to protect some transient class such as String with Spring ACL when that transient is used to identify entities: when we're interested in protecting entities we just protect the entities themselves, using the implicit ID of those entities e.g. the ID stored by Hibernate.
Transients Could Still be protected
Of course, there's nothing stopping you from adding object identity entries into the Spring ACL acl_object_identity table for any class you want, as long as that class has a getId() method. So it is certainly possible for you to add permissions relating to transients, and should those transients appear again in memory then Spring ACL will kick in. But this isn't really what Spring ACL was designed for - it's really meant to protect entities, not transients, which are linked to the ACL logic by getId().
Strings Could Still be Used in PreAuthorize
Now, although we shouldn't really use Spring ACL to protect Strings, that's not to say that #PreAuthorize is completely off the table when it comes to Strings. We note that #PreAuthorize can handle any SpEL expression, the same for #PostAuthorize and the other method annotations as pointed out here. So, for example, you would be able to do something like this:
#PreAuthorize("#user.accountNumbers.contains(#accountNumber)")
public Account readAccount(String accountNumber, User user) {
//CODE THAT RETRIEVES THE ENTITY FROM THE DB AND RETURNS IT
}
The above assumes that the User class maintains a list of account numbers to which that user has access, so presumably a User is an entity, or at least is backed by some DB-persisted data.
However, beware if you do want to go down this path. Not only do you risk entangling your access control logic with the rest of your business logic, you also might lose out on the performance front; Spring ACL uses caching to make permissions lookups fast whereas the above code presumably needs to fetch User data from the DB in order to do the authorization.

How to handle a lot of validation checks necessary before creating a object?

I have a class which models FK relationship. It has 2 lists in it. These lists contains the column names of the Parent Table & the Child Table respectively. These lists are passes by the client to me. Now before creating my FK object, I think it is necessary to do following checks (in order):
Check if lists are not null.
Check if lists contains null.
If a list contains duplicates columns?
Size of both the lists are equal.
So you can see there will be total 7 checks. Is it OK to have so many checks?
If it is OK to have these many checks, is there any pattern to handle such cases (with high no. of validation checks)?
If it is not OK, then what should I do? Should I just document these conditions as part of contract & mention that API will produce nonsensical results if this contract is violated?
Edit : Basically, I am trying to takes these 2 lists & produce a Database specific Query. So, it is kind of important to have this object built correctly.
Like everybody says, it depends on you. There is no such fixed/standard guideline for this. But to make it simple, you must have to put all your validation logic in one place, so that it remains readable and easy to change.
A suggestion can be, as you said, all of your validation logic seems to be very business oriented..by which I mean the end user should not be bothered about your db configuration. Let assume your class name, FKEntity. So if you follow the entity concept then you can put the validation logic in FKEntity.validate() (implementing an interface Validatable) which will validate the particular entity...this is for those kind of validation logic which applies to all FKEntity type objects in same way. And if you need any validation logic that compares/process different FKEntity depending on each other (e.g. if there is one FKEntity with some value "x" then no other entity can have "x" as their values, if they do, then you can not allow the entire entity list to persist), then you can put the logic in your Service layer.
Inteface Validatable { void validate() throws InvalidEntityException; }
Class FKEntity implements Validatable {
//..
public void validate() throws InvalidEntityException {
//your entity specific logic
}
}
Class FKDigestService {
public digestEntities() {
try {
for(FKEntity e : entityList)
e.validate();
//your collective validation logic goes here
} catch (EntityValidationException e) {//do whatever you want}
}
}
This will give you two advantages,
Your entity specific validation logic is kept in a single place (try to think most of the logic as entity specific logic)
Your collective logic is separated from entity logic, as you can not put these logic in your entity since these logic is only applicable when there is a collection of FKEntity, but not for single entity...it is business logic, not validation logic
I depends on you. There is no real argument against many checks. If your are developing an API, this can be very useful for other programmers. And it will make your own program more reliable.
I think the important point is, that you do your checks at one single point. You must have a clean and simple interface for your API. In this interface, it is ok to make checks. After these checks you could be sure that everything works.
What happens if you leaf the checks away? Will an exception be thrown somewhere or will the program just do something? If the program will just work and do something unpredictable, you should provide checks or things will begin to get strange. But if an exception will be thrown anyway, (I think) you can leaf the checks away. I mean, the program will get an exception anyway.
This is complex problem, so solution should be simplest possible to do not make it even more complicated and less understandable.
My approach would be:
some public method wrapping private method named something like doAllNeededListsValidationInFixedOrder() in which I'd create another private methods - each for every needed validation.
And ofc writing method like doAllNeededListsValidationInFixedOrder should be follow by some solid javadoc, even though it's not public.
If you want to go for pattern - the solution wouldn't be so straightforward. Basic thing to require checks in given order is to create lots or classes - every one for state telling that object is after one check, before another.
So you can achieve this with State pattern - treating every check as new state of object.
OR
You can use something like Builder pattern with forced order of methods invoked to create object. It is basically using a lot of interfaces to have every single (building) method (here validating) fired from different interface, to control order of them.
Going back to begining - using simple, well documenented and properly named method, that hides validating methods set, seems better for me.
If it is OK to have these many checks, is there any pattern to handle such cases (with high no. of validation checks)?
These checks become trivial if tackled from a data conversion point of view.
List from a client is actually any list of any possible elements
List from a client is to be converted to a well defined list of not duplicating not null elements
This conversion can be decomposed into several simple conversions ToNonNull, ToNonNullList, ToNonDuplicatingList
The last requirement is essentially conversion from two lists to one list of pairs ToPairs(ListA, ListB)
Put together it becomes:
ParentTableColumns = List1FromClient.
ToNonNull.
ToNonNullList.
ToNonDuplicatingList
ChildTableColumns = List2FromClient.
ToNonNull.
ToNonNullList.
ToNonDuplicatingList
ParentChildColumnPairs = List.
ToPairs(ParentTableColumns, ChildTableColumns)
If data from client is valid then all conversions succeed and valid result is obtained.
If data from client is invalid then one of the conversions fails and produces an error message.

JavaWorld on OO: Getters/Setters vs Builder

Background:
I found this article on JavaWorld, where Allen Holub explains an alternative to Getters/Setters that maintains the principle that the implementation of an object should be hidden (his example code can also be found below).
It is explained that the classes Name/EmployeeId/Money should have a constructor taking a single string - the reasoning is that if you type it as an int, and later need to change it to a long, you will have to modify all the uses of the class, and with this pattern you don't have to.
Question 1:
I was wondering: doesn't this simply move the problem to the parsing of the String parameters being tossed about? For example, if all the code using the EmployeeId (received from the Exporter) parses the String into an int, and suddenly you start exporting long values, you need to modify exactly as many uses... and if you start out parsing it as a long it might well have to change to a double (even though that makes no sense for id's)... and if you can't be sure what to parse the String into, you can't implement anything.
Question 2:
Besides this question, I have another: I realise that the article is over seven years old, so could anyone point me to some recent overviews concerning OO-design, and specifically to ideas concerning the getter/setter and implementation hiding debate?
Listing 1. Employee: The Builder Context
public class Employee
{ private Name name;
private EmployeeId id;
private Money salary;
public interface Exporter
{ void addName ( String name );
void addID ( String id );
void addSalary ( String salary );
}
public interface Importer
{ String provideName();
String provideID();
String provideSalary();
void open();
void close();
}
public Employee( Importer builder )
{ builder.open();
this.name = new Name ( builder.provideName() );
this.id = new EmployeeId( builder.provideID() );
this.salary = new Money ( builder.provideSalary(),
new Locale("en", "US") );
builder.close();
}
public void export( Exporter builder )
{ builder.addName ( name.toString() );
builder.addID ( id.toString() );
builder.addSalary( salary.toString() );
}
//...
}
Question 1:
String parsing seems strange. IMHO you can only do so much to anticipate future enhancements. Either you use a long parameter right from the start to be sure, or consider adding additional constructors later. Alternatively you can introduce an extensible parameter class. See below.
Question 2:
There are several scenarios in which the builder pattern can be useful.
Complex Object creation
When you are dealing with very complex object that have lots of properties
that you would preferably only set once at object creation, doing this with
regular constructors can become hard to read, because the constructor will
have a long list of parameters. Publishing this as an API is not good style
because everyone will have to read the documentation carefully and make sure
they do not confuse parameters.
Instead when you offer a builder, only you have to cope with the (private)
constructor taking all the arguments, but the consumers of your class can
use much more readable individual methods.
Setters are not the same thing, because they would allow you to change object
properties after its creation.
Extensible API
When you only publish a multi-parameter constructor for your class and later
decide you need to add a new (optional) property (say in a later version of your software)
you have to create a second constructor that is identical to the first one, but
takes one more parameter. Otherwise - if you were to just add it to the existing
constructor - you would break compatibility with existing code.
With a builder, you simply add a new method for the new property, with all existing
code still being compatible.
Immutability
Software development is strongly trending towards parallel execution of
multiple threads. In such scenarios it is best to use objects that cannot
be modified after they have been created (immutable objects), because these
cannot cause problems with concurrent updates from multiple threads. This is
why setters are not an option.
Now, if you want to avoid the problems of the multi-parameter public constructors,
that leaves builders as a very convenient alternative.
Readability ("Fluent API")
Builder based APIs can be very easy to read, if the methods of the builder are
named cleverly, you can come out with code that reads almost like English sentences.
In general, builders are a useful pattern, and depending on the language you are using, they are either really easy to use (e. g. Groovy) or a little more tedious (e. g. in Java) for the provider of an API. For the consumers, however, they can be just as easy.
There are many problems with constructors that take arguments (for example, you can't build the object in several steps). Also if you need lots of arguments, you will eventually get confused about parameter order.
The latest idea is to use a "fluent interface". It works with setters that return this. Often, set is omitted from the method name. Now you can write:
User user = new User()
.firstName( "John" )
.familyName( "Doe" )
.address( address1 )
.address( address2 )
;
This has several advantages:
It's very readable.
You can change the order of parameters without breaking anything
It can handle single-value and multi-value arguments (address).
The major drawback is that you don't know anymore when the instance is "ready" to be used.
The solution is to have many unit tests or specifically add an "init()" or "done()" method which does all the checks and sets a flag "this instance is properly initialized".
Another solution is a factory which creates the actual instance in a build() method which must be the last in the chain:
User user = new UserFactory()
.firstName( "John" )
.familyName( "Doe" )
.address( address1 )
.address( address2 )
.build()
;
Modern languages like Groovy turn this into a language feature:
User user = new User( firstName: 'John', familyName: 'Doe',
address: [ address1, address2 ] )
You can implement Builders is a more concise manner. ;) I have often found writing Builders by hand tedious and error prone.
It can work well if you have a data model which generates your Data Value objects and their Builders (and marshallers). In that case I believe using Builders is worth it.
When you require a constructor (consider factories in a similar way) for an object, you force the code using your object to pass the essential requirements to the constructor. The more explicit the better.
You can leave the optional fields to be set later (injected) using a setter.

Categories