Class properties can be delegated to a Map or MutableMap instance, which contains keys of the String type and values of the Any type. The map's keys correspond to the names of the class properties and the map's values associated with them store the properties values. The map that is delegated to is being updated dynamically whenever the delegated property is updated.
Let's take a look at how we can make use of the Client class implemented in this recipe. We can instantiate the Client class by passing the Map instance to the class constructor:
val SAMPLE_CLIENT_MAP = mapOf("name" to "Mark Zuck",
"email" to "[email protected]",
"creditCards" to listOf(
CreditCard("Mark Zuckerberg", "123345456789", "123",
1527330705017),
CreditCard("Mark Zuckerberg", "987654321", "321",
1527330719816))
)
val client1 = Client(SAMPLE_CLIENT_MAP)
We can also instantiate the Client class using the fromJson() function, passing a string containing a JSON representation of the sample Client type object:
@Language("JSON")
const val SAMPLE_CLIENT_JSON =
"{ "name": "Mark Zuck",
"email": "[email protected]",
"creditCards": [
{
"holderName": "Mark Zuckerber",
"number": "123345456789",
"cvc": "123",
"expiration": 1527330705017
},
{
"holderName": "Mark Zuckerber",
"number": "987654321",
"cvc": "321",
"expiration": 1527330719816
}
]
}"
val client2 = Client.fromJson(SAMPLE_CLIENT_JSON)
Under the hood, the Client.fromJson() function uses Gson to convert JSON data to the Map<String, Any> instance.
We can now test those two ways and print the contents of both the client1 and client2 objects to the console:
println("name: ${client1.name}, mail: ${client1.email}, cards: ${client1.creditCards}")
println("name: ${client2.name}, email: ${client2.email}, cards: ${client2.creditCards}")
As the result, we are going to get the following output printed to the console:
name: Mark Zuck, email: [email protected], cards: [{holderName=Mark Zuckerber, number=123345456789, cvc=123, expiration=1.527330705017E12}, {holderName=Mark Zuckerber, number=987654321, cvc=321, expiration=1.527330719816E12}]
name: Mark Zuck, email: [email protected], cards: [CreditCard(holderName=Mark Zuckerberg, number=123345456789, cvcCode=123, expiration=1527330705017), CreditCard(holderName=Mark Zuckerberg, number=987654321, cvcCode=321, expiration=1527330719816)]
In both cases, all the class properties are stored in the data map object, no matter which way of instantiating the Client class was chosen. The delegation of the properties to the map allowed us to implement a mechanism that exports the state of the Client object to the map automatically. The map object was stored internally in the Client class, however, it could be declared anywhere else as well.