The Dependency Inversion Principle

What is a Dependency Inversion Principle? The Dependency Inversion Principle means that high-level modules should not depend on low-level modules. Source Source What problems does it solve? The Dependency Inversion Principle (DIP) helps solve: Rigidity Fragility Immobility problems Real-world code example Violation of DIP // High-level module directly depending on low-level modules class MessageService { func sendMessageViaEmail(message: String) { let emailSender = EmailSender() emailSender.sendMessage(message: message) } func sendMessageViaSMS(message: String) { let smsSender = SMSSender() smsSender.sendMessage(message: message) } func sendMessageViaPushNotification(message: String) { let pushNotificationSender = PushNotificationSender() pushNotificationSender.sendMessage(message: message) } } Adhering to DIP // Protocol defining the interface for sending messages protocol MessageSender { func sendMessage(message: String) } // High-level module depending on abstraction (MessageSender protocol) class MessageService { private let messageSender: MessageSender init(messageSender: MessageSender) { self.messageSender = messageSender } func sendMessage(message: String) { messageSender.sendMessage(message: message) } } // Concrete implementations of MessageSender protocol for different channels class EmailSender: MessageSender { func sendMessage(message: String) { print("Sending email: \(message)") } } class SMSSender: MessageSender { func sendMessage(message: String) { print("Sending SMS: \(message)") } } class PushNotificationSender: MessageSender { func sendMessage(message: String) { print("Sending push notification: \(message)") } } // Example usage let emailSender = EmailSender() let smsSender = SMSSender() let pushNotificationSender = PushNotificationSender() let emailService = MessageService(messageSender: emailSender) let smsService = MessageService(messageSender: smsSender) let pushNotificationService = MessageService(messageSender: pushNotificationSender) emailService.sendMessage(message: "Hello via email") smsService.sendMessage(message: "Hello via SMS") pushNotificationService.sendMessage(message: "Hello via push notification") Thank you for reading! 😊

March 5, 2024 Â· 2 min Â· Dmytro Chumakov

Big O notation

What is a Big O notation? The Big O notation helps identify algorithm efficiency. It can measure computation and memory growth with respect to input. Real-world code example O(n) — Linear Time func containsValue(array: [Int], value: Int) -> Bool { for element in array { if element == value { return true } } return false } O(1) — Constant Time func findFirstElement(array: [Int]) -> Int? { return array.first } Thank you for reading!

February 21, 2024 Â· 1 min Â· Dmytro Chumakov

Combine — Basics

What is Combine? Combine Framework provides an API for processing async events over time such as user-input, network response, and other dynamic data. What is the purpose of Combine? The purpose of Combine is to simplify the management of async events and data streams. Publishers Publisher declares that a type can transit a sequence of values over time. A publisher delivers elements to one or more Subscriber instances. class PostService { func fetchPosts() -> AnyPublisher<[Post], Error> { guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { fatalError("Invalid URL") } return URLSession.shared.dataTaskPublisher(for: url) .map(\.data) .decode(type: [Post].self, decoder: JSONDecoder()) .receive(on: DispatchQueue.main) .eraseToAnyPublisher() } } Subscribers Subscriber is a protocol that declares a type that can receive input from a publisher. A Subscriber instance receives a stream of elements from a Publisher. ...

February 7, 2024 Â· 4 min Â· Dmytro Chumakov

Modern Concurrency

When was it introduced? It was introduced in Swift 5.5 at WWDC 2021. You can find the more comprehensive info about Modern Concurrency in Swift Concurrency Manifesto. What are actors? Actors eliminate shared mutable state and explicit synchronization through deep copying of all the data that passed to an actor to a message sent and preventing direct access to actor state. Actors are reference types. actor DatabaseManager { private var data: [String: String] = [:] func readData(key: String) -> String? { data[key] } func writeData(key: String, value: String) { data[key] = value } } What is an asynchronous function? The asynchronous function or asynchronous method can be suspended while it is partway through execution. It can pause in the middle when it’s waiting for something. ...

February 4, 2024 Â· 4 min Â· Dmytro Chumakov

What are Threads in Swift?

What is the Thread? A Thread is a small set of instructions that can be executed independently from the main program. Threads are often used to improve program performance by allowing multiple tasks to be executed at the same time. The Thread has its own stack, registers, and program counters. Threads share memory address space, and it is possible to communicate between Threads using shared memory space. ...

January 20, 2024 Â· 2 min Â· Dmytro Chumakov