SOLID principles explained by Sandro Mancuso

SOLID principles

Have you ever heard SOLID principles?

SOLID stands for:

  • Single responsibility principle
  • Open/closed principle
  • Liskov substitution principle
  • Interface segregation principle
  • Dependency inversion principle

Easy to understand, easier to violate

Those principles are not difficult to understand when you initially study them, however stick to them in your daily job is not trivial at all. Let’s make an example on the first one – Single Responsibility Principle – the easiest and probably the most violated one.

Let’s imagine you have a function named calculateTotalPrice(..) and it’s long, I don’t know, let’s say 50 lines of code. Is the single responsibility principle respected?

Maybe yes, is doing one thing: calculate the total price of the cart. However when we look at the code we see something like that:

Are you still convinced the method is following Single Responsibility Principle? Clearly not.

It does five things:

  • Coordinate total price calculation by applying sequentially four operations
  • Calculate single entry price
  • Sum all entries price
  • Apply discount
  • Apply taxes

If one of those five things changes, we have to touch this method – clearly it has more than one responsibility.

It’s really easy violate them without even realising it.

“Functional is cool, but do you know OO” by Sandro Mancuso

So today we will not speak about Java 8 or Spring MVC but Objected Oriented principles.

We start by suggesting this talk by Sandro Mancuso.

 

Spring MVC @Requestparam – Binding request parameters

In this article we are going to see several examples on how to get request parameters with Spring MVC, how to bind them in different objects, how  to use @RequestParam annotation and when the annotation is not needed.

@RequestParam examples

@RequestParam is an annotation which indicates that a method parameter should be bound to a web request parameter.

1. Biding method parameter with web request parameter

Let’s say we have our /books url that requires a mandatory parameter named category:

we just need to add @RequestParam("parameterName") annotation before the method parameter that we will use for biding the web request parameter.
Let’s see an example:

In the snippet above we’ve captured value of request parameter “category” into String cat method argument and we put its value into a Model object so that we can easily test it.

In the test above we are using Spring MVC test library to perform an HTTP GET request to /books with a parameter – category – which has value “java”. Then we verify that the response status is OK (code: 200) and that the model contains an attribute named category and that its value is “java”.

For this test we’ve quickly setup a Spring Boot project, you can find the pom.xml at the end of this article.

Please note that category is considered a mandatory parameter, if we don’t pass category parameter in our call as in the test below we receive a 400: BadRequestException.

2. Request parameter match method parameter name

If both variable and request parameter name matches we don’t need to specify the parameter name in the @RequestParam annotation.

In the example above, since both variable and request parameter name is ‘category’, binding is performed automatically.

3. Auto type conversion

If the request parameter is not a String but – for example – a number we can bind it to the corresponding type. Let’s say we have a call like this:

In order to bind rate and maxprice respectively with an int and a BigDecimal, we just need to specify the target type after the annotation.

Similarly if we want to pass a date like:

We need to bind it with respective object:

Since dates have different formats, it’s necessary specify which one should be used in order to parse the value parameter correctly. In our example we’ve used @DateTimeFormat  to specify iso DateTimeFormat.ISO.DATE that is the most common ISO: yyyy-MM-dd.

All simple types such as int,long, Date, etc. are supported.

Conversion process can be configured and customized according to your needs using WebBinder or by registering Formatters

4. @RequestParam with not mandatory parameters

When we add@RequestParam annotation, as we’ve seen, by default we are assuming that request parameter is mandatory. In case we want to specify that is not, we can just add required=false.

In this case if we call just /books without parameter, we won’t receive a 400 as before. String category in this case will remain null.

5. @RequestParam with Default value 

It’s also possible specify a default value that will be applied if parameter is not sent. Let’s say our default value is “fantasy” we can add defaultValue = "fantasy" in the annotation as follow:

Let’s then perform our test in which we don’t pass category request parameter, expected value it’s gonna be “fantasy”.

When request parameter is sent, value should be, of course, the one sent and not our default.

6. @RequestParam with List or array

We can also perform a call in which we specify several values for a parameters, like:

In this case we can bind it using a List or an array – this is with a List:

and with array:

