Generic parameters are a very powerful concept. But they are not easy to understand for beginners. In this article I'm going to explain them in a beginner friendly way.
The article will have the following progressions:
- Non generic class
- See limitations of non generic class
- Add generic parameter to class
- "Realworld" example
Let's start with a simple non generic class to see its limitations:
The Transformer class can hold any number of strings. You can add new strings to it by calling the 'add' method. When creating a new instance of the class, you can pass a method that transforms all strings that were previously added and returns a new list of strings that contains all transformed strings previously added. This is basically the js map method reimplemented (of course with a lot of functionality missing).
Here is a use case for our transformer class:
The method makeUpper takes a list of strings and returns a new list of strings with every element uppercased. We then create a new instance of our Transformer class and pass in the makeUpper method. We now add some strings and call the transform method. This will give us a new list of strings with all elements uppercased.
Let's have a look at another example:
This time we defined a method that adds 5 to every number in a list and returns a new list with the modified numbers. This will give us typescript errors because our Transformer class expects to work with strings.
What do we have to do to make our Transformer class work with every datatype?
A generic parameter:
You see the difference? We removed every occurrence of the type string from the class and replaced it with a so called generic type. We called the generic type T, but we could have called it whatever we want. T is a placeholder for the type that we specify when we create an instance of the class. Let's do that now:
You see that we now say that the generic type of our class instance should be of type number. Now typescript knows how to handle the generic parameter. Every occurrence of 'T' will now be an instance of type number. This time our code compiles. And it will compile for every other datatype too.
Of course this simple example is pretty much useless.
Let's have a look at an example that could be used in a real life application:
What we're trying to achieve here is creating a Repository that holds data objects and can save data objects to a database. And it has to work with any kind of data object.
First we define a class called DbConnection. It doesn't do anything and just exists to show what a real world repository could use to communicate with a real database.
The Repository class is where the 'magic' happens. But once you understood the concept, it's a pretty simple class isn't it? It creates a mocked database connection in its constructor and has a method to add new data and a method to return all data. The trick is that the class doesn't care at all about the type of the data. It stores them regardless.
Finally the MyApp class shows how to use the repository class. We create two repositories. One holds data of type Todo and the other of Type Bookmark. Now both repositories have the same functionality but only work with their respective data type. You can not accidentally add a Bookmark object to the TodoRepository. The typescript compiler will complain about it.
And that's it. We created a fully generic Repository class that can store any kind of data. Pretty cool.
A fundamental part of kissjs are so called Business Logic blocs(bloc). These are classes that contain all the business logic your app consists of and are accessible from everywhere in your application. And there are special kinds of blocs which are responsible to handle data objects. Pretty similar to our Repository example. These DataBlocs can create, read, update and delete data out of the box. They work in the same way as the repository above. When a DataBloc gets created, it gets the type of its data passed as a generic parameter and you as the developer never have to worry about passing wrong data to it.
And if you are interested in this kind of topics, I share a lot about it on twitter. So make sure to follow me there @RalliPi.