提高系统可读性和可维护性_可读性,可伸缩性和可测试性

提高系统可读性和可维护性

A bit more closer to perfection with MVVM-C in swift

借助MVVM-C更快更接近完美

Many architectural design patterns are introduced since now, amongst those few gained more popularity for developing iOS applications. Earlier, we were using MVC design pattern for developing iOS application, which is quite old now, since many developers have already adapted MVVM design pattern for their iOS applications to focus more on clearly defining responsibility for each layer of architecture.

从现在开始,引入了许多架构设计模式,其中有少数在开发iOS应用程序中获得了越来越多的欢迎。 早些时候,我们使用MVC设计模式来开发iOS应用程序,这已经很老了,因为许多开发人员已经为他们的iOS应用程序改编了MVVM设计模式,以更加专注于明确定义体系结构每一层的职责。

In the following part of the story, we would see, why there was need to enhance MVVM further and how MVVM-C emerged as one of the widely used architectural design pattern.

在故事的以下部分,我们将了解为什么需要进一步增强MVVM,以及MVVM-C如何成为广泛使用的架构设计模式之一。

To answer these questions, let’s have a glimpse of MVC and MVVM.

为了回答这些问题,让我们看一下MVC和MVVM。

MVC中过多的ViewController (Overburdened ViewControllers in MVC)

MVC is having three components Model-View-Controller.

MVC具有三个组件Model-View-Controller。

Model is quite nicely defined and having specific responsibility.

模型定义得很好,并负有具体责任。

View component is somewhat confused with ViewController notion in iPhoneSDK.

View组件与iPhoneSDK中的 ViewController概念有些混淆。

Developers tend to make ViewController responsible for View rendering as well as Controller activity(i.e navigation logic, business logic etc.)

开发人员倾向于让ViewController负责View渲染以及Controller活动( 即导航逻辑,业务逻辑等 )。

Which makes View and Controller tightly coupled to each other and hence they are hard to re-use and of course hard for Unit Testing.

这使得ViewController彼此紧密耦合,因此很难重用,当然也很难进行单元测试。

调用MVVM进行救援以减少ViewController的责任 (Call MVVM to rescue to reduce responsibility of ViewControllers)

MVVM is quite nice compared to MVC, since it helps to overcome drawback of overburdened ViewController of MVC design pattern.

与MVC相比,MVVM非常不错,因为它有助于克服MVC设计模式的ViewController负担过重的缺点。

MVVM has also three components Model-View-ViewModel.

MVVM还具有三个组件Model-View-ViewModel。

Model is straight forward and having single responsibility like MVC.

模型简单明了,并且像MVC一样具有单一职责。

View is simplified and made more clearer with avoiding confusion of ViewController as Controller in MVC. View is responsible for UI rendering on screen. It can be either UIView or UIViewController subclass.

避免将ViewController作为MVC中的Controller造成混淆,从而简化了视图并使视图更加清晰。 视图负责在屏幕上呈现UI。 它可以是UIView或UIViewController子类。

ViewModel is responsible for implementation of business logic as well as communicator between Model and View. ViewModel can be struct or class.

ViewModel负责业务逻辑的实现以及ModelView之间的通信器。 ViewModel可以是structclass

ViewModel is responsible for containing navigation logic, business logic etc. Since, it’s not UIViewController subclass, it is easier to test business logic which is implemented in ViewModel.

ViewModel负责包含导航逻辑,业务逻辑等 。 由于不是UIViewController子类,因此更容易测试在ViewModel中实现的业务逻辑。

ViewModel also helps to make View component dumb with removing ViewController’s responsibility of containing navigation logic. With a dumb View component, it’s completely re-usable.

ViewModel还有助于消除ViewController包含导航逻辑的责任,从而使View组件变得笨拙。 借助笨拙的View组件,它可以完全重用。

ViewModel承担着许多责任,因此很难重用 (ViewModel is having many responsibilities, making it harder to re-use)

