谈谈我现在使用的设计模式

2017-09-19  本文已影响574人  我要在河边钓一整天的鱼

1、传统的MVC

1.png

可以看出另外每个实体都知道另外两个实体,这显然降低了可重用性当然也不是您在开发中想要的。

2、苹果的MVC

2.png

这里View和Model的关系剪断,但是在Controller中会变得很臃肿,Controller中代码量会变得很大。想想将业务逻辑、网络请求、View状态改变还有把addSubView的代码也放在Controller中的,看了眼要修改的Controller是不是想死的心都有了。

3、我的MVC

设计模式不是死,根据自己的需求和理解进行一些改变是必要的,再变也是万变不离其宗,现在的项目的使用的MVC实际上就是对Controller的瘦身。上图是取自iOS Architecture Patterns,这里我直接说我的实现。

我的目录是根据模块进行分解然后在模块目录下创建MVC的文件夹,我不喜欢大的MVC文件目录然后吧相关的类放进对应的文件夹下的。


3.png

Model

和你所知MVC中的M是一样的

/
//  Model.swift
//  Test
//
//  Created by 小七 on 2017/9/19.
//  Copyright © 2017年 Seven. All rights reserved.
//

import UIKit

struct Model {
    var name: String?
}

View

我不会在Controller中写addSunViews这样的代码, 所以这样的代码全在封装带View中了,这里用的Storyboard。我将storyboard放在Controller中纯属个人习惯,我个人认为这个是属于View的

//
//  TableViewCell.swift
//  Test
//
//  Created by 小七 on 2017/9/19.
//  Copyright © 2017年 Seven. All rights reserved.
//

import UIKit

class MyTableViewCell: UITableViewCell {

    @IBOutlet weak var label: UILabel!
    
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Controller

Controller中含有Request和C->V的数值传递类, 在实际项目中将一部分的业务逻辑代码放在了ViewModel中了(这里的ViewModel并不是MVVM中所表达的意思,只是借鉴了一些思路)

//
//  ViewController.swift
//  Test
//
//  Created by 小七 on 2017/9/19.
//  Copyright © 2017年 Seven. All rights reserved.
//

import UIKit

class ViewController: UITableViewController {

    lazy private var mViewModel: ViewModel = ViewModel()
    lazy private var mRequest: Request = Request()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        mRequest.request {[weak self] in
            self?.tableView.reloadData()
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return mRequest.list.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell", for: indexPath) as! MyTableViewCell
        mViewModel.loadCellWithModel(mRequest.list[indexPath.row], view: cell)
        return cell
    }
}

ViewModel

这里做了数据的传递

//
//  ViewModel.swift
//  Test
//
//  Created by 小七 on 2017/9/19.
//  Copyright © 2017年 Seven. All rights reserved.
//

import UIKit

class ViewModel: NSObject {
    
    func loadCellWithModel(_ model: Model, view: MyTableViewCell) {
        view.label.text = model.name
    }
    
}

Request

网络请求的封装和Model的储存,我的Controller中是不储存Model的

//
//  Request.swift
//  Test
//
//  Created by 小七 on 2017/9/19.
//  Copyright © 2017年 Seven. All rights reserved.
//

import UIKit

class Request: NSObject {
    
    var list: [Model] = [Model]()
    
    func request(result: () -> Void){
        for _ in  0 ... 20 {
            var m = Model()
            m.name = "12345"
            list.append(m)
        }
        result()
    }
    
}

后语

实际上MVVM和MVP可以也可以解决C过于臃肿的问题。那为什么没有使用流行的MVVM呢,因为MVVM的实现离不开RX和RAC,主要项目中没有使用它们所以就没有直接引入MVVM(这个理由确实牵强 = =!),还有建议使用的所有第三方库最好自己进行封装下,不然在换库的时候会留下悔恨的泪水。

git地址go go

谢谢观赏,这里是我在项目中对MVC的理解,希望多多指正

参考 iOS Architecture Patterns

上一篇下一篇

猜你喜欢

热点阅读