<style> code.orange { color: #F7A004 !important; } </style> ## *Design Pattern* # <code class="orange"><b>Decorator Pattern</b></code> Speaker - Wendy --- # Wiki - Allows behavior to be added to an individual object, dynamically - Without affecting the behavior of other objects from the same class. --- # Real - World --- ![](https://i.imgur.com/CdbVzdS.png) --- ### Create a Person class ```kotlin interface Human { fun getBody() } class Person : Human { override fun getBody() { println("Person's body") } } ``` --- ### Wear clothes ```kotlin class Person : Human { override fun getBody() { println("Person's body") println("Wear a sweater") println("Put on a raincoat") } } ``` `getBody() has too many behaviors!` --- ### Base Decorator ```kotlin abstract class ClothingDecorator(private val human: Human) : Human { override fun getBody() { human.getBody() } } ``` --- ### Add a sweater ```kotlin class SweaterDecorator(private val human: Human) : ClothingDecorator(human) { override fun getBody() { super.getBody() println("Wear a sweater") } } ``` --- ### Wear a sweater ```kotlin fun main() { val person = SweaterDecorator(Person()) person.getBody() } ``` #### Result ``` Person's body Wear a sweater ``` --- ### Add a raincoat ```kotlin class RaincoatDecorator(private val human: Human) : ClothingDecorator(human) { override fun getBody() { super.getBody() println("Wear a raincoat") } } ``` --- ### Wear a raincoat ```kotlin fun main() { val person = RaincoatDecorator(SweaterDecorator(Person())) person.getBody() } ``` #### Result ``` Person's body Wear a sweater Wear a raincoat ``` --- # For App --- ## For App - Ad Banner ![](https://i.imgur.com/Fb04RDg.jpg =400x) --- ### Ads Statistics *Ads - provided callback interface* ```kotlin interface AdEventListener { fun onAdScrollByUser() fun onAdAutoScroll() } ``` --- ### Ads Statistics *Implementation knows nothing about stats* ```kotlin class AdBannerEventListenerImpl : AdEventListener { override fun onAdScrollByUser() { println("Do scrolling by user logic") } override fun onAdAutoScroll() { println("Do auto scrolling logic") } } ``` --- ### Ads Statistics *All stats logic is encapsulated into decorator* ```kotlin class AdEventListenerLoggingDecorator( private val target: AdEventListener, private val statistics: GAStatistics ) : AdEventListener by target { override fun onAdScrollByUser() { target.onAdScrollByUser() statistics.sendEvent(“ad_scroll_by_user”) } override fun onAdAutoScroll() { target.onAdAutoScroll() statistics.sendEvent(“ad_auto_scroll”) } } ``` --- ### Ads Statistics ```kotlin fun main() { val adBanner = AdEventListenerLoggingDecorator( AdBannerEventListenerImpl(), GAStatistics() ) adBanner.onAdScrollByUser() adBanner.onAdAutoScroll() } ``` --- ## Pros - Extend an object’s behavior without making a new subclass. - Add or remove responsibilities from an object at runtime. - Combine several behaviors by wrapping an object into multiple decorators. - Single Responsibility Principle. --- ## Cons - Hard to implement a decorator in such a way that its behavior doesn’t depend on the order in the decorators stack. - The initial configuration code of layers might look pretty ugly. --- ### Reference - Android - [Java decorator example](https://refactoring.guru/design-patterns/decorator/java/example) - [Applying decorator pattern to decorate views on Android](https://www.javacodegeeks.com/2014/08/applying-decorator-pattern-to-decorate-views-on-android.html) - [Decorator pattern in Android](https://medium.com/@denisrebrof/decorator-pattern-in-android-development-5dd1637710fa) - [Decorator pattern in Android development](https://www.reddit.com/r/androiddev/comments/a6p6y4/decorator_pattern_in_android_development/) --- ### Reference - iOS - [Swift Design Patterns in Practice: the Decorator Pattern](https://stablekernel.com/article/swift-design-patterns-in-practice-the-decorator-pattern/) - [Using Decorator Pattern to Add Architectural Non-Intrusive Analytics in Swift](https://holyswift.app/using-decorator-pattern-to-add-architectural-non-intrusive-analytics-in-swift/) - [Design Patterns in Swift - Decorator](https://vinileal.com/design%20patterns/design-patterns-swift-decorator/)
{"metaMigratedAt":"2023-06-17T12:25:12.846Z","metaMigratedFrom":"YAML","title":"<code class=\"orange\"><b>Decorator Pattern</b></code>","breaks":true,"contributors":"[{\"id\":\"17076682-2483-46ff-99ad-cd09df8cced9\",\"add\":8082,\"del\":3459}]"}
    169 views