ViewModel helped to make View component re-usable and testable and also it made easier to Unit test business logic.

ViewModel有助于使View组件可重用和可测试,并且使单元测试业务逻辑更加容易。

However, if you have observed, still it has other responsibilities(i.e navigation logic) apart from it’s main responsibility of implementing business logic.

但是,如果您已经观察到,除了实现业务逻辑的主要职责之外,它还有其他职责(即导航逻辑 )。

It’s time now to think of reducing responsibility of ViewModel.

现在是时候考虑减少ViewModel的责任了。

MVVM-C模式的出现,并在MVVM中引入了新的组件`Coordinator`。 (Emergence of MVVM-C pattern with introduction of new component `Coordinator` in MVVM.)

To reduce responsibility of ViewModel we can add one more component which can take out responsibility to implement navigation logic from ViewModel

为了减少ViewModel责任,我们可以再添加一个组件,该组件可以承担从ViewModel实现导航逻辑的责任

We call new component Coordinator, since it acts as a coordinator between View and ViewModel.

我们将其称为新组件Coordinator ,因为它充当ViewViewModel之间的协调器。

Coordinator would help ViewModel to hold single responsibility of implementing business logic, which means it’s more easily testable and re-usable now.

Coordinator将帮助ViewModel承担实现业务逻辑的单一责任这意味着它现在更容易测试和重用

We could achieve separation of concerns with introducing fourth component(Coordinator) to MVVM.

通过在MVVM中引入第四个组件( 协调器 ),可以实现关注点分离。

致电MVVM-C以提高可读性,可伸缩性和可测试性 (Call MVVM-C to improve Readability, Scalability and Testability)

Overview of each component in MVVM-C:

MVVM-C中的每个组件概述:

Model

模型

  • Represents data-objects

    表示数据对象
  • Can be struct or class (Recommended to use struct, and confirm to Codable protocol for easy encoding/decoding operations.)

    可以是structclass (建议使用struct ,并确认为Codable协议以方便进行编码/解码操作。)

View

视图

  • Responsible for rendering UI elements on screen

    负责在屏幕上呈现UI元素
  • Make it dumb object, it should follow command of ViewModel only

    使其成为哑对象,仅应遵循ViewModel命令

  • Recommended to make View dependant on ViewModel with Protocol instead of Concrete types. (i.e DataSource, Loadable, Refreshable, Searchable etc.)

    建议使View依赖于具有Protocol ViewModel而不是Concrete类型。 (即数据源,可加载,可刷新,可搜索等)

  • Make it’s additional behaviour(except data rendering) Abstract (i.e LoadingDisplayable)

    使其成为额外的行为(数据渲染除外) Abstract (即LoadingDisplayable)

ViewModel

视图模型

  • Responsible for implementing business logic

    负责实施业务逻辑
  • Communicates with DataLayer to load data from API/Database

    DataLayer通信以从API /数据库加载数据

  • Acts as convenient Datasource for View

    充当View方便Datasource

  • Must notify View when it’s state is changed(i.e isLoading, isRefreshing)

    state更改时必须通知View (即isLoadingisRefreshing )

  • Must notify View when it’s updated(i.e with data from API/Database or any kind of sort/filter of data)

    更新时必须通知View (即使用API​​ /数据库中的数据或任何类型的数据排序/过滤器)

  • Optionally communicates to Coordinator for Error handling

    可以选择与Coordinator进行Error处理

Coordinator

协调员

  • Responsible for implementing navigation logic

    负责实施导航逻辑
  • Instantiates and returns ViewController via start() method

    通过start()方法实例化并返回ViewController

  • Instantiates ViewModel and feeds it to ViewController

    实例化ViewModel并将其提供给ViewController

  • Optionally acts as ErrorDelegate of ViewModel to handle errors

    (可选)充当ViewModel ErrorDelegate处理错误

  • Informs to parent cordinator via finished() method about it’s job completion

    通过finish finished()方法通知父项Cordinator工作完成情况

