Represent email, telephonenumber and id's as POJO's instead of Strings - java

I have a typical business web application where the domain contains entities like accounts and users. My backend is Java, so they're represented by POJO's. During an early iteration, every attribute of those POJO's were just strings. This made sense because the html input was a string, and the way the data is persisted in the DB is also similar to a string.
Recently, we've been working on validating this kind of input and I found it helps if I switch over to an object notation for this kind attributes. For example, a TelephoneNumber class consists of:
(int) country calling code
(string) rest of number
(static char) the character to prefix the country calling code (in our case this is a +)
(static pattern) regular expression to match if phonenumber is sensical
methods to compare and validate telephone numbers.
This class has advantages and disadvantages:
not good: Additional object creation and conversion between string/object
good: OOP and all logic regarding telephone numbers is bundled in one class (high cohesion),
good: whenever a telephone number is needed as an argument for a method or constructor, java's strict typing makes it very clear we're not just dealing with a random string.
Compare the possible confusing double strings:
public User(String name, String telephoneNumber)
vs the clean OOP way:
public User(String name, TelephoneNumber telephoneNumber)
I think in this case the advantages outweight the disadvantges. My concern is now for the following two attributes:
-id's (like b3e99627-9754-4276-a527-0e9fb49d15bb)
-e-mailadresses
This "objects" are really just a single string. It seems overkill to turn them into objects. Especially the user.getMail.getMailString() kind of methods really bother me because I know the mailString is the only attribute of mail. However, if I don't turn them into an object, I lose some of the advantages.
So my question is: How do you deal with this concepts in a web application? Are there best practices or other concerns to take into account?

If you use Strings for everything you are essentially giving up type safety, and you have to "type check" with validation in any class or method where the string is used. Inevitably this validation code gets duplicated and makes other classes bloated, confusing, and potentially inconsistent because the validation isn't the same in all places. You can never really be sure what the string holds, so debugging becomes more difficult, maintenance gets ugly, and ultimately it wastes lots of developer time. Given the power of modern processors, you shouldn't worry about the performance cost of using lots of objects because it's not worth sacrificing programmer productivity (in most cases).
One other thing that I have found is that string variables tend to be more easily abused by future programmers who need to make a "quick fix", so they'll set new values for convenience just where they need them, instead of extending a type and making it clear what's going on.
My recommendation is to use meaningful types everywhere possible.
Maximizing the benefit of typing leads to the idea of "tiny types", which you can read about here: http://darrenhobbs.com/2007/04/11/tiny-types/
Essentially it means you make classes to represent everything. In your example with the User class, that would mean you would also make a Name class to represent the name. Inside that class you might also have two more classes, FirstName and LastName. This adds clarity to your code, and maximizes the number of logical errors the compiler stops you from making. In most cases you would never use a first name where you want a last name and vice versa.

One of the biggest advantages of objects is the fact that they can have methods. For example, all your data object (phone number, address, email etc.) can implement the same interface IValidatable with validate method, which does the obvious. In this case, it would make sense to wrap email in an object as well, since we do want to validate emails. Regarding ID - assuming it's assigned internally by your app, you probably don't need to wrap it.

Related

DDD vs Clean Code - function parameter number

I'm trying to get my coding a little more into DDD aproach. Suppose I have a method, like a static constructor:
public class Enrollment {
private final User user;
private final EnrollmentStatus status;
private final ClassesParams classesParams;
public static Enrollment of(User user, EnrollmentStatus status, ClassesParams classesParams) {
// implementation goes here
}
}
Robert Martin says in his Clean Code book, that the less parameters function has the better, and 3 should be used in some exceptional cases. And I think it's perfectly reasonable in the above case to have just 1 parameter, because all these arguments are actually parts of some input data to create new Enrollment:
public static Enrollment of(NewEnrollmentRequest request) { // NewEnrollmentRequest would contain user, status and classesParams
// implementation goes here
}
The problem now is that NewEnrollmentRequest would be in fact some form of DTO, which is not part of the domain. And I guess I'm not supposed to put NewEnrollmentRequest outside the domain, because domain shouldn't depend on outside layers.
So the question is, how can I keep it both clean and DDD-style? Is it fine to have the constructor with all the fields - but what if I have not 3 but 6-7 fields? Or maybe the request class is part of the domain in this case? I feel there is some sort of tradeoff here, but I can't find it, or I'm just tackling the problem wrongly.
So the question is, how can I keep it both clean and DDD-style?
Create your domain interfaces in a way that conforms to the clean style
Including value objects with fluent interfaces that make clear to the programmer the semantics of the information that is being passed to the domain model. (In other words, having representations of documents, like an enrollment form, in your domain model is normal).
expect that you'll need to have a parser that copies information from the representations of the presentation layer to the representations of the domain model. Sometimes you will be able to leverage general purpose code that copies information from one information to another (like web server libraries that translate application/x-www-form-urlencoded byte sequences into sequences of key value pairs, or takes an application/json byte sequence and initializes your value object), but you should recognize that as a happy accident that may not hold for the life of the project.
Don't sweat the argument count constraint too much - Robert Martin's 2009 essay doesn't support his conclusion very well.
Instead, pay attention to the communication of argument semantics, and the fact that the arguments (a) have different lifespans and (b) those lifespans tend to "clump" into groups that are candidates for re-use.

