Skip to content
Egor Badmaev edited this page Jan 11, 2023 · 6 revisions

Single Responsibility Principle

  1. Single responsibility principle was implemented in CoreDataManager class that is responsible only for working with Core Data. It is the only place where Core Data was imported.

  2. The next example is in NetworkManager class that is responsible for networking. It is the only place where URLSession is being used.

  3. And the most predictable answer is Interactor, for example, from VIPER - that is responsible for working with data.

Open-Closed Principle

The simplest example is in creating Endpoints. If you want to create new endpoint, you can add new method to the public extension and use it.

public extension Endpoint {

    static func random() -> Self {
        return Endpoint(path: "api/recipes/v2",
                        parameters: [("type", "public"),
                                     ("app_id", Credentials.appId),
                                     ("app_key", Credentials.apiKey),
                                     ("q", keywords.randomElement() ?? "chicken")]
        )
    }
    
    static func random(by category: String) -> Self {
        return Endpoint(path: "api/recipes/v2",
                        parameters: [("type", "public"),
                                     ("app_id", Credentials.appId),
                                     ("app_key", Credentials.apiKey),
                                     ("cuisineType", category),
                                     ("q", keywords.randomElement() ?? "chicken")]
        )
    }
}

Liskov Substitution Principle

This principle was implemented between such modules as Common, Discover and Search.

The Liskov substitution principle (LSP) is a particular definition of a subtyping relation, called strong behavioral subtyping.

Interface Segregation Principle

We have two entities in Core Data and CoreDataManager class. Methods for both entities will be the same (CRUD operations), but we should segregate them into two interfaces, because components should not depend on interfaces that they do not use

public protocol CDRecipeProtocol { ... }
public protocol CDStepProtocol { ... }

public final class CoreDataManager { ... }

extension CoreDataManager: CDRecipeProtocol { ... }
extension CoreDataManager: CDStepProtocol { ... }

Dependency Inversion Principle

image

Same principle here:

NetworkManagerProtocol is an abstraction over NetworkManager class. When we are using network manager, we access to it via protocol:

let networkManager: NetworkManagerProtocol