From c4b02ee56a0becd167044e7188ccba5cfea5b430 Mon Sep 17 00:00:00 2001 From: Shaun Culver Date: Thu, 28 Nov 2024 09:31:43 +0200 Subject: [PATCH 1/6] Facade --- DesignPatterns/AppleStoreFacade/README.md | 90 ++++++++++++++--------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/DesignPatterns/AppleStoreFacade/README.md b/DesignPatterns/AppleStoreFacade/README.md index bb6299d..c7847c1 100644 --- a/DesignPatterns/AppleStoreFacade/README.md +++ b/DesignPatterns/AppleStoreFacade/README.md @@ -10,61 +10,83 @@ ## Pattern overview -- The Facade pattern is a structural pattern that provides a simplified interface to a complex system of classes. -- For example, a Mac has many subsystems such as CPU, memory, storage, etc. -- The Facade pattern provides a unified interface to these subsystems. +- The Facade pattern provides a simple way to complete tasks where many underlying parts are needed. + +- These parts are encapsulated in an object, which provides a simple interface to perform the tasks. ## Problem statement -- We have services that are separate but often used together. -- By providing a simple interface to these services, we can reduce the complexity of the client code. -- This pattern is also useful for testing the subsystems in isolation and how they may interact with each other. +- Once orders are processed on the Apple Store, notifications are sent to the customer. -## Domain application +- At the moment, this is initiated on the server. Let's imagine that we are tasked to implement notification processing from the app. -Facade: +- Once an order is processed, we need to send a notification to the customer. -- Knows which subsystem classes are responsible for a request. -- Delegates client requests to appropriate subsystem objects. +- We have two notfication APIs that we have implemented: `MailNotificationAPI` and `MessageNotificationAPI`. -```swift -class OrderProccessor { - private let bag: Bag - private let paymentService: PaymentService +- We also have a `Settings` class that handles all the settings for the app, including the notification type selected by the user. - init(bag: Bag, paymentService: PaymentService) { - self.bag = bag - self.paymentService = paymentService - } +- Once an order is processed, we want to avoid having to call the `MailNotificationAPI` or `MessageNotificationAPI` directly. + +- The Facade pattern allows us to combine these classes into a single class that can handle the notification processing. + +## Definitions - func processOrder() { - paymentService.processPaymentWithBag(bag) +#### Facade: + +- Maintains references to subsystem classes. + +- Delegates work to subsystem classes. + +```swift +struct NotificationFacade { + private let mailNotificationAPI = MailNotificationAPI() + private let messageNotificationAPI = MessageNotificationAPI() + private let settings = Settings(notificationType: .mail) + + func send(text: String) { + switch settings.notificationType { + case .mail: + mailNotificationAPI.sendMailWithText(text) + case .message: + messageNotificationAPI.sendMessageWithText(text) + } } } ``` -Subsystem classes: +#### Subsystem classes: -- Implement subsystem functionality. -- Handle work assigned by the Facade object. -- Have no knowledge of the facade; that is, they keep no references to it. +- Implements the functionality of the subsystems. -```swift -struct Bag { - var products: [Product] +- They are decoupled from the Facade object. - addProduct(_ product: Product) { - products.append(product) +```swift +struct Settings { + enum NotificationType { + case mail + case message } - removeProduct(_ product: Product) { - products.removeAll { $0.id == product.id } + var notificationType: NotificationType +} + +struct MailNotificationAPI { + func send(text: String) { + print("Mail sent with text: \(text)") } } -class PaymentService { - func processPaymentWithBag(_ bag: Bag) { - // Process payment +struct MessageNotificationAPI { + func send(text: String) { + print("Message sent with text: \(text)") } } ``` + +## Example + +```swift +let notificationFacade = NotificationFacade() +notificationFacade.send(text: "Order processed.") // Mail sent with text: Order processed. +``` From 284d5cf85da78830fdd1518dfd57bcf619fde1a5 Mon Sep 17 00:00:00 2001 From: Shaun Culver Date: Thu, 28 Nov 2024 09:35:58 +0200 Subject: [PATCH 2/6] Facade update --- DesignPatterns/AppleStoreFacade/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DesignPatterns/AppleStoreFacade/README.md b/DesignPatterns/AppleStoreFacade/README.md index c7847c1..7ab30fd 100644 --- a/DesignPatterns/AppleStoreFacade/README.md +++ b/DesignPatterns/AppleStoreFacade/README.md @@ -30,6 +30,8 @@ - The Facade pattern allows us to combine these classes into a single class that can handle the notification processing. +- This is all done without exposing the complexity of the underlying objects. + ## Definitions #### Facade: From 766d97ca178b4591fcc5c4b3246035d9339b08a5 Mon Sep 17 00:00:00 2001 From: Shaun Culver Date: Thu, 28 Nov 2024 09:38:11 +0200 Subject: [PATCH 3/6] Facade: Definition order swap --- DesignPatterns/AppleStoreFacade/README.md | 46 +++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/DesignPatterns/AppleStoreFacade/README.md b/DesignPatterns/AppleStoreFacade/README.md index 7ab30fd..91685ce 100644 --- a/DesignPatterns/AppleStoreFacade/README.md +++ b/DesignPatterns/AppleStoreFacade/README.md @@ -34,29 +34,6 @@ ## Definitions -#### Facade: - -- Maintains references to subsystem classes. - -- Delegates work to subsystem classes. - -```swift -struct NotificationFacade { - private let mailNotificationAPI = MailNotificationAPI() - private let messageNotificationAPI = MessageNotificationAPI() - private let settings = Settings(notificationType: .mail) - - func send(text: String) { - switch settings.notificationType { - case .mail: - mailNotificationAPI.sendMailWithText(text) - case .message: - messageNotificationAPI.sendMessageWithText(text) - } - } -} -``` - #### Subsystem classes: - Implements the functionality of the subsystems. @@ -86,6 +63,29 @@ struct MessageNotificationAPI { } ``` +#### Facade: + +- Maintains references to subsystem classes. + +- Delegates work to subsystem classes. + +```swift +struct NotificationFacade { + private let mailNotificationAPI = MailNotificationAPI() + private let messageNotificationAPI = MessageNotificationAPI() + private let settings = Settings(notificationType: .mail) + + func send(text: String) { + switch settings.notificationType { + case .mail: + mailNotificationAPI.sendMailWithText(text) + case .message: + messageNotificationAPI.sendMessageWithText(text) + } + } +} +``` + ## Example ```swift From 56fd354b585b2a27a65e62bd3a378cf807b8998c Mon Sep 17 00:00:00 2001 From: Shaun Culver Date: Thu, 28 Nov 2024 10:55:36 +0200 Subject: [PATCH 4/6] Facade: Rewording --- DesignPatterns/AppleStoreFacade/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignPatterns/AppleStoreFacade/README.md b/DesignPatterns/AppleStoreFacade/README.md index 91685ce..15983cc 100644 --- a/DesignPatterns/AppleStoreFacade/README.md +++ b/DesignPatterns/AppleStoreFacade/README.md @@ -26,7 +26,7 @@ - We also have a `Settings` class that handles all the settings for the app, including the notification type selected by the user. -- Once an order is processed, we want to avoid having to call the `MailNotificationAPI` or `MessageNotificationAPI` directly. +- Once an order is processed, we want to avoid exposing the objects we need to use to send a notification: `Settings`, `MailNotificationAPI`, and `MessageNotificationAPI`. - The Facade pattern allows us to combine these classes into a single class that can handle the notification processing. From b068cb4a81e72c3ea8d086fe02c67bc24e38dd81 Mon Sep 17 00:00:00 2001 From: Shaun Culver <45091059+xsdc@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:05:32 +0200 Subject: [PATCH 5/6] Update README.md --- DesignPatterns/AppleStoreFacade/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesignPatterns/AppleStoreFacade/README.md b/DesignPatterns/AppleStoreFacade/README.md index 15983cc..c01b21b 100644 --- a/DesignPatterns/AppleStoreFacade/README.md +++ b/DesignPatterns/AppleStoreFacade/README.md @@ -1,4 +1,4 @@ -![Facade](https://github.com/user-attachments/assets/9b3ca4a3-ab1e-4a2f-828c-491282b6614c) +![Facade](https://github.com/user-attachments/assets/b4217919-558b-4b46-b5ba-de31f8bc8a5d)
From 8ce74542b89caefae75e85e6c5f367f6abda301c Mon Sep 17 00:00:00 2001 From: Shaun Culver <45091059+xsdc@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:20:32 +0200 Subject: [PATCH 6/6] Update README.md --- DesignPatterns/AppleStoreFacade/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DesignPatterns/AppleStoreFacade/README.md b/DesignPatterns/AppleStoreFacade/README.md index c01b21b..3be7053 100644 --- a/DesignPatterns/AppleStoreFacade/README.md +++ b/DesignPatterns/AppleStoreFacade/README.md @@ -22,7 +22,7 @@ - Once an order is processed, we need to send a notification to the customer. -- We have two notfication APIs that we have implemented: `MailNotificationAPI` and `MessageNotificationAPI`. +- We have two notification APIs that we have implemented: `MailNotificationAPI` and `MessageNotificationAPI`. - We also have a `Settings` class that handles all the settings for the app, including the notification type selected by the user. @@ -51,13 +51,13 @@ struct Settings { } struct MailNotificationAPI { - func send(text: String) { + func sendMail(withText: String) { print("Mail sent with text: \(text)") } } struct MessageNotificationAPI { - func send(text: String) { + func sendMessage(withText: String) { print("Message sent with text: \(text)") } } @@ -78,9 +78,9 @@ struct NotificationFacade { func send(text: String) { switch settings.notificationType { case .mail: - mailNotificationAPI.sendMailWithText(text) + mailNotificationAPI.sendMail(withText: text) case .message: - messageNotificationAPI.sendMessageWithText(text) + messageNotificationAPI.sendMessage(withText: text) } } }