How to selectively filter based on various paramters value

I work for an investment bank and we need to deal with Market and Instruments. So in my programming question I will be using those words to make the question more clear.
I have been trying to build an interface and its implementation of ReferenceData whose tasks are:
getAllInstruments()
getAllInstrumentsForAMarket(final String market)
getInstrumentsFromAllMarketOfAnISIN(final String isin)
getInstrumentFromAMarketAndISIN(final String market, final String isin)
Including above there will be other combination of parameters and will involve other parameters like instrument type (Bond, future etc.).
The above design will lead to make a parameter combination as and when new type of query parameter is taken into account in future which is I believe a bad design.
I followed up with Interpreter pattern as discussed by Joshua Kerievsky's Refactoring To Patterns but I am stuck with two problems:
How to deal with null values in the parameters, like somebody might be using method getInstrumentFromAMarketAndISIN(final String market, final String isin) and passing null value in market.
It is to be considered as a valid query which should then be a case of getInstrumentsFromAllMarketOfAnISIN(final String isin).
I do not want to have the client deal with if else checks of parameters and then call the methods, because these are utility methods and will be called from plenty of places, which will lead to null checks all over the client code everywhere.
Instead the implementation of ReferenceData should be able to handle it.
Thanks in advance.

Programming practice for defining string constants in Java

My perception for defining string constants in Java is that one should define a string constant, when the same string is used at multiple places. This help in reducing typo errors, reduce the effort for future changes to the string etc.
But how about string that are used at a single place. Should we declare string constant even in that case.
For eg. Logging Some counter (random example).
CounterLogger.addCounter("Method.Requested" , 1)
Is there an advantage of declaring constant rather than using raw string?
Does the compiler does any optimization?
Declaring constants can improve your code because they can be more descriptive. In your example
CounterLogger.addCounter("Method.Requested" , 1)
The method parameter "Method.Requested" is quite self describing but the 1 is not making this a constant would make this example more readable.
CounterLogger.addCounter("Method.Requested" , INITIAL_VALUE)
The way I see it, Strings can be used in one of two ways:
As properties / keys / enumerations - or in other words, as an internal representation of another Objects/states of your application, where one code component writes them, and another one reads them.
In UI - for GUI / console / logging display purposes.
I Think it's easy to see how in both cases it's important to avoid hard-coding.
The first kind of strings must (if possible) be stored as constants and exposed to whichever program component that might use them for input/output.
Displayed Strings (like in your Logger case) are strings that you might change somewhere in the future. Having them all stored as static final fields in a constants-dedicated class can make later modifications much easier, and help avoid duplicates of similar massages.
Regarding the optimization question - as others have already answered, I believe there's no significant difference.
Presumably, you'll want to write a unit test for whichever method contains that line of code. That unit test will need access to that String value. If you don't use a constant, you'll have the String repeated twice, and if you have to change it in the future, you'll have to change it in both places.
So best to use a constant, even though the compiler is not going to do any helpful optimisations.
In my view in your case is fine. If you cant see any advantage in declaring it as a constant dont do it. To support this point take a look at Spring JdbcTemplate (I have no doubt that Spring code is a good example to follow) it is full of String literals like these
Assert.notNull(psc, "PreparedStatementCreator must not be null");
Assert.notNull(action, "Callback object must not be null");
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
but only two constants
private static final String RETURN_RESULT_SET_PREFIX = "#result-set-";
private static final String RETURN_UPDATE_COUNT_PREFIX = "#update-count-";
Iterestingly, this line
Assert.notNull(sql, "SQL must not be null");
repeats 5 times in the code nevertheless the authors refused to make it a constant

