Monday, February 15, 2016

Refactoring in Swift - Extract protocol

A protocol (also called interface in other languages) defines a blueprint of properties, functions and other functionality a class needs to follow.

It is used to define a certain type of classes.

Sometimes classes evolve and only after a while their common functionality becomes apparent.

Consider the following classes:

class Car {
    var make: String?
    var model: String?
    var mileage: Float?
    var numberOfDoors: Int?
    var maximumSpeed: Float?
    var horsePower: Float?
    var colour: UIColor?
}

class Motorcycle {
    var make: String?
    var model: String?
    var mileage: Float?
    var maximumSpeed: Float?
    var horsePower: Float?
    var colour: UIColor?
    var wheels: Int?
}

Because they are different classes, functionality that applies to both is difficult to write. For example, it is not easy to create an array of both cars and motorcycles and sort them by maximum speed.

We notice they have common functionality so we can extract a protocol containing it:

protocol Vehicle {
    var make: String? { get set }
    var model: String? { get set }
    var mileage: Float? { get set }
    var maximumSpeed: Float? { get set }
    var horsePower: Float? { get set }
    var colour: UIColor? { get set }
}

In this case, our classes will become:

class Car : Vehicle {
    var make: String?
    var model: String?
    var mileage: Float?
    var numberOfDoors: Int?
    var maximumSpeed: Float?
    var horsePower: Float?
    var colour: UIColor?
}

class Motorcycle : Vehicle {
    var make: String?
    var model: String?
    var mileage: Float?
    var maximumSpeed: Float?
    var horsePower: Float?
    var colour: UIColor?
    var wheels: Int?
}

A sorting function is now obvious:

func sortVehicle(vehicleArray:[Vehicle]) -> [Vehicle] {
    return vehicleArray.sort ({ $0.maximumSpeed < $1.maximumSpeed })
}

Here is some code to test it:


let v1 = Car()
v1.maximumSpeed = 100
let v2 = Motorcycle()
v2.maximumSpeed = 150
let v3 = Car()
v3.maximumSpeed = 140

var array1: [Vehicle]
array1 = [v1,v2,v3]

let array2 = sortVehicle(array1)

No comments:

Post a Comment