model层 swift_swift model列表 - CSDN
  • 
 
 
 
 
 
 
 价值 | 思考 | 共鸣简评:我们经常需要在编写 方便的代码 和 易于维护的代码 之间取得平衡,当然...
        

    价值 | 思考 | 共鸣

    640?wx_fmt=gif

    简评:我们经常需要在编写 方便的代码 和 易于维护的代码 之间取得平衡,当然如果能兼顾两者是最好的。

    640?wx_fmt=jpeg在平衡便利性和可维护性时,往往会遇到 View 和 Model 需要建立联系的情况,如果 View 和 Model 建立太强的连接会导致代码难以重构和难以重用。

    专用 View

    先看一个例子,在构建应用时,我们需要创建用于显示特定类型数据的专用视图,假设我们需要在表格中显示用户列表。一个常见的方法是创建一个专门用于渲染用户数据的 UserTableViewCell,如下:

    1. class UserTableViewCell: UITableViewCell {

    2.    override func layoutSubviews() {

    3.        super.layoutSubviews()

    4.        let imageView = self.imageView!

    5.        imageView.layer.masksToBounds = true

    6.        imageView.layer.cornerRadius = imageView.bounds.height / 2

    7.    }

    8. }

    我们还需要使用 User model 来填充 Cell 里面的内容,一般会添加一个 configure 方法,用于填充内容,代码如下:

    1. extension UserTableViewCell {

    2.    func configure(with user: User) {

    3.        textLabel?.text = "\(user.firstName) \(user.lastName)"

    4.        imageView?.image = user.profileImage

    5.    }

    6. }

    上面的代码在功能上没有任何的问题,但是技术上讲,我们实际上已经将 Model 层泄露给我们的 View 层。我们的 UserTableViewCell class 不仅专门用于呈现 User 的信息(不能是其他的数据模型)而且还需要知道 User 对象的具体内容,起初,这可能不是问题,但是如果我们继续沿着这条路走,我们的 View 很容易演变成包含 app 逻辑的代码:

    1. extension UserTableViewCell {

    2.    func configure(with user: User) {

    3.        textLabel?.text = "\(user.firstName) \(user.lastName)"

    4.        imageView?.image = user.profileImage

    5.        // Since this is where we do our model->view binding,

    6.        // it may seem like the natural place for setting up

    7.        // UI events and responding to them.

    8.        if !user.isFriend {

    9.            let addFriendButton = AddFriendButton()

    10.            addFriendButton.closure = {

    11.                FriendManager.shared.addUserAsFriend(user)

    12.            }

    13.            accessoryView = addFriendButton

    14.        } else {

    15.            accessoryView = nil

    16.        }

    17.    }

    18. }

    编写如上所示的代码可能看起来非常方便,但通常会让程序难以测试和维护。

    通用 View

    解决上述问题的一个办法是让 View 和 Model 之间进行严格的分离(代码层面和概念层面进行分离)。

    我们再回去看看我们 UserTableViewCell 。他不再与 User 耦合,我们可以该名为 RoundedImageTableViewCell 并删除 configure 这个与 User 耦合的方法。

    1. class RoundedImageTableViewCell: UITableViewCell {

    2.    override func layoutSubviews() {

    3.        super.layoutSubviews()

    4.        let imageView = self.imageView!

    5.        imageView.layer.masksToBounds = true

    6.        imageView.layer.cornerRadius = imageView.bounds.height / 2

    7.    }

    8. }

    进行上述更改的好处是,我们现在可以轻松的将 RoundedImageTableViewCell 和 其他 model 配合使用。

    但是,在将我们的模型代码与我们的视图代码进行分离时,损失了便利性。之前我们可以使用 configure(with:) 方法来渲染 User,现在我们需要找一种新方法来实现这一点。

    我们可以做的是创建一个专用对象来配置 View 的显示。我们来构建一个 UserTableViewCellConfigurator 类,代码如下(不同的架构实现有所不同):

    1. class UserTableViewCellConfigurator {

    2.    private let friendManager: FriendManager

    3.    init(friendManager: FriendManager) {

    4.        self.friendManager = friendManager

    5.    }

    6.    func configure(_ cell: UITableViewCell, forDisplaying user: User) {

    7.        cell.textLabel?.text = "\(user.firstName) \(user.lastName)"

    8.        cell.imageView?.image = user.profileImage

    9.        if !user.isFriend {

    10.            // We create a local reference to the friend manager so that

    11.            // the button doesn't have to capture the configurator.

    12.            let friendManager = self.friendManager

    13.            let addFriendButton = AddFriendButton()

    14.            addFriendButton.closure = {

    15.                friendManager.addUserAsFriend(user)

    16.            }

    17.            cell.accessoryView = addFriendButton

    18.        } else {

    19.            cell.accessoryView = nil

    20.        }

    21.    }

    22. }

    这样我们能够重复使用通用 UI 代码,以及方便的在 View 中呈现 model 数据。并且我们的代码通过依赖注入可以很方便的进行测试,而不是使用单例(这部分内容可以参考这篇文章)。

    无论在哪个地方想使用 User 渲染 Cell,我们都可以简单地使用我们的 configurator。

    1. class UserListViewController: UITableViewController {

    2.    override func tableView(_ tableView: UITableView,

    3.                            cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    4.        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    5.        let user = users[indexPath.row]

    6.        configurator.configure(cell, forDisplaying: user)

    7.        return cell

    8.    }

    9. }

    View 工厂

    configurator 非常适合可复用的 View,例如 TableViewCell ,因为他们重用的时候需要不断 re-configurator(重新配置)来显示新的 model,但对于更多的 “static” View,通常只需要配置一次就够了,因为它们渲染的模型在他的生命周期内不会改变。

    这种情况下,使用工程模式可能是一个不错的选择。通过这种方式,我们可以将视图创建和配置捆绑在一起,同时仍然保持 UI 代码简单(与任何 model 分离)。

    假设我们想要重建一种简单的方式呈现应用消息。我们可能会有一个视图控制器来显示一条消息。以及某种形式的通知视图。当用户收到一条新消息时弹出一个 View,为了避免重复代码我们创建一个 MessageViewFactory 让我们轻松为给定的 message 创建视图。

    1. class MessageViewFactory {

    2.    func makeView(for message: Message) -> UIView {

    3.        let view = TextView()

    4.        view.titleLabel.text = message.title

    5.        view.textLabel.text = message.text

    6.        view.imageView.image = message.icon

    7.        return view

    8.    }

    9. }

    如上所示我们不仅使用通用的 TextView 来显示我们的消息(而不是专用类 MessageView),我们对外隐藏了具体的视图(我们的方法只返回 UIView)。就像在 Swift 中的代码封装 看到的一样,API 中删除具体类型可以在后期更便于修改。

    640?wx_fmt=gif

    ▼点击阅读原文获取文中链接

    展开全文
  • swift版本的model

    2017-06-06 16:33:45
    // Author.swift // FlowerField // // Created by CJW on 17/6/6. // Copyright © 2017年 cjw. All rights reserved. // import UIKit class Author: NSObject {  

    //

    //  Author.swift

    //  FlowerField

    //

    //  Created by CJW on 17/6/6.

    //  Copyright © 2017 cjw. All rights reserved.

    //


    import UIKit


    class Author: NSObject {

        //认证类型 专家

        var auth:String?

        //所在城市

        var city : String?

        //简介

        var content:String?

        //是否订阅

        var dingYue:Int = 0

        //头像

        var headImg:String?

            {

            didSet{

                if !(headImg?.hasPrefix("http://"))!{

                    headImg = "http://static.htxq.net/" + headImg!

                }

            }

        }

        // 用户ID

        var id : String?

        //标识:官方认证

        var identity:String?

        //用户名

        var userName : String?

        //手机号

        var mobile : Int64 = 15444354345

        //订阅数

        var subscibeNum : Int = 0

        // 认证的等级 1 yellow 2 是个人认证

        var newAuth:Int = 0{

            didSet{

                switch newAuth {

                case 1:

                    authImage = UIImage(named: "u_vip_yellow")

                case 2:

                    authImage = UIImage(named: "personAuth")

                default:

                    authImage = UIImage(named: "u_vip_blue")

                }

            }

        }

        var authImage : UIImage?

        // 经验值

        var experience : Int = 0

        // 等级

        var level : Int = 1

        // 积分

        var integral : Int = 0

        

        init(dict:[String:AnyObject]){

            super.init()

            setValuesForKeysWithDictionary(dict)

        }

        override func setValue(value: AnyObject?, forUndefinedKey key: String) {

        }



    }


    展开全文
  • Model层的两种写法

    2017-04-23 10:47:33
    Model层的两种写法  第一种写法 namespace MyMVC.Models { public class Child { //属性 private int id; public int Id { get { return id; } set {

    Model层的两种写法


              第一种写法

    namespace MyMVC.Models
    {
       public class Child
       {   
           //属性
           private int id;
           public int Id
           {
               get { return id; }
               set { id = value; }
           }
           private string strName;
           public string StrName
           {
               get { return strName; }
               set { strName = value; }
           }
        }
    }

              快捷键

              光标选择字段名称之后

              Ctrl+R+E,就会弹出封装字段对话框


              确定,应用即可


              或者是选择属性

              右键选择重构——封装字段

              同样弹出封装字段对话框,确定应用即可


              第二种写法

    namespace MyMVC.Models
    {
       public class Child
        {
           //属性
           public int id { get; set; }
           public string strName { get; set; }
        }
    }

              快捷键

              直接输入prop+TAB键


              修改字段类型,修改属性名称即可


              这里,可以使用VS的快捷键,选中某个单词Ctrl+Shift+W,封装字段,或者直接修改。

     

    展开全文
  • ASP.NET三架构框架自底向上分为: 数据访问(DAL),业务逻辑(BLL)和表示(UI) ...实体类(Model的创建: 首先,我们要明确数据库中有几张表,根据数据表的个数来创建相应个数的类(.cs文件)。

    ASP.NET三层架构框架自底向上分为:

    数据访问层(DAL),业务逻辑层(BLL)和表示层(UI)

    1、表示层(UI):就是展示给用户的界面,即用户在使用一个系统的时候他所看到的界面及功能。

    2、业务逻辑层(BLL):针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。

    3、数据访问层(DAL):该层直接操作数据库,实现数据的增删改查,以及SqlHelper的创建

    实体类(Model)层的创建:

    首先,我们要明确数据库中有几张表,根据数据表的个数来创建相应个数的类(.cs文件)。

    注意:因为数据库中有两张表,所以我们创建两个.cs文件,也就是创建两个类就可以了

    其次,根据数据库表中的列创建相对应的列,要和数据库数据保持一致性。

    /// <summary>
        /// 产品类
        /// </summary>
        public class Product
        {
            /// <summary>
            /// 主键Id	
            /// </summary>
            public int Id { get; set; }
            /// <summary>
            /// 产品名称
            /// </summary>
            public string ProductName { get; set; }
            /// <summary>
            /// 市场价
            /// </summary>
            public double MarketPrice { get; set; }
            /// <summary>
            /// 售价
            /// </summary>
            public double SellingPrice { get; set; }
            /// <summary>
            /// 类别Id
            /// </summary>
            public int CategoryId { get; set; }
            /// <summary>
            /// 产品介绍
            /// </summary>
            public string Introduction { get; set; }
            /// <summary>
            /// 是否上架
            /// </summary>
            public int IsOnSale { get; set; }
            /// <summary>
            /// 添加时间
            /// </summary>
            public DateTime AddTime { get; set; }
        }

     注意:在写类中列的时候,我们可以使用快捷键(输入 prop 然后双击Tab键),这是系统自带的快捷键,可以提高我们的写作速度,切记 一定要小写。

     

    展开全文
  • Swift 3 popup model dialog传递数据
  • Model (Fat Model):在Model 中对数据根据需要进行处理,让Controller可以直接使用经过处理后的数据。 瘦Model(Thin Model):Model中的数据不进行任何处理或修改,原封不动的把服务器返回内容发送给Controller...
  • JSON是移动端开发常用的应用数据交换协议。最常见的场景便是,客户端向服务端发起网络请求,服务端返回JSON文本,然后客户端解析这个JSON文本,再把对应数据展现到页面上。 但在编程的时候,处理JSON是一件麻烦事...
  • git地址:Swift JSON 转模型 只需要复制json 就可以转换为Swift 模型 JSONSwiftModel是一个Xcode插件,可以将json 转为模型 支持struct, class 所有值为可选 支持自定义遵循 和 import 如果图片不显示,请移步...
  • swift在4.0之前,一直没有一套数据解析的方法。现在4.0后,终于有了Codable可以直接将json转成对象,有望取代OC的KVC机制。 先来看看Codable public typealias Codable = Decodable & Encodable 基本...
  • JSON是移动端开发常用的应用数据交换协议。最常见的场景便是,客户端向服务端发起网络请求,服务端返回JSON文本,然后客户端解析这个JSON文本,再把对应数据展现到页面上。 但在编程的时候,处理JSON是一件麻烦...
  • 前言:Swift相对应Objective C来说,它不再需要绝大部分对象继承自NSObject,所以Swift的类型和Objective C的变量类型也不一致。 Value Type/Reference Type 什么是值类型,引用类型? 二者最主要的差别...
  • 构建数据 数据总体结构包括由CoreData构建的数据模型、通过AppDelegate构建相应的初始化对象。 coredata数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型。
  • swift3.0发布有一段时间了,发现很多朋友在swift3.0json解析上上遇到很多问题,我这边为大家提三种常见的json方案。 1.第一种是自带的字典转模型,自带的需要实现系统的setValue方法,然后自己还要实现dictToModel...
  • 现在有一个需求:需要加载本地plist文件中的数据,数据格式如下图所示: 即:数组里存放2个数组,然后这2个数组又... fileprivate lazy var sections = [[SettingModel]]() 第一种方式:双层for循环 le...
  • 本文旨在帮助开发者快速从OC开发过渡到Swift开发,挑选了一些比较浅显的但是比较常用的Swift语法特性,在介绍的过程中,通常会拿OC中的语言特性作比较,让大家更好的注意到Swift的不同。 另外需要说明的是,笔者也...
  • 刚开始时感觉有点扯淡 ,但是慢慢的机会发现 原来swift会让你的程序开发变得如此美妙,下面就是我理解的MVC中的M 修改 import 语句来引入 UIKit 代替 Foundation: import UIKit 默认 Swift 文件引入 ...
  • model基类与字典中嵌套数组Model的处理方法 RMBaseModel :Model基类 实现字典与model之间的转化实现Model的description RMFirstModel 继承自RMBaseModel处理字典中嵌套数组的问题 得到 Model中嵌套...
1 2 3 4 5 ... 20
收藏数 3,025
精华内容 1,210
关键字:

model层 swift