内置于Flex:基于视图的RESTful API
您刚刚发布了最新功能,一切进行得很好,除了要求已更改。 在您的用户界面中,需要将tableview中的所有cityName
实例替换为countryName.
如果您使用的端点具有这种灵活性,该怎么办? 如果该端点允许您呈现动态,灵活且受控的服务器端视图,该怎么办? 如果此视图使您可以显示各种类型的对象或更改当前对象的值而不发布新版本的应用程序该怎么办? 好吧,坚持。 这篇文章将向您介绍一种设计模式,以帮助您完成上述所有工作。
灵活性的需求
与移动应用程序相比,在网络上部署更改要快得多,因为没有其他应用程序需要提交和审批。 即使这样,减少部署数量同时仍然能够在移动和Web客户端上进行更改将被认为是成功的选择。 这可以通过提前使端点,数据协定和UI更加抽象的努力来实现。 这种抽象将为您的UI提供更大的灵活性,并让您控制服务器端的业务逻辑,从而可以帮助减少进行这些更改所需的部署。
上面列出的场景并不少见,但是还有其他一些优势可能有助于我们朝着这种设计模式迈进。 这些功能包括:
- 从服务器更新/重新排列UI元素
- 运行各种A / B测试版本
- 避免在App Store审核过程中增加额外的发布时间
- 将业务逻辑移至服务器并具有单个控制点进行更改
典型到灵活
现在您已经确信了,让我们开始做生意,看看如何实现这一目标。 让我们以一个基本的旅行应用程序为例,该应用程序会根据您的位置向您显示飞往目的地的费用。
此视图的JSON是什么样的?
通常,数据库中会有一个destination
表,该表将在端点中传递。 它可能看起来像以下内容:
{
“目的地”:[{
“ id”:“ 1234567890”,
“ city”:“ Los Angeles”,
“ state”:“ CA”,
“国家”:“美国”,
“ background”:“ http://www.example.com/losAngeles.jpg”,
“ airportCode”:“ LAX”,
“ lat”:“ 165.0987654”,
“ lon”:“ 45.3456788”,
“ flightPrice”:“ 180”
},
{ 等等...
使用基于视图的API,我们可以使用以下JSON表示同一视图:
{
“数据”:[{
“ backgroundImage”:“ http://www.example.com/losAngeles.jpg”,
“ title”:“洛杉矶”,
“副标题”:“ $ 180往返”,
“ objectID”:“ 1234567890”,
“ type”:“机票”
},
{ 等等...
让我们分解一下这里发生的事情。
我们完全忽略了原始数据模型,而将重点转移到了需要表示的视图上。 然后,我们抽象出视图的所有元素,使用通用名称表示它们,这样它们就不会与诸如价格或位置之类的特定数据绑定。 完成此操作后,不仅删除了所有向下发送的多余数据,而且还从数据中分离了视图。 现在,无论服务器发送给我们title
或subtitle
任何值,都将在它们各自的视图中显示。 我们也将id
更改为objectId
因为我们希望该值对我们来说是不透明的。 继续阅读,您会明白为什么。
灵活的时间
考虑以下情况:我们的应用程序正在扩展,以包括酒店等其他类型的产品,但我们也希望能够链接到我们认为用户会发现有趣并从中获得启发的博客。 让我们看看如何使用基于视图的API进行管理。
{
“数据”:[{
“ backgroundImage”:“ http://www.example.com/losAngeles.jpg”,
“ title”:“洛杉矶”,
“副标题”:“ $ 180往返”
“ objectID”:“ 1234567890”,
“ type”:“机票”
},
{
“ backgroundImage”:“ http://www.example.com/hotel.jpg”,
“ title”:“标准酒店”,
“副标题”:“每晚$ 220”
“ objectID”:“ 456789876”,
“类型”:“酒店”
},
{
“ backgroundImage”:“ http://www.example.com/blog.jpg”,
“ title”:“十大夏日度假胜地”,
“ objectID”:“ http://www.someblog.com”,
“ type”:“博客”
},
{ 等等...
是时候再次分解它了。
我们列表上的第一项保持不变。 在第二个中,我们可以使用与航班相同的JSON数据合同添加酒店。 由于我们拥有的视图将保持不变,因此唯一的区别是传递给下一个数据的值。 这将我们带到type
和objectId.
这两个是内容之所在。 您会注意到,即使我们在视图中包括了三种不同类型的对象,但所有更改都是该type.
type
值使我们知道将用户发送到哪里。 例如,您将看到type
“ blog”的objectId
是url。 当我们看到值是blog时,可以假定如果将objectId
发送到浏览器,则视图将呈现。 同样,对于酒店,我们会将那个objectId
传递给视图控制器,该控制器可以将objectId
发送到服务器并获取有关该特定酒店的信息。
这种设计模式不仅限于提要视图。 您可以将这些用于您的详细视图,在其中您需要A / B测试是要在描述上方显示地图还是要优化结帐流程的顺序。 可能性是无止境!
既然您已经了解了可以使用的灵活性,那么让我们简要概述一下为该API提供动力的设计模式。
实体控制边界设计模式
实体控制边界(Entity-Control-Boundary,ECB)设计模式是MVC的一种变体,用于系统,而不仅仅是用户界面。 让我们分解各个组件以帮助说明它们的作用:
- 实体是代表系统数据的对象:目的地,航班,旅馆,用户等。
- 边界是与系统参与者交互的对象:API端点,用户界面,网关,代理等。
- 控制器是在边界和实体之间进行中介的对象。 它们协调来自边界的命令的执行,并充当边界元素和实体元素之间的粘合剂,从而实现管理各种元素及其交互所需的逻辑。
与MVC一样,围绕各种元素之间的交互也有一些规则:
- 角色只能与边界对象交谈。
- 边界对象只能与控制器和参与者对话。
- 实体对象只能与控制器对话。
- 控制器可以与边界对象和实体对象以及其他控制器对话,但不能与参与者对话
最终,目标是分离应用程序层之间的关注点。 这种架构以及许多类似的架构并不依赖于表示模型或平台。 所有箭头或依赖项都指向抽象链中的内部,每个连续的层都比之前的层少抽象。
有关此设计模式的更多信息,请参考以下链接:
- 实体控制边界(ECB)设计模式
- 准则:实体控制边界模式
- 实体-边界-交互者
结论
与许多设计模式一样,每种模式都有其优缺点。 ECB允许该实现抽象您的业务并从模型中查看逻辑,并建立与数据库无关的体系结构。 没有设计模式可以用作广为人知的灵丹妙药,但是当您想从服务器端控制参与者或需要灵活性时,ECB绝对是您的有用工具。