Sobes.tech
Middle+

Ինչպես օգտագործել MVC ճարտարապետությունը՝ կանխելու վերահսկողի ծանրաբեռնվածությունը?

sobes.tech AI

Պատասխան AI-ից

MVC (Model-View-Controller) iOS-ում հաճախ հանգեցնում է «մեծ» վերահսկիչների՝ դրանցում բիզնես-լոգիկայի և ներկայացման լոգիկայի տեղակայման պատճառով։ Այս խնդիրը լուծելու համար կարելի է օգտագործել հետևյալ մոտեցումները՝

  • Ներկայացման լոգիկայի տեղափոխում View-ին: Ստեղծել հատուկ UIView կամ սեղանի/հավաքածուի բջիջներ, որոնք պատասխանատու են տվյալների ցուցադրման և հիմնական գործողությունների (օրինակ՝ կոճակների սեղմում) մշակման համար։ Վահանակը միայն կոնֆիգուրացնում է View-ը անհրաժեշտ տվյալներով։

    class MyCustomView: UIView {
        private let label = UILabel()
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            addSubview(label)
            // սահմանել constraints և այլն
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        func configure(with text: String) {
            label.text = text
        }
    
        // UIControlEvents իրադարձությունների մշակումը, օրինակ՝ addTarget-ի միջոցով
    }
    
  • Բիզնես-լոգիկայի տեղափոխում Model կամ առանձին Service օբյեկտների մեջ: Ստեղծել դասեր, որոնք պատասխանատու են կոնկրետ գործողությունների համար (օրինակ՝ ցանցի, տվյալների բազայի աշխատանքը, տվյալների վավերացում)։ Վահանակը փոխանցում է այդ օբյեկտներին այդ գործառույթների կատարման պատասխանատվությունը։

    class UserService {
        func fetchUsers(completion: @escaping ([User]?, Error?) -> Void) {
            // ցանցային հարցման լոգիկա
        }
    }
    
    class ProfileViewController: UIViewController {
        private let userService = UserService()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            userService.fetchUsers { users, error in
                // UI-ի թարմացում ստացված տվյալների կամ սխալի հիման վրա
            }
        }
    }
    
  • Data Source և Delegate Protocol-ների օգտագործում: Реализация протоколов UITableViewDataSource, UICollectionViewDataSource, UITableViewDelegate, UICollectionViewDelegate առանձին դասերում, ոչ թե հենց վերահսկիչում։ Վահանակը միայն կպատկանի այդ դասերի օրինակներին։

    class UsersTableViewDataSource: NSObject, UITableViewDataSource {
        private var users: [User] = []
    
        func update(users: [User]) {
            self.users = users
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return users.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "UserCell", for: indexPath)
            let user = users[indexPath.row]
            cell.textLabel?.text = user.name
            return cell
        }
    }
    
    class UsersViewController: UIViewController {
        @IBOutlet weak var tableView: UITableView!
        private let dataSource = UsersTableViewDataSource()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            tableView.dataSource = dataSource
            // տվյալների բեռնում և փոխանցում dataSource-ին
        }
    }
    
  • Coordinator Pattern-ի կիրառումը: Ստեղծել առանձին օբյեկտներ, որոնք պատասխանատու են էկրանների միջև նավիգացիայի համար։ Վահանակները միայն գիտեն, որ պետք է անցնել հաջորդ քայլը, բայց չեն իմանում՝ որ վերահսկիչը կլինի հաջորդը։

    protocol AppCoordinator: AnyObject {
        func start()
        func showUserDetails(user: User)
    }
    
    class MainAppCoordinator: AppCoordinator {
        private let navigationController: UINavigationController
    
        init(navigationController: UINavigationController) {
            self.navigationController = navigationController
        }
    
        func start() {
            let usersVC = UsersViewController()
            // կարգավորել դելեգատը, dataSource-ը և այլն
            navigationController.pushViewController(usersVC, animated: false)
        }
    
        func showUserDetails(user: User) {
            let userDetailsVC = UserDetailsViewController(user: user)
            navigationController.pushViewController(userDetailsVC, animated: true)
        }
    }
    

Այս մոտեցումները թույլ են տալիս նվազեցնել վերահսկիչի բեռը՝ դարձնելով այն ավելի «փոքր», կենտրոնանալով View-ի կյանքի ցիկլի կառավարմանը և փոխգործակցության կազմակերպմանը Model և View-ի միջև, այլ ոչ թե ամբողջ ծրագրային լոգիկայի իրականացմանը։