Java toString for debugging or actual logical use

This might be a very basic question, apologies if this was already asked.
Should toString() in Java be used for actual program logic or is it only for debugging/human reading only. My basic question is should be using toString() or write a different method called asString() when I need to use the string representation in the actual program flow.
The reason I ask is I have a bunch of classes in a web service that rely on a toString() to work correctly, in my opinion something like asString() would have been safer.
Thanks
Except for a few specific cases, the toString should be used for debugging, not for the production flow of data.
The method has several limitations which make it less suitable for use in production data flow:
Taking no parameters, the method does not let you easily alter the string representation in response to the environment. In particular, it is difficult to format the string in a way that is sensitive to the current locale.
Being part of the java.Object class, this method is commonly overridden by subclasses. This may be harmful in situations when you depend on the particular representation, because the writers of the subclass may have no idea of your restrictions.
The obvious exceptions to this rule are toString methods of the StringBuilder and the StringBuffer classes, because these two methods simply make an immutable string from the mutable content of the corresponding object.
It is not just for debugging/human reading only, it really depends on the context in which the object is being used. For example, if you have a table which is displaying some object X, then you may want the table to display a readable textual representation of X in which case you would usually implement the toString() method. This of course is a basic example but there are many uses in which case implementing toString() would be a good idea.

Why is using a class as a struct bad practice in Java?

We recently had a code review . One of my classes was used so that I could return/pass more than one type of data from/to methods . The only methods that the class had were getters/setters . One of the team's members ( whose opinion I respect ) said that having a class like that is bad practice ( and not very OOP ) . Why is that ?
There's an argument that classes should either be "data structures" (i.e., focus on storing data with no functionality) or "functionality oriented" (i.e., focus on performing certain actions while storing minimal state). If you follow that argument (which makes sense but isn't always easy to do) then there is nothing necessarily wrong with that.
In fact, one would argue that beans and entity beans are essentially that - data containers with getters and setters.
I have seen certain sources (e.g., the book "clean code") arguing that one should avoid methods with multiple parameters and instead pass them as a single object with getters and setters. This is also closer to the "smalltalk model" of named parameters where order does not matter.
So I think that when used appropriately, your design makes sense.
Note that there are two separate issues here.
Is a "struct-like" class sensible?
Is creating a class to return multiple values from a method sensible?
Struct-like classes
An object class should -- for the most part -- represent a class of real-world objects. A passive, struct-like java bean (all getters and setters) may represent a real-world thing.
However, most real-world things have rules, constraints, behaviors, and basic verbs in which they engage. A struct-like class is rarely a good match for a real-world thing, it's usually some technical thing. That makes it less than ideal OO design.
Multiple returns from a method
While Python has this, Java doesn't. Multiple return values isn't an OO question, per se. It's a question of working through the language limitations.
Multiple return values may mean that an object has changed state. Perhaps one method changes the state and some group of getters return the values stemming from this state change.
To be honest, it sounds fine to me. What alternative did the reviewer suggest?
Following OOP "best practices" and all is fine, but you've got to be pragmatic and actually get the job done.
Using Value Objects like this (OO speak for 'struct') is a perfectly legitimate approach in some cases.
In general, you'll want to isolate the knowledge needed to operate upon a class into the class itself. If you have a class like this, either it is used in multiple places, and thus can take on some of the functionality in both of those places, or it is in a single place, and should be an inner class. If it is used in multiple ways, but in completely different ways, such that there is no shared functionality, having it be a single class is misleading, indicating a shared functionality where there is none.
However, there are often specific reasons for where these general rules may or may not apply, so it depends on what your class was supposed to represent.
I think he might be confusing "not very OOP" for bad practice. I think he expected you to provide several methods that would each return 1 value that was needed (as you will have to use them in your new class anyway that isn't too bad).
Note that in this case you probably shouldn't use getters/setters, just make the data public. No this is "not very OOP" but is the right way to do it.
Maybe Josh Bloch offers some insight into this here.

Categories