Thursday, February 25, 2016

Refactoring: Introduce Null object

Some of the objects in our programs can have null values (nil in Swift).

The functionality is different if we know the value for those objects or not, so we might need to check in multiple places for that. 

Let's consider the following code:

class Address {
    var street: String = ""
    var city: String = ""
    
    func formattedAddress() -> String {
        return "\(street), \(city)"
    }
}

class User {
    var address: Address?
}

let user = User()

Suppose in different places in the code you need information about the value of the street for a user, for example, for displaying reasons.

var street: String

if let address = user.address {
    street = address.street
} else {
    street = ""
}

Also in other places you need the city, so you have the following code:

var city: String
if let address = user.address {
    city = address.city
} else {
    city = ""
}

And so forth. This might be cumbersome and also prone to error. It is easy to forget to check for nil in one place.

The solution to this is to create one new class to include all the functionality we need to have when the address is not know.

Here is an example:

class NullAddress: Address {
    override init() {
        street  = ""
        city  = ""
    }

    override func formattedAddress() -> String {
        return "unknown address"
    }
}

And here is how our User class will look now.

class User {
    var address: Address = NullAddress()
}


So the following code:

var street: String

if let address = user.address {
    street = address.street
} else {
    street = ""
}

will become:

var street =  user.address.street

Notice the formattedAddress() function. If the address is unknown, it will return "unknown address" so custom functionality can also be added to our null class.





No comments:

Post a Comment