Протоколно-ориентированная загрузка файлов

Недавно я посмотрел этот доклад ( ссылка, см. Раздел " Сеть") и решил сделать несколько замечаний в программировании, ориентированном на протокол. Поэтому я подумал об этом простом примере: View Controller для отображения списка файлов. Конечно, протокол-ориентированный способ, со следующими ограничениями:

FilesViewController - содержит табличное представление & FilesTableViewAdapter, Таблица просмотра делегата.FilesTableViewAdapter - инициализируется с представлением таблицы & FilesProvider: Gettable, так что в тестах могу вводить FilesProviderMock: Gettable,FilesTableViewAdapter является источником данных табличного представления и использует FilesProvider для получения файлов.

final class FilesTableViewController: UIViewController {

    var filesTableView: FilesTableView! { return view as! FilesTableView }

    private var tableViewAdapter: FilesTableViewAdapter<FilesProvider>!

    // MARK: Subclassing

    override func loadView() {
        view = FilesTableView(frame: UIScreen.main.bounds)
    }

    override func viewDidLoad() {
       tableViewAdapter = FilesTableViewAdapter(filesTableView.tableView, provider: FilesProvider())

       // Actually I would like to have this method in Adapter
       // so that VC isn't handling networking.
       tableViewAdapter.provider.get { result in
           // result type: (Result<[File]>)
           switch result {
           case .success(let files): print(files)
           case .failure(let error): print(error)
           }
        }

        filesTableView.tableView.delegate = self
        filesTableView.tableView.dataSource = tableViewAdapter
     }
}

extension FilesTableViewController: UITableViewDelegate {
  //
}


final class FilesTableViewAdapter<T: Gettable>: NSObject, UITableViewDataSource {

    let provider: T
    private let tableView: UITableView

    init(_ tableView: UITableView, provider: T) {
        self.tableView = tableView
        self.provider = provider

        super.init()
    }

    func problem() {
        provider.get { result in
            // Result type is (Result<T.T>) - :(
            switch result {
            case .success(let files): print(files)
            case .failure(let error): print(error)
        }
    }
}

struct FilesProvider {
   private let Files = [File]()
}

extension FilesProvider: Gettable {

    func get(completionHandler: (Result<[File]>) -> Void) {
        //
    }
}

protocol Gettable {
   associatedtype T
   func get(completionHandler: (Result<T>) -> Void)
}

Я знаю, что зашел слишком далеко, обобщив этот фрагмент кода. Теперь я застрял, и у меня есть эти вопросы, на которые я не могу ответить сам:

  1. Как сделать это ориентированным на протокол способом с сетевым кодом в классе, отличном от VC (скажем, Adapter)?
  2. Как сделать его легко тестируемым и расширяемым в будущем?

0 ответов

Другие вопросы по тегам