Skip to content
Tamerlan Satualdypov edited this page Jul 31, 2023 · 2 revisions

The entities in the Model layer are not a simple structs (DTOs or POJOs), they serve as repositories for the application's data and embody the logic for manipulating that data. This domain is a system of such objects, that has their own properties, methods and relationships. Models should be independent and could be reused across all modules of an app. The objects in the Model layer could use Active Record, Data Mapper or Factory Method design patterns to avoid doing extra work and creating unnecessary layers in the project.

Designing your Model

In order to successfully design your Model, you should see it as an object that represents special knowledge and expertise. They identify and define the logic that manipulates the data. You should not see Models as plain structs and put all the logic around it in other layers, as it is mistakenly done in other patterns, such as MVC or MVVM. Do not feel uncomfortable that entities in this layer contain the logic that manipulates its data, because it is natural and it gives you flexibility in reusing them in different modules of your app.

You could use the following steps to quickly design the Model:

  • Identify the data (properties)
  • Identify the tasks (methods)
  • Identify the dependencies (nested Models)

Example

struct Post: Codable, Identifiable {
    // Data
    let id: String
    let title: String
    let text: String
    
    // Dependency
    let author: [Profile]

    // Tasks
    func like(...) async { ... }
    func dislike(...) async { ... }

    // Factory
    static var all: [Post] { get async throws }
    static func with(id: String) async throws -> Post { ... }
    static func search(for query: String) async throws -> [Post] { ... }
}
Clone this wiki locally