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.
Related
I've been reading up Java recently. So I have a enum below that acts as a map with key "JESSIE" and value "My favorite cat".
So why does anyone need to use EnumMap? Thanks
public enum Cat {
JESSIE("My favorite cat");
private String description;
Cat(String description){
this.description = description;
}
}
The enum is the key in an EnumMap, and therefore those two things are completely different. You have no way of knowing all the kinds of things you may want to associate with your cats.
The description may be an inherent part of Cat, but you might want to associate cats with their servants, or where they (currently) live or what their preferred meal (currently) is.
EnumMap<Cat, Human> catsServant;
EnumMap<Cat, House> catsHome;
EnumMap<Cat, Meal> catsFood;
Since you don't need to modify Cat to associate it with another object, it makes it a lot easier to use, and your enum would become huge if you filled it with all possible things you might want to associate your cats with.
A second issue is that enums are singletons, which means that if you were to put mutable state (strongly discouraged!) in your Cat by adding a setDescription(String) method, it will change that globally in your program. That may not matter for simple programs or a simple property like description, but it does matter when you have more complex code.
Now a more realistic example. The JDK TimeUnit enum has values such as MINUTE, and the creators couldn't have known of all the possible things that people might want to associate with them. However with an EnumMap I can provide a translation to my native language as follows:
EnumMap<TimeUnit, String> xlate = new EnumMap<>(TimeUnit.class);
xlate.put(TimeUnit.MINUTE, "Minuutti");
xlate.put(TimeUnit.SECOND, "Sekunti");
TimeUnit isn't my class, so I can't edit it to include those translations, and it would be the wrong place anyway.
A related question is why is there a special EnumMap, since you can also use a normal map, such as HashMap<Cat, Human>.
The primary reason behind this would be to design the classes in such a way that it holds the attributes that represent its entity and not which it would require a mapping with while querying.
As an example, consider another class Human as follows
#AllArgsConstructor
static class Human {
String name;
}
Now you could have looked for a Cat to its owner mapping, but how much of a sense would it make to keep the entire Human object referenced for such a mapping? Despite the fact, that you could keep such a reference, what's helpful for the purpose of query ability is to keep such a reference in an additional data structure EnumMap in this case -
EnumMap<Cat, Human> enumMap = new EnumMap<>(Cat.class);
enumMap.put(Cat.JESSIE, new Human("naman"));
enumMap.put(Cat.LUCY, new Human("user"));
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.
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.
I have a domain object Invoice that has around 60 attributes, some are mandatory and some are optional. This Invoice class is a representation of a record in the underlying DB table with certain columns values wrapped with application layer classes (like Enum for a simple integer stored in the DB, Currency for a double etc.,).
This Invoice class is currently defined as follows:
Public full-arg constructor.
Public getters.
Protected setters.
Now, it is scaring the clients of this class who create an Invoice object, to pass all 60 odd attributes to the constructor. I am adamant against making the setters public for obvious reasons.
Could you please suggest a better way to allow creation/modification of this invoice object? Please let me know if you need more details.
Using the Builder Pattern
Use the Builder Pattern that Joshua Bloch describes in his book Effective Java 2nd Edition. You can find the same example in http://www.javaspecialists.eu/archive/Issue163.html
Pay special attention to the line:
NutritionFacts locoCola = new NutritionFacts.Builder(240, 8) // Mandatory
.sodium(30) // Optional
.carbohydrate(28) // Optional
.build();
Using BeansUtils.populate
Other way is to use the method org.apache.commons.beanutils.BeanUtils.populate(Object, Map) from Apache Commons BeansUtils. In this case, you need a map to store the object's properties.
Code:
public static void main(String[] args) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("servingSize", 10);
map.put("servings", 2);
map.put("calories", 1000);
map.put("fat", 1);
// Create the object
NutritionFacts bean = new NutritionFacts();
// Populate with the map properties
BeanUtils.populate(bean, map);
System.out.println(ToStringBuilder.reflectionToString(bean,
ToStringStyle.MULTI_LINE_STYLE));
}
Output:
NutritionFacts#188d2ae[
servingSize=10
servings=2
calories=1000
fat=1
sodium=<null>
carbohydrate=<null>
]
What you could do maybe would be to decompose your object into smaller ones. As per the comments above, you might require the users to build these new objects however, depending on your database design, you might just need to pass a primary or foreign key to the class.
The class will then have some behaviour which will seek the relevant data from the database. This obviously could increase the load on your database server, but it will allow you to less complex (albeit, more in amount) classes. The reduction in complexity will most likely increase the chances of code re-usability as well as make it more maintenance friendly.
As suggeste #Jake King , it is always better to 60 attributes to composite into smaller data objects.
While doing this, I will look into one aspect, which possible combinations are optional and I will compose in that way. For example, Mailing Address is optional if Client Clicks on to say that use the Current Address and Mailing Address.
Build Constructors around these composed objects will help you manage/maintain the Class easily and effeciently.
If your Invoice Object has 60 attributes and you are sure that you wont be requiring some of them there is no need create getter and setter for those attribute.it is always recommended to create getter setter of the attributes which you required in code. but you need to make sure that the omitted field should allow null contraint in database.
else if you required all the 60 attributes in the code then create different contructor as per required by the client.if client needs to pass only 4 then create contructor accepting 4 parameters and you can set default values for attributes in the database whose values are not passed by the clients.
So there is a new guy that has started where I work. I'm quite a junior programmer myself, but I've been developing for a bit longer, so I'm using my "gut feeling" to guide us in developing a project. The blind leading the blind.
A relatively small thing just came up, and I would like to know what is the best way to create this for future reference and why.
Essentially there is a basic XML file with details for files (structure isn't really relevant). He went about querying this XML file and then storing all retrieved files by creating several lists, something like so:
List<Integer> fileId = new List<Integer>;
List<String> title = new List<String>;
And then you would create a method which would query against these Lists looking for the ID.
I pictured a method would be created to query for a file out of the XML file without storing/setting anything, like so:
public Form getFile(Integer id) {
Form ret = new Form();
//Query XML, set to ret...
return ret;
}
I wanted to use value objects, since that's how I'm used to working. So suggested and settled for this in the end:
List<Form> forms = new List<Form>;
So now, we have 2 methods, 1 to populate the 'forms' variable, and then 1 to query it and return the Form... still seems very strange to me.
Also, instead of:
Form tempForm = new Form();
tempForm.id = 1;
tempForm.title = "Foo";
He prefers to do:
Form tempForm = new Form(id, title);
Purely because it's in 1 line and looks tidier. Later down the line though, I don't think using a value object like this is the best way to go.
Maybe I am worrying and thinking about stuff to much as opposed to getting on with development, but any advice on this would be great.
On your second style question:
One of the reasons to use a constructor is that you can then make your Form object immutable as in:
public class Form {
private final String id;
private final String title;
public Form(String id, String title) {
this.id = id; this.title = title;
}
public String getTitle() { return title; }
public String getId() { return id; }
}
This helps avoid concurrency issues.
I'm not sure I understand your question properly, but at the basis, it sounds like a performance question. ie: is it worth reading in an entire XML file, and restructuring it such that it is faster and easier to query, or is it better to scan the xml file every time and query against it. That's a question that only you can answer. As usual, it's the space-speed tradeoff that you have to evaluate.
If your XML file is huge and would require significant amount of memory to cache and you only query against in sporadically, then perhaps your solution is better. If it is small and speed is critical, then caching it is a good idea.
All that being said, there are several different libraries that you can use to speed up the processing in different ways. You can look at using XQuery and/or XPath (see How to read XML using XPath in Java), JAXB, SAX, etc. Each technology has its own advantages and disadvantages.
Hopefully that will give you a little more background that you can discuss with each other.
Interresting question! There are however several questions in one. Let me answer each one of them separately.
Let me first lay down the definition of a value type as found on domaindrivendesign.org
Definition: A Value Object is an object that describes some
characteristic or attribute but carries no concept of identity.
For example a file path is a string, but it also has some restrictions on the format of the string and some operations. Here it would be a good idea to create a value object. Note also that a path carries no notation of identity. That is, two path objects representing the same path would be considered equal.
Now to the actual question, I strongly recommend your way of coding - Creating a class for data that belong together. In your first example id and title are only related by an index into two separate lists.
It's better to use this form
Form tempForm = new Form(id, title);
That way the Form class can be immutable which will give you great readability benefits and also performance gains. Also the fields of the class are encapsulated.
Now to the last thing you thought was strange - Having two methods, one for creating the list and one for querying against it.
Here I would actually create a new class, containing only those two methods instead of having them say in a static class. I would call it a FormCollection. You guys can probably come up with some smarter name since you have more context. Spend at most five minutes figuring out a meaningful name.
You could also refactor your code further to for example take the xml file path or stream as a constructor argument and then have a single method for querying aginst it on id. Like so:
class FormCollection
{
public FormCollection(String xmlFilePath) { ... }
public Form getById(int id) { ... }
}
This is probably a good interface to the rest of your application, since it easy and to the point. Also it's easy to test.