7. @RequestParam with Map

It’s also possible bind all request parameters in a Map just by adding a Map object after the annotation:

In this example we’ve added a Map<String,String>, the key is the request parameter name, so we just get the parameters from the Map using their name. I think it’s worth highlight that with this approach you can’t specify which parameters are mandatory and which not and that the code can be insidious to read, since might need to read it all in order to figure out which are the possible parameters used by this method.

In order to validate the snippet let’s perform a little test:

Note that if you have multiple values for the same parameter name, you should use MultiValueMapIn the example below we use@RequestParam with MultiValueMap<String,List<String>> so that we can store multiple values for same parameter in a List.

Let’s test it passing two authors and one category:

Examples without @RequestParam

Based on the list of HandlerMethodArgumentResolver configured in your application, @RequestParam can also be omitted. If you have a look at the code of method getDefaultArgumentResolvers() of RequestMappingHandlerAdapter there is the following piece of code at the end:

Basically it’s added to the resolvers a RequestParamMethodArgumentResolver with useDefaultResolution set to true. Looking at the documentation we can see that this means that method argument that is a simple type, as defined in BeanUtils.isSimpleProperty(java.lang.Class<?>), is treated as a request parameter even if it isn’t annotated. The request parameter name is derived from the method parameter name.

Let’s see in the next example what it means.

8. Binding without annotation

We define our controller without adding the usual @RequestParam annotation before the method argument String category. 

If we run our usual test we will see that it pass!

This happens because both variable and request parameter name is ‘category’ and in the list of default handlers we have RequestParamMethodArgumentResolver with useDefaultResolution set to true. 

Despite it might looks convenient, I prefer to always specify the annotation since it clearly states that the argument represents a request parameter. 

9. Bind with a field of an object

In a similar way if we pass as argument a simple pojo object that has a field – with getter and setter – named like the request parameter, value of the request parameter will be stored into this field.

Let’s define our pojo class:

then our Controller:

and we run our usual test, we will see that also in this case value of request parameter is correctly stored into myForm.getCategory().

pom.xml

For these test we’ve quickly setup a Spring Book project, you can find below the pom.xml.

 

Java 8 Comparator – How to sort a List

In this article we’re going to see several examples on how to sort a List in Java 8.

1. Sort a List of String alphabetically

By purpose we’ve written London with “L” in low-case to better highlight difference between Comparator.naturalOrder() that returns a Comparator that sorts by placing capital letters first and String.CASE_INSENSITIVE_ORDER that returns a case-insensitive Comparator.

Basically in Java 7 we were using Collections.sort() that was accepting a List and, eventually, a Comparator –  in Java 8 we have the new List.sort() that accepts a Comparator.

2. Sort a List of Integer

3. Sort a List by String field

Let’s suppose we’ve our Movie class and we want to sort our List “by title”. We can use Comparator.comparing() and pass a function that extracts the field to use for sorting – title – in this example.

Output will be:

As you’ve probably noticed we haven’t passed any Comparator but the List is correctly sorted. That’s because title – the extracted field – is a String and String implements Comparable interface. If you peek at Comparator.comparing() implementation you will see that it calls compareTo on the extracted key.

4. Sort a List by double field

In a similar way we can use Comparator.comparingDouble() for comparing double value. In the example we want to order our List of Movie by rating, from the highest to the lowest.

We used reversed function on the Comparator in order to invert default natural-order that is from lowest to highest. Comparator.comparingDouble() uses Double.compare() under the hood.

If you need to compare int or long you can use comparingInt() and comparingLong() respectively.

5. Sort a List with custom Comparator

In the previous examples we haven’t specified any Comparator since it wasn’t necessary but let’s see an example in which we define our own Comparator. Our Movie class has a new field – “starred” – set using the third constructor parameter. In the example we want to sort the list so that we have starred movie at the top of the List. 

Result will be:

We can, of course, use Lambda expression instead of Anonymous class as follow:

And we can also use again Comparator.comparing():

In the latest example Comparator.comparing() takes as first parameter the function to extract the key to use for sorting and a Comparator as second parameter. This Comparator uses the extracted keys for comparison, star1 and star2 are indeed boolean and represents m1.getStarred() and m2.getStarred() respectively.

