The Decorator Pattern
The Decorator pattern is a structural design pattern that allows you to add behaviour to individual objects, either statically or dynamically, without altering their structure. The Decorator pattern is often used to enhance the functionality of classes by wrapping them with additional behaviour, rather than modifying the classes themselves. This promotes code reusability, maintainability, and flexibility.
Imagine you are developing a photo editing app that allows users to apply various filters to their images. You have a base ImageFilter class that defines the interface for different filters.
protocol ImageFilter {
? ? func apply(image: UIImage) -> UIImage
}
You also have concrete filter classes like BlackAndWhiteFilter, SepiaFilter, and ContrastFilter, each implementing the ImageFilter interface.
class BlackAndWhiteFilter: ImageFilter {
? ? func apply(image: UIImage) -> UIImage {
? ? ? ? // Apply black and white filter to the image
? ? ? ? return processedImage
? ? }
}
Now, you want to introduce a feature where users can apply stickers to their images. Instead of directly modifying the existing filter classes to support stickers, you can use the Decorator pattern to dynamically add sticker functionality to the filters.
class StickerDecorator: ImageFilter {
? ? private let baseFilter: ImageFilter
? ? private let sticker: Sticker
? ??
? ? init(baseFilter: ImageFilter, sticker: Sticker) {
? ? ? ? self.baseFilter = baseFilter
? ? ? ? self.sticker = sticker
? ? }
? ??
? ? func apply(image: UIImage) -> UIImage {
? ? ? ? var processedImage = baseFilter.apply(image: image)
? ? ? ? // Apply sticker to the processedImage
? ? ? ? return processedImage
? ? }
}
Now the Client Code to use this decorator pattern will be:---
let originalImage: UIImage = // Load original image
let filter: ImageFilter = BlackAndWhiteFilter()
let sticker: Sticker = // Load sticker image
let filterWithSticker = StickerDecorator(baseFilter: filter, sticker: sticker)
let finalImage = filterWithSticker.apply(image: originalImage)
In this scenario, the Decorator pattern enables you to add sticker functionality to any filter dynamically without modifying the existing filter classes. This approach keeps the codebase clean, promotes code reusability, and allows for easy addition of new features in the future.
By using the Decorator pattern, you can extend the functionality of classes in your iOS app without making extensive changes to the existing codebase, which is particularly beneficial when dealing with third-party libraries or when you want to avoid creating numerous subclasses for every possible combination of functionalities.
Sharing my TCA expertise to empower your development ?? | ?????? with TCA in apps with 100,000+ monthly active users | iOS Software Engineer @ AVIV
1 年The Decorator pattern is a fantastic way to adhere to the Open/Closed Principle (OCP) in software design. It empowers you to enhance class functionality without altering their core code, promoting flexibility and maintainability. ??????