protocol-oriented programming vs object-oriented programming

Question:

Can you explain 'protocol-oriented programming' in Swift? How does it differ from 'object-oriented programming'?


Answer:

Protocol oriented programming is a programming pattern introduced by Apple in Swift, where protocols are given more prominence compared to classes and inheritance, which are commonly used in object oriented programming. Protocols define blueprints for methods, properties or other requirements. Any type (class, struct, enum) that conforms to a protocol must provide implementations for those requirements.

    1. Protocol Definition:
    • A protocol defines a blueprint of methods, properties, or other behaviors that a class, struct, or enum can adopt.
    • Protocols are somewhat like interfaces in other languages, specifying what a conforming type must implement without detailing how the implementation should be done.
protocol Vehicle {
    var speed: Double { get set }
    func accelerate()
}
    2. Protocol Conformance:
    • Types that adopts a protocol must implement the required methods and properties.
    • A major difference from OOP is that structs, enums and classes can all conforms to protocols, not just classes.
struct CarVehicle {
    var speed: Double = 0.0
    func accelerate() {
        speed += 10
    }
}
    3. Default Implementations:
    • Swift allows protocols to provide default implementations for their methods, making it easier to conform to protocols without needing to rewrite common behaviors.
    • Any type conforming to the protocol can use this default implementation unless they provide their own custom version
extension Vehicle {
    func accelerate() {
        print("Accelerating at a default speed")
    }
}
4. Value types and Structs
    • In swift, structs and enums are value types, while classes are reference types. Swift encourages the use of value types like structs to achieve predictable and safe behavior, as they avoid many of the issues that arise with reference types.
    • Protocols are more naturally suited to value types as they promote behavior reuse without relying on class inheritance.
struct TruckVehicle {
    var speed: Double = 0.0
}

var myTruck = Truck()
myTruck.accelerate()  // Uses the default implementation

Difference Between Protocol-Oriented programming and Object-Oriented programming:

    1. Focus on Protocols vs Classes:
    • In OOP the primary focus is on classes and inheritance. A class typically inherits behavior from a parent class through subclassing.
    • In POP, the focus is on protocols and composition. Instead of inheriting behavior from a base class, types conforms to multiple protocols to gain behavior. This leads to more flexible and modular design.
    2. Inheritance vs Composition:
    • OOP heavily relies on inheritance to share behavior. This can lead to complex hierarchies where subclasses inherits all the traits of their parent classes, even when it is unnecessary and undesirable.
    • POP favors composition through protocols. They can conform to multiple protocols gaining only the behaviors they need without being forced into a  rigid class hierarchy.
    OOP Example:
class Vehicle {
    var speed: Double = 0.0
    func accelerate() {
        speed += 10
    }
}

class CarVehicle { }
POP Example:
protocol Drivable {
    var speed: Double { get set }
    func accelerate()
}

struct CarDrivable {
    var speed: Double = 0.0
    func accelerate() {
        speed += 10
    }
}
    3. Single inheritance vs Multiple protocol conformance:
    • In OOP, Swift supports single inheritance. This means a class can inherit from only on parent class, which can limit flexibility.
    • In POP, types can conform to multiple protocols, allowing more flexible combinations of behavior.
protocol FuelEfficient {
    var fuelEfficiency: Double { get }
}

protocol Drivable {
    var speed: Double { get set }
    func accelerate()
}

struct HybridCarDrivableFuelEfficient {
    var speed: Double = 0.0
    var fuelEfficiency: Double = 100.0
    func accelerate() {
        speed += 10
    }
}
    4. Code Reuse with Extensions:
    • In OOP, code reuse is primarily achieved through inheritance and base classes.
    • In POP, code reuse can be achieved using protocol extensions, which allow shared behavior across multiple types that conforms to a protocol, without the need for a shared base class.
    5. Value Types:
    • POP encourages the use of value types (like structs) to avoid common issues with reference types, such as unwanted side effects due to shared state.
    • OOP often relies on reference types (like classes), which can lead to side effects when instance are shared or mutated in different parts of the program.

    Advantages of protocol-oriented programming:
    • Flexibility: Types can conform to multiple protocols, allowing greater flexibility without being tied down by rigid class hierarchies.
    • Code reusability: Protocols and extensions allow for reusable code without the pitfalls of inheritance.
    • Value types: Encourage the use of value types that are safer and avoid problems like shared mutable state.
    • Modular design: Protocols promote modular, decoupled designs, where functionality is separated into protocols, making it easier to swap or update the behavior.
    When to user protocol-oriented programming:
    • We use POP when we want more flexible and reusable code that doesn't rely on deep inheritance hierarchy.
    • When working with value types like structs or enums, POP is a natural fit.
    In Summery:
        Protocol-oriented programming in swift highlights protocols and composition over inheritance, promoting more flexible, reusable and modular code compared to traditional object-oriented programming. It allows for code to be shared more easily across multiple types, encourages the use of value types, and avoids many of the pitfalls of deep class hierarchies found in OOP.

Comments

Popular posts from this blog