Tag: 抽象

Swift中的关联类型

动机 可重用性是软件开发中的重要组成部分。 我认为,软件体系结构中最重要的考虑因素之一就是即将推出的功能的实现时间。 我经常有片刻,然后躺在床上,直到实施了该死的功能后才入睡。 因此,快速的实施时间可以为我节省大量的睡眠时间(这是我绝对需要的)。 继承是重用超类功能的一种方法。 但是事情会迅速发展,随之而来的是复杂性的增加。 幸运的是,我们在Swift中有了面向协议的方法。 但是协议必须是通用的,以便将其定义重新用于不同的类型。 类允许我们指定通用参数。 协议为我们提供了“关联类型” 。 实际示例:用于CoreData处理的CRUD协议 我想为我的CoreData实现创建一个协议。 这将是常见的CRUD (创建,读取,更新,删除)功能。 没有通用协议,我必须在所有地方都使用NSManagedObject,这真的很不舒服,因为我有Xcode生成的子类。 我的实体是: TaskMO和ItemMO 。 我都需要他们的经理班。 对于TaskMO,协议定义必须匹配一次,对于ItemMO,协议定义必须匹配一次。 可以使用“ associatedtype ”关键字来实现。 协议持久{ 关联类型实体 } 如您所见,实体只是一个占位符,而不是具体类型。 具体类型将仅在实现中指定。 使用约束来缩小类型 Persistable协议使我们能够处理CRUD功能。 但是我要确保将其用于CoreData。 我们可以通过向我们的关联类型添加约束来确保这一点。 就我而言,我只想允许在NSManagedObject子类上使用。 此步骤与通用参数非常相似。 协议持久{ relatedtype实体:NSManagedObject } 完整协议如下所示: 编写实现 现在按照您习惯的方式实现类型。 名为“类型推断”的编译器功能会自动检测具体类型的定义。 因此,我们不必明确指定它。 煮咖啡机 凉。 我们创建了一个通用的可重用协议。 但是,让我们深入一点。 我想制造一台咖啡机。 不只是基本的黑咖啡。 我想要一杯很棒的拿铁玛奇朵。 首先,我指定成分: 我的咖啡由主要的咖啡成分和某种牛奶组成。 我将协议命名为“ Drinkable […]

为模型创建一个抽象层

您是否在iOS开发中见过模型的不同层? 我从来没有。 例如,当使用Core Data时,我们通常直接在视图中操作NSManagedObject 。 那不理想。 因此,我一次研究了如何为模型创建抽象层。 为什么要使用其他型号? 我正在使用Core Data将数据存储在我们的应用程序中记住。 要创建核心数据模型,我需要在NSManagedObject构造函数中注入NSManagedObjectContext对象。 问题是我不想在应用程序中到处传递上下文对象。 我希望将其隔离在模型层中。 我想在业务层中操作简单的 POSO (普通的旧Swift对象)。 为此,我需要一种将NSManagedObject对象转换为业务对象,反之亦然的方法。 另外,我的数据库对象不应该知道我的业务对象。 这样,我可以轻松地用另一个数据库提供程序替换Core Data,而不会影响其余的代码库。 这个想法的灵感来自清洁架构。 业务和模型层 在我们的应用程序中,请记住,我只有一个表来存储用户最后一次执行某项操作的时间。 很简单 我在业务层中创建了一个Event类。 这是我将在视图中操作的对象。 对于模型层,我创建了一个EventManagedObject类,该类继承自NSManagedObject 。 从一种模式到另一种 为了双向转换对象,我创建了一个由Event类实现的ObjectConvertible协议。 该identifier用于获取相应的NSManagedObject (如果存在)。 然后,我创建了ManagedObjectConvertible协议。 因为我不想在实现该协议的每个NSManagedObject子类中重写相同的代码,所以我写了一个协议扩展来完成大部分工作。 这就是魔术发生的地方。 该协议由EventManagedObject类实现。 由于协议扩展,我只剩下两种方法可以实现。 这些是将业务对象的数据传输到数据库对象的数据,反之亦然的方法。 CRUD操作 现在,无需直接操作NSManagedObject对象,即可在Event对象上执行操作非常容易。 商店 在本文开头,我说过我不想在整个代码中都传递NSManagedObjectContext对象。 为了隔离上下文,我创建了一个EventStore类,该类在NSManagedObjectContext对象上保留了一个引用。 然后,可以在视图控制器或视图模型中使用商店。 业务层使用商店对业务对象执行操作。 它不知道对象的存储位置,它可能在Core Data,Realm甚至文件中。 这是我的抽象层。 缺点 尽管此方法在处理模型对象时提供了一定的便利,但它也有一些缺点。 最大的问题是我无法使用Core Data的内置延迟加载系统或NSFetchedResultsController 。 如果要使用它,则必须创建自己的分页系统。 此解决方案中也未实现处理关系 […]