Site icon CodeWithSwift

Protocol Oriented Programming

Protocol-Oriented Programming (POP) is a programming paradigm in Swift that emphasizes the use of protocols to define shared behaviour and default implementations. It is an alternative to traditional Object-Oriented Programming (OOP) and promotes code reusability, flexibility, and type safety.

Introduced by Apple in Swift 2.0, POP leverages Swift’s features like protocol extensions, default implementations, and generics to make code more modular and reusable.

Concepts of Protocol-Oriented Programming

  1. Protocol as Blueprints:
    • Protocols define a set of requirements (methods, properties) that conforming types must implement.
  2. Protocol Extensions:
    • Extensions provide default implementations of protocol methods, allowing conforming types to inherit behavior automatically.
  3. Protocol Composition:
    • Combine multiple protocols into a single requirement.
  4. Value Types over Classes:
    • Prefer structs and enums (value types) over classes to avoid issues like shared mutable state and inheritance complexity.
  5. Generics with Protocols:
    • Use protocols with generics to write type-safe and reusable code.

1.Protocol with Default Implementation

protocol Greetable {
    func greet()
}

extension Greetable {
    func greet() {
        print("Hello, nice to meet you!")
    }
}

struct Person: Greetable {}
struct Robot: Greetable {}

let person = Person()
person.greet()  // Output: Hello, nice to meet you!

let robot = Robot()
robot.greet()  // Output: Hello, nice to meet you!

2.Protocol Composition

protocol Drivable {
    func drive()
}

protocol Flyable {
    func fly()
}

typealias FlyingCar = Drivable & Flyable

struct FutureCar: FlyingCar {
    func drive() {
        print("Driving on the road.")
    }
    
    func fly() {
        print("Flying in the air.")
    }
}

let car = FutureCar()
car.drive()  // Output: Driving on the road.
car.fly()    // Output: Flying in the air.

3.Protocol with Associated Types

protocol Container {
    associatedtype Item
    var items: [Item] { get set }
    mutating func addItem(_ item: Item)
}

extension Container {
    mutating func addItem(_ item: Item) {
        items.append(item)
    }
}

struct StringContainer: Container {
    var items: [String] = []
}

var container = StringContainer()
container.addItem("Swift")
container.addItem("Protocol-Oriented Programming")
print(container.items)  // Output: ["Swift", "Protocol-Oriented Programming"]

4.Value Types in POP

protocol Shape {
    func area() -> Double
}

struct Rectangle: Shape {
    var width: Double
    var height: Double
    
    func area() -> Double {
        return width * height
    }
}

struct Circle: Shape {
    var radius: Double
    
    func area() -> Double {
        return .pi * radius * radius
    }
}

let rect = Rectangle(width: 5, height: 10)
let circle = Circle(radius: 7)

print("Rectangle Area: \(rect.area())")  // Output: 50.0
print("Circle Area: \(circle.area())")  // Output: 153.93804002589985
Exit mobile version