To tackle the problem, first we need to understand its root cause: How can we fix the NPE without adding unnecessary complexity to the code, keeping it simple and focused solely on the business requirements? The right Option for the right semantic The NPE is fixed, but now a simple and elegant one-line function has 7 lines and a higher cyclomatic complexity, mostly because of the checks against null values, a lot of noise! Suppose that both can return null, so what should we do? You can say: we should handle the possibilities of null! Our interface is violating the Principle of Least Astonishment because it doesn’t make this kind of situation explicit, so in theory, “anything could happen”. And accessing null will lead us to the tragic NullPointerException(NPE). On the other hand, one or both can return null.Maybe findUser returns an “empty” User and getRoles returns an empty collection of Roles, which is the best case.As we, unfortunately, use it in cases where we can’t return what the user expects, instead we need to represent the missing value somehow to make the code compile.īut, think about the printRolesFromUser’s perspective, by inspecting the used API, that is the called functions’ signatures, it can’t know what they return to represent the absence of a value. However, if we didn’t find a user, what will findUser return? And if the user doesn’t have any role, what will getRoles return? We need to model these scenarios in our code, but how? The common and not so good solution is to express this absence of value by using null, which is the default value for references, we can think of it as a reference to nowhere or an empty box. Everything went fine, it’s the “happy path”. If you answered “yes” for one or both of the above questions, then this solution is wrong! Why?įor the normal scenario, findUser will return a user, then getRoles will return its roles that will be printed by printRolesFromUser. Is it allowed to have a user without any role?.Is it allowed to call findUser with a name that doesn’t have a corresponding user?.See how efficiently flatMap has done it for us, we can also do the same thing using method flatten, similarly we can also use flatMap operation wherever we flatten nested Options wrappers to flatten the structure as per our needs.What do you think? Is it right? The answer is: it depends! What? :S So if we look at the signatures of map() and flatMap() methods in class Option they look like this: Now let’ s first look the above operations help us dealing with Option, So let’s get started with moving toward Options. In my previous blog, map and flatMap in Scala for collections we had a quite basic but yet effective understanding how map() and flatMap() works with collections in scala, keeping in contrast with my last blog, one may find it pretty weird like the methods that works on collections can also work on Futures and Options too, but we will look how these methods put us at ease while handling Futures and Options. In this blog, we would be looking at how map() and flatMap() operations work with Option and Future of scala, literally speaking both Futures and Options are very effective features of scala, A Future lets us have a value from some task on a differnt thread and Option provides us a hand from null of java as using null in scala is seen a very bad approach in functional programming.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |