我应该为这些模型使用协议吗?

Should I Be Using Protocols for these Models?

我正在使用 Dribbble API,目前我正在使用三个模型:

ShotUserTeam 上传到他们各自的作品集以供展示的东西。这可以是图像或动画。一个User可以属于多个Team,而一个Team可以有多个User

这三个模型各有许多属性,我在下面提供了这些属性。

User 采用以下结构:

/// Encapsulates information about a Dribbble User.
public struct User {

    // MARK: - Properties

    /// The identifier of the User.
    public var identifier: Int?

    /// The name of the User.
    public var name: String?

    /// The username of the User.
    public var username: String?

    /// The `URL` for the User's Dribbble page.
    public var htmlURL: URL?

    /// The `URL` for the User's avatar image.
    public var avatarURL: URL?

    /// The biography for the User.
    public var biography: String?

    /// The location for the User.
    public var location: String?

    /// The `URL` for the User's website.
    public var websiteURL: URL?

    /// The `URL` for the User's Twitter profile.
    public var twitterURL: URL?

    /// The number of Buckets for the User.
    public var bucketsCount: Int?

    /// The number of Comments the User has received.
    public var commentsReceivedCount: Int?

    /// The number of followers for the User.
    public var followersCount: Int?

    /// The number of followings for the User.
    public var followingsCount: Int?

    /// The number of Likes for the User.
    public var likesCount: Int?

    /// The number of Likes received for the User.
    public var likesReceivedCount: Int?

    /// The number of projects for the User.
    public var projectsCount: Int?

    /// The number of Rebounds received for the User.
    public var reboundsReceivedCount: Int?

    /// The number of Shots for the User.
    public var shotsCount: Int?

    /// The number of Teams that the User belongs to.
    public var teamsCount: Int?

    /// Whether the User is authorized to upload Shots.
    public var canUploadShot: Bool?

    /// The type of User.
    public var type: String?

    /// Whether the User has Pro status.
    public var isPro: Bool?

    /// The `URL` for the User's Buckets.
    public var bucketsURL: URL?

    /// The `URL` for the User's followers.
    public var followersURL: URL?

    /// The `URL` for the User's followings.
    public var followingURL: URL?

    /// The `URL` for the User's Likes.
    public var likesURL: URL?

    /// The `URL` for the User's Projects.
    public var projectsURL: URL?

    /// The `URL` for the User's Shots.
    public var shotsURL: URL?

    /// The `URL` for the Teams that the User belongs to.
    public var teamsURL: URL?

    /// The `Date` that the User was created.
    public var createdAt: Date?

    /// The `Date` that the User was last updated.
    public var updatedAt: Date?
}

Team 采用以下结构:

/// Encapsulates information about a Dribbble Team.
public struct Team {

    // MARK: - Properties

    /// The identifier of the Team.
    public var identifier: Int?

    /// The name of the Team.
    public var name: String?

    /// The username of the Team.
    public var username: String?

    /// the `URL` for the Team's Dribbble page.
    public var htmlURL: URL?

    /// The `URL` for the Team's avatar image.
    public var avatarURL: URL?

    /// The biography for the Team.
    public var biography: String?

    /// The location for the Team.
    public var location: String?

    /// The `URL` for the Team's website.
    public var websiteURL: URL?

    /// The `URL` for the Team's Twitter profile.
    public var twitterURL: URL?

    /// The number of Buckets for the Team.
    public var bucketsCount: Int?

    /// The number of Comments the Team has received.
    public var commentsReceivedCount: Int?

    /// The number of followers for the Team.
    public var followersCount: Int?

    /// The number of followings for the Team.
    public var followingsCount: Int?

    /// The number of Likes for the Team.
    public var likesCount: Int?

    /// The number of Likes received for the Team.
    public var likesReceivedCount: Int?

    /// The number of projects for the Team.
    public var projectsCount: Int?

    /// The number of Rebounds received for the Team.
    public var reboundsReceivedCount: Int?

    /// The number of Shots for the Team.
    public var shotsCount: Int?

    /// Whether the Team is authorized to upload Shots.
    public var canUploadShot: Bool?

    /// The type of Team.
    public var type: String?

    /// Whether the Team has Pro status.
    public var isPro: Bool?

    /// The `URL` for the Team's Buckets.
    public var bucketsURL: URL?

    /// The `URL` for the Team's followers.
    public var followersURL: URL?

    /// The `URL` for the Team's followings.
    public var followingURL: URL?

    /// The `URL` for the Team's Likes.
    public var likesURL: URL?

    /// The `URL` for the Team's Projects.
    public var projectsURL: URL?

    /// The `URL` for the Team's Shots.
    public var shotsURL: URL?

    /// The `Date` that the Team was created.
    public var createdAt: Date?

    /// The `Date` that the Team was last updated.
    public var updatedAt: Date?

    /// The number of members for the Team.
    public var membersCount: Int?

    /// The `URL` for the members of the Team.
    public var membersURL: URL?

    /// The `URL` for the Team Shots.
    public var teamShotsURL: URL?

}

Shot 采用以下结构:

/// Encapsulates information about a Dribbble Shot.
public struct Shot {

    // MARK: - Properties

    /// The identifier of the Shot.
    public var identifier: Int?

    /// The title of the Shot.
    public var title: String?

    /// The description of the Shot.
    public var description: String?

    /// The size of the Shot.
    public var size: CGSize?

    /// The `URL` for the Shot's high-definition image.
    public var highDefinitionImageURL: URL?

    /// The `URL` for the Shot's normal image.
    public var normalImageURL: URL?

    /// The `URL` for the Shot's teaser image.
    public var teaserImageURL: URL?

    /// The number of views for the Shot.
    public var viewsCount: Int?

    /// The number of likes for the Shot.
    public var likesCount: Int?

    /// The number of comments for the Shot.
    public var commentsCount: Int?

    /// The number of attachments for the Shot.
    public var attachmentsCount: Int?

    /// The number of Rebounds for the Shot.
    public var reboundsCount: Int?

    /// The number of Buckets for the Shot.
    public var bucketsCount: Int?

    /// The `Date` that the Shot was created.
    public var createdAt: Date?

    /// The `Date` that the Shot was last updated.
    public var updatedAt: Date?

    /// The `URL` for the Shot's Dribbble page.
    public var htmlURL: URL?

    /// The `URL` for the Shot's attachments.
    public var attachmentsURL: URL?

    /// The `URL` for the Shot's Buckets.
    public var bucketsURL: URL?

    /// The `URL` for the Shot's comments.
    public var commentsURL: URL?

    /// The `URL` for the Shot's Likes.
    public var likesURL: URL?

    /// The `URL` for the Shot's Projects.
    public var projectsURL: URL?

    /// The `URL` for the Shot's Rebounds.
    public var reboundsURL: URL?

    /// Whether the Shot is animated.
    public var isAnimated: Bool?

    /// The tags associated with the Shot.
    public var tags: Array<String>?

    /// The `User` that the Shot belongs to.
    public var user: User?

    /// The `team` that she Shot belongs to.
    public var team: Team?

}

UserTeam 有很多重复的属性,而 Shot 有一些 UserTeam 有。如果我走这些模型的协议路线,将会有许多个协议实现。

在我的例子中,我没有理由拥有 Identifiable 类型或 WebsiteURL 类型的 Array 类型,或符合重复属性协议的任何其他类型。我将有 ShotArray 个,它们属于 User 个或 Team 个。我还将 Arrays 用于 Users 和 Arrays 用于 Teams.

我是否应该为重复的属性实施协议并让 UserTeamShot 符合它们,或者这会导致协议地狱,除了没有明显的好处之外正所谓"Swifty"?

那么像这样使用继承呢,

Common parent 获取 Shot、User 和 Team 的属性,Parent for user 和 team 仅获取 user 和 team 的属性有

   Common parent
     |
-----------------------------------------------
|                                             |
Parent for user and team                      |
|                                             |
|-----------|                                 |
User      Team                              Shot