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
- Protocol as Blueprints:
- Protocols define a set of requirements (methods, properties) that conforming types must implement.
- Protocol Extensions:
- Extensions provide default implementations of protocol methods, allowing conforming types to inherit behavior automatically.
- Protocol Composition:
- Combine multiple protocols into a single requirement.
- Value Types over Classes:
- Prefer structs and enums (value types) over classes to avoid issues like shared mutable state and inheritance complexity.
- 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