6. Sort a List with chain of Comparator

In the latest example we want to have starred movie at the top and then sort by rating.

And output is:

As you’ve seen we first sort by starred and then by rating – both reversed since we want highest value and true first.

Java 8 Optional – Replace your get() calls

Optional class were introduced in order to prevent NullPointerException, but method get() used to retrieve the value inside the Optional might still throw a NoSuchElementException.

Different name, same issue?

Calling get() without checking that value is actually present it’s a bug. So we should always write something like that in order to use get().

But are Optional really meant to be used in this way? No.

Writing block of isPresent/get it’s not so different from writing a classic null check.

Let’s see how we can really benefit from Optional object.

1. Optional orElse example

It returns the value if is present, or the other specified otherwise.

Let’s see an example:

As you can see we haven’t called get() and we’ve made the code easier and more readable compared to the isPresent/get version:

 

2. Optional orElseThrow example

It returns the value if is present, or throws the specified exception otherwise.

 

3. Optional filter example

filter() is useful to specify other conditions on our object. It returns an Optional containing the value if is not empty and satisfy the specified predicate, an empty Optional otherwise.

In this example we want that the name not only is different from null but also that is not empty or made of only empty spaces.

And those are the tests for the null and the empty name:

4. Optional ifPresent example

IfPresent, that it’s different from isPresent, accept a function, a Consumer, and executes it only if the value is present.

So instead of writing something like:

You can write:

or if you prefer:

But let’s have a look to a proper example.

We define a Pojo class, useful also for the following examples, that represents a Loyalty card.

We want to add 3 points to the loyalty card if loyalty card is actually present.

Node: In the following example we’re going to use Mockito to mock LoyaltyCard class. Don’t worry if you are not familiar with Mockito, I’ll add some comments to the code.

 

5. Optional map example

map() it’s a method that we use to transform an input in a different output. In this case nothing changes except that the map operation will be executed only if the value is actually present, otherwise it returns an empty Optional.

In this example we want to retrieve the number of points of our loyalty card if we have it, otherwise number of point will return 0.

6. Optional flatMap example

flatMap() it’s really similar to map() but when output is already an Optional it doesn’t wrap it with another Optional. So instead of having Optional<Optional<T>> if will just return Optional<T>.

Let me clarify it using an example. Let’s define a new class, called Gift.

And let’s define a new method to our LoyaltyCard class that returns an Optional containing the last Gift chosen. Since we are going to mock the result of this method, we don’t really care about its implementation.

We can now create a mocked Gift with name “Biography of Guybrush Threepwood”, put it into an Optional and make getLastGift return it. So if we write:

Output will be an Optional<Optional<Gift>> that is not what we want, so flatMap will unwrap this double level and leave only an Optional<Gift>.

Writing this solution by using isPresent/get would have meant using a nested if: one for check that card was present and another of checking the gift. Harder to read, easier to fail.

7. Optional ifPresentOrElse ?

Unfortunately this is yet to come 🙂 It will be available in Java 9.

Until then we have to write something like:

There are cases in which you are allowed to use get() and isPresent() but use them with a grain of salt.

Resources:

JavaDoc

Short Tutorial By Example

Java 8 Stream – From List to Map

An example to convert a List<?> to a Map<K,V> using Java 8 Stream.

Java 8 – Collectors.toMap()

Let’s define a Pojo class:

In the first example we convert a List<Person> in a Map<String, Person> that has email as key and the object itself as value.

Output will be:

Or using lambda:

Output:

Let’s break this out

First of all we create a Stream of Person from the List<Person> defined.

Then we collect this stream in a Map. Java 8 helps us to define the needed Collector by providing us the method: Collectors.toMap().

Collectors.toMap() takes two functions – one for mapping the key and one for the value – and returns a Collector that accumulates elements into a Map.

Since we are working with Stream of Person – our input it’s an object Person.

We have chosen the email as key, so that’s function that given the input – Person – returns its email:

and then the object itself as value, so it’s just an identity function:

These are the parameters for toMap.

Another example

Given a List<Person> we want to create a Map<String, Integer> that contains the name as key and the age as value.