Till this point, we just focused on theoretical part. May be you’re not 100% clear about implementing MVVM-C.

至此,我们只关注理论部分。 可能您对实现MVVM-C不太了解100%。

Don’t worry!! In the following section, we would discuss around actual code to give you better understanding. :)

不用担心! 在下一节中,我们将围绕实际代码进行讨论,以使您更好地理解。 :)

We would build one demo application, which consumes remote API and populates list on the screen.

我们将构建一个演示应用程序,该应用程序使用远程API并在屏幕上填充列表。

In this demo, we used https://restcountries.eu APIs to populate countries on the screen, based on search keyword.

在此演示中,我们基于搜索关键字 ,使用https://restcountries.eu API填充了屏幕上的国家/地区。

Let’s start defining one by one entities for our application.

让我们开始为我们的应用程序定义一个实体。

模型 (Model)

As you can see below, I defined my Model as struct and confirmed my Model to Codable protocol for easy encoding/decoding.

如下所示,我将Model定义为struct并确认Model to Codable协议易于编码/解码。

To know more about Codable, you can check my story: Essential of “Codable” in Swift

要了解有关Codable更多信息,可以查看我的故事: Swift中“ Codable”的要点

视图模型 (ViewModel)

As I mentioned above, ViewModel is responsible to implement business logic and notify View about its state change.

如上所述, ViewModel负责实现业务逻辑并通知View 状态更改。

So, I prefer to define ViewModel protocol, with methods to keep notifying View about it’s state change and notify View when it’s updated with data.

所以,我更愿意定义ViewModel 协议 ,与方法,以保持通知View它的状态变化,并通知View时,它的数据更新

This mechanism to notify view would make communication between View and ViewModel pretty easy to implement and understand.

这种通知视图的机制将使ViewViewModel之间的通信非常容易实现和理解。

It would also make View implementation clean and readable to render updated data when ViewModel is updated.

ViewModel更新时,这也将使View实现变得干净和可读以呈现更新的数据。

Now, we can define our concrete ViewModel and let’s name it CountryListViewModel .

现在,我们可以定义具体的ViewModel并将其命名为CountryListViewModel

CountryListViewModel confirms toCountryListDatasource protocol, which would make CountryListViewModel act as datasource for View.

CountryListViewModel确认使用CountryListDatasource协议,这将使CountryListViewModel充当View 数据源

CountryListViewModel confirms to ViewModel protocol to notify View about state change.

CountryListViewModelViewModel协议确认以通知View状态更改。

CountryListViewModel implements “func seachFor(keyword: String)” method to confirm to Searchable protocol.

CountryListViewModel实现“ func seachFor(keyword:String) ”方法以对Searchable协议进行确认。

CountryListViewModel communicates to DataLayer via RequestManager.

CountryListViewModel通过RequestManager与DataLayer进行通信。

And it communicates with Coordinator via ErrorDelegate protocol.

并且它通过ErrorDelegate协议与Coordinator进行通信。

CountryListViewModel implements all required things, which we listed in above section with great Readability.

CountryListViewModel实现了所有必需的东西,我们在上一节中以很高的可读性列出了这些东西

We also increased Scalability of CountryListViewModel, in a sense to easily add new behaviour.

我们还增加了可扩展性 CountryListViewModel ,从某种意义上讲可以轻松添加新的行为。

It can confirm to Refreshable protocol and implement “func refresh()” method like we implemented “func searchFor(keyword: String)”.

它可以确认为可Refreshable协议,并可以像我们实现“ func searchFor(keyword:String)”那样实现“ func refresh() ”方法。

Now, let’s have a look, how it helps to improve Testability of our code.

现在,让我们看看它如何帮助提高代码的可测试性。

As you can see above, we can easily test all responsibilities of our ViewModel. It has code coverage of 100%.

