gpt4 book ai didi

ios - Swift 中对于具有多个方面的模型的良好设计?

转载 作者:行者123 更新时间:2023-11-30 13:43:43 24 4
gpt4 key购买 nike

我想问一个关于如何在 swift 中定义具有多个方面的模型的好例子,特别是当项目变得越来越大并且一个模型具有多个方面时。问题很长,但我只是想知道人们如何在大项目中设计模型。任何评论或想法将不胜感激。

假设有一个名为“Book”的模型,其定义如下:

class Book {
var id: String
var title: String
var author: String
init?(json: [String: AnyObject]) {
// parse the model from JSON
}
}

Book 有一个可失败的初始化程序,用于解析服务器发送的 JSON 中的属性。在 View Controller A上,它描述了关于模式Book的更详细的信息,因此在 View Controller R A上使用时,会在模型中添加一些属性:

class Book {
var id: String
var title: String
var author: String

// required on View Controller A
var price: Int
var seriersName: String
var reviewNumber: Int
var detailedDescription: String

init?(json: [String: AnyObject]) {
// parse the model from JSON
}
}

在另一个 View Controller B 上,我们想要显示图书购买的历史记录。因此该模型需要如下附加属性:

class Book {
var id: String
var title: String
var author: String

// required on View Controller A
var price: Int
var seriersName: String
var reviewNumber: Int
var detailedDescription: String

// required on View Controller B (Not required on VC A)
var purchasedDate: NSDate
var expireDate: NSDate

init?(json: [String: AnyObject]) {
// parse the model from JSON
}
}

Book 的这个定义缺乏灵 active ,因为传递给故障标签初始化程序的 JSON 必须具有所有属性,即使在仅使用部分属性的 VC 上也是如此。

解决方案A:
我认为最简单的解决方案就是将这些附加属性声明为可选,但我个人认为这不太酷,因为每当使用这些可选属性时,都需要检查它们是否不为零。

if let seriesName = book.seriesName {
self.seriesNameLable.title = seriesName
}

这种可选绑定(bind)代码将会溢出到我假设的所有代码中。隐式可选绑定(bind)也许可以使用,但使用起来并不安全。

解决方案B:
另一种解决方案可能是定义继承 Book 的不同模型,例如 BookA 和 BookB。但是如果我们需要一个同时具有 BookA 和 BookB 方面的模型怎么办?

我想这类问题没有单一的解决方案,但我想知道其他人如何在大项目中定义模型。 (我想知道是否有人会使用一些“快速特定”功能(例如协议(protocol)及其扩展)提供一个很酷的解决方案:)。我将不胜感激任何意见...谢谢。

最佳答案

免责声明:我不是 Swift 程序员,这是我根据具有相同功能的其他语言进行的推断,我的 Swift 语法可能不是 100% 准确

使用protocols我会做类似的事情:

class EBook: Book, HasOnlineSource {
...
}

class OtherKindOfBook: Book, WithCollectorEditions, HasBleh, WithFoo {...}

但你必须问自己:

我需要进行动态更改吗?

如果是这种情况,您需要通过组合来进行委派。

应用程序的不同部分使用核心模型的方式是否不同?

或者换句话说,这些模型的不同用户是否需要不同的行为?在这种情况下,扩展非常有用,因为允许根据上下文公开同一模型的不同行为。例如,报告模块可以发送消息numberOfReaders,而销售模块可以请求promotionalCodes。两者都使用相同的模型,但与不同的协议(protocol)进行交互。就您而言,您有不同的 Controller 想要不同的东西,因此这可能适用。

使用委托(delegate)

这遵循组合优于继承原则,但在回顾了如何delegates work in Swift之后,我知道它们不是 native 实现,但仍然是一种设计模式(您可能会说是功能请求),委托(delegate)是手工进行的。

其他语言允许您使用 BookProtocol 创建 JSSONSerializedBook,但您可以设置委托(delegate),而不是实现 BookProtocol 上所需的内容初始化后将实现此类协议(protocol)。该委托(delegate)将是 JSSONSerializedBook 的内部协作者,并且 JSSONSerializedBook 接收到的属于 BookProtocol 一部分的所有消息都将委托(delegate)给它。或者换句话说,消息传递是自动处理的(如果您想检查其他语言如何实现它,这里是Kotlin documentatin on delegates)。

如果您想在 Swift 上执行相同的操作,则必须显式将消息传递给您的委托(delegate)。这种设计有几个优点,但由于没有对消息传递的 native 支持,因此实现起来变得非常冗长。

如需进一步引用,您可以查看 mixins 上的论文和 traits深入了解此功能背后的设计决策。

关于ios - Swift 中对于具有多个方面的模型的良好设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35238605/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com