We just need to change the two parameters of the Collectors.toMap, by specifying:

So the code will be:

Output:

If you are a good observer you may have noticed that the order hasn’t been respected. That’s because the default implementation used by toMap is the HashMap that does not guarantee the order of the map.

 

Java 8 – Collectors.toMap with a LinkedHashMap

 

If we want to preserve the order we should use a LinkedHashMap instead of the HashMap.

Let’s try the previous example by passing a LinkedHashMap to Collectors.toMap()

Output:

We are using the definition of toMap that takes four parameters:

  • keyMapper – a mapping function to produce keys
  • valueMapper – a mapping function to produce values
  • mergeFunction – a merge function, used to resolve collisions between values associated with the same key
  • mapSupplier – a function which returns a new, empty Map into which the results will be inserted

We’ve already discussed the first two parameters.

In case of a collision we just want to throw an exception, so as third parameter we define that. In the example we used the same implementation of the static method throwingMerger defined in the java.util.stream.Collectors class.

Fourth parameter it’s the one in which we define a function that returns our LinkedHashMap.

Java 8 – Convert List to String comma separated

Convert a List<String> in a String with all the values of the List comma separated in Java 8 is really straightforward. Let’s have a look how to do that.

In Java 8:

We simply can write String.join(..), pass a delimiter and an Iterable and the new StringJoiner will do the rest:

In case we are working with a stream we can write as follow and still have the same result:

Note: you can statically import java.util.stream.Collectors.joining if you prefer just typing “joining“.

In Java 7:

For the old times’ sake, let’s have a look to Java 7 implementation.

As you can see it’s much more verbose and easier to make mistakes like forgetting to remove the last comma. You can implement this in several ways – for example by moving the logic that removes last comma inside the for-loop – but none will be so explicative and immediate to understand as the declarative solution expressed in Java 8.

Focus should be on what you want to do – joining a List of String – not on how.

 

Java 8: Manipulate String before joining

Before joining you can manipulate your String as you prefer by using map() or cutting some String out by using filter().  I’ll cover those topics in further articles. Meanwhile, this a straightforward example on how to transform the whole String in upper-case before joining them.

Java 8: From List to upper-case String comma separated

If you  want to find out more about stream, I strongly suggest this cool video of Venkat Subramaniam.

Let’s play

The best way to learn it’s playing! Copy this class with all the implementations discussed and play with that. There is already a small test for each of them 🙂

Let’s start this journey!

Ciao!

I’m Mario and I’m going to start this new adventure thanks to John Sonmez.
I’ve been following his blog for long time, but only a couple of weeks ago I’ve decided to subscribe to his free course “How To Build A Blog That Will Boost Your Career“.

I’ve never paused to properly think on how valuable it could be having a blog or works on something that’s simply yours. When I say “properly think” I mean consider finding hours to work on that, to get started, to forget about “perfection” and just jump into it. And now…here we go!

Let’s be honest!

There are hundreds of good tutorials on the web that explains you how to easily create a blog, install WordPress and get started because, apparently, that is all what you need.

So why did I choose this course?

As I said, I’ve never tried to create a blog, I’ve always thought would’ve been nice working on something that was mine, but I’ve never given the right priority to that. But then John, through his course, said:

Hey man, I know you are busy, I know you think that you aren’t a great author, I know you prefer invest your spare time on doing something else..but you know what… if you don’t try, you will always be one of the others! So let’s start, follow me and in 3 weeks you’ll have your blog up and running.” Simply as that!

In a nutshell: what is this course about?

It’s a course focused on boosting your career thanks to your blog, on helping you find a better job, have a better salary..MAKE THE DIFFERENCE and be in the top 1% of all software developers! It helps you find a theme that enhances your passions, know what to write about, get some traffic on it and keep it up. Moreover it’s a specialised course, it’s for software engineers, so it will be easy find an answer to the questions you may have..And if you can’t find an answer, drop him an email and he will answer. I promise. At least, that’s what happened to me.

That’s why, in my opinion, this tutorial is completely different from what you can find on the web. I really recommend you to subscribe and..let me know what you think about this course.

Cheers.