如您在上面看到的,我们可以轻松测试ViewModel所有职责。 它的代码覆盖率为100%。

And not only code coverage, it would make it easier to achieve 100% functional coverage to test various scenarios for your business logic.

而且不仅是代码覆盖率,还可以更轻松地实现100% 功能覆盖率,以测试各种业务逻辑方案

视图 (View)

I prefer to make View dumb object, to make it easy to re-use.

我更喜欢使View哑对象,以使其易于重用。

It must communicate to ViewModel to fetch data to render it on screen. It should observe state change and updating of ViewModel to refresh data on screen.

它必须与ViewModel通信以获取数据以将其呈现在屏幕上。 它应该观察状态变化和ViewModel 更新以刷新屏幕上的数据。

CountryListViewController communicates to Coordinator via CountryListViewControllerDelegate protocol.

CountryListViewController通过CountryListViewControllerDelegate协议与Coordinator进行通信。

View is dependant on protocol types for ViewModel in “func configure(viewModel: CountryListViewModelProtocol)”

View取决于“ func configure(viewModel:CountryListViewModelProtocol)”中ViewModel协议类型

It would increase Scalability of View. For example, if we want to add ability to “refresh” screen, we could easily ask our ViewModel to be Refreshable like below.

这将增加可扩展性 View 。 例如,如果我们想为“刷新”屏幕添加功能,我们可以轻松地要求ViewModel如下所示是可Refreshable

typealis CountryListViewModelProtocol = CountryListDatasource & ViewModel & Searchable & Refreshable

typealis CountryListViewModelProtocol = CountryListDatasource&ViewModel&Searchable& Refreshable

协调员 (Coordinator)

Coordinator is mainly responsible for implementing navigation logic.

Coordinator器主要负责实现导航逻辑。

I prefer to define Coordinator protocol, which defines basic responsibility of Coordinator.

我宁愿定义Coordinator协议,它定义的基本责任Coordinator

Let’s implement concrete coordinator and name it CountryListCoordinator.

让我们实现具体的协调器并将其命名为CountryListCoordinator

You can see that CountryListCoordinator implements functionality of Coordinator protocol.

您可以看到CountryListCoordinator实现了Coordinator协议的功能。

CountryListCoordinator instantiated CountryListViewController and returned it from start() method.

CountryListCoordinator实例化CountryListViewController并从start()方法返回它。

CountryListCoordinator acts as delegate for View by confirming to CountryListViewControllerDelegate protocol.

通过确认CountryListViewControllerDelegate协议, CountryListCoordinator充当Viewdelegate

CountryListCoordinator also acts as ErrorDelegate of ViewModel by confirming to CountryListViewModeLoadingErrorDelegate protocol.

通过确认CountryListViewModeLoadingErrorDelegate协议, CountryListCoordinator还可以充当ViewModelErrorDelegate

Implementing Coordinator makes it easy to separate concern of implementing navigation logic from View or ViewModel.

通过实现Coordinator ,可以轻松地将实现导航逻辑的关注点与ViewViewModel分开。

We can easily test Coordinator now.

我们现在可以轻松地测试Coordinator

MVVM-C helps to follow SOLID principles by Uncle Bob.

MVVM-C帮助遵循Bob叔叔的 SOLID原则。

SOLID principles helps you improve Readability, Scalability and Testability of your application.

SOLID原则可帮助您提高应用程序的可读性可伸缩性可测试性。

I hope you enjoyed reading this story and have good understanding of MVVM-C for your swift applications.

我希望您喜欢阅读这个故事,并且对快速应用程序对MVVM-C有很好的了解。

I would be happy to answer your queries.

我很乐意回答您的问题。

Happy Coding!! :)

快乐编码! :)

翻译自: https://medium.com/swlh/readability-scalability-and-testability-ae0d1d8b08c0

提高系统可读性和可维护性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值