美文网首页iOS
【设计模式】适配器模式

【设计模式】适配器模式

作者: 刘大帅 | 来源:发表于2015-12-17 14:15 被阅读106次

    学习文章

    类图

    类适配器类图.png 对象适配器类图.png

    说明

    1. 类适配器: 通过继承要被适配的类,并实现新的接口要求(协议),来适配
    2. 对象适配器: 实现新的接口要求(协议),并引用要被适配的对象,通过判断对象的类型做出相应的处理,来适配

    源码

    StudentModel.swift

    import Foundation
    
    class StudentModel {
        
        var firstName  : String!
        var secondName : String?
        var lastName   : String!
        var studentAge : Int!
        var hobby      : String!
    }  
    

    TeacherModel.swift

    import Foundation
    
    class TeacherModel {
        
        var teacherName : String!
        var teacherAge  : Int!
        var major       : String!
    }  
    

    CardView.swift

    import UIKit
    
    enum CardViewError : ErrorType {
    
        case FrameTooSmallError
    }
    
    class CardView: UIView {
        
        var nameLabel        : UILabel!
        var ageLabel         : UILabel!
        var descriptionLabel : UILabel!
        
        override init(frame: CGRect) {
            
            let frameIsAvailable : Bool = frame.width >= 40 && frame.height >= 160
            
            assert(frameIsAvailable, "宽度应大于40,高度应大于160")
            
            super.init(frame: frame)
            
            self.nameLabel        = UILabel(frame: CGRect(x: 30, y: 30, width: frame.width - 30.0, height: 30))
            self.ageLabel         = UILabel(frame: CGRect(x: 30, y: 30 + 30 + 20, width: frame.width - 30.0, height: 30))
            self.descriptionLabel = UILabel(frame: CGRect(x: 30, y: 30 + 30 + 20 + 30 + 20, width: frame.width - 30.0, height: 30))
            
            self.addSubview(self.nameLabel)
            self.addSubview(self.ageLabel)
            self.addSubview(self.descriptionLabel)
            
            self.layer.borderWidth = 0.5
            self.backgroundColor   = UIColor.orangeColor()
        }
        
        convenience init(frame: CGRect, name: String, age: String, description: String ) {
            
            self.init(frame:frame)
            self.nameLabel.text        = name
            self.ageLabel.text         = age
            self.descriptionLabel.text = description
        }
        
        func loadData(data : ProfileProtocol) {
        
            self.nameLabel.text        = data.name
            self.ageLabel.text         = data.age
            self.descriptionLabel.text = data.description
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    }
    

    ProfileProtocol.swift

    import Foundation
    
    protocol ProfileProtocol {
    
        var name        : String {get}
        var age         : String {get}
        var description : String {get}
    }  
    

    StudentModelAdapter.swift

    import UIKit
    
    // StudentModel 类适配器
    
    class StudentModelAdapter: StudentModel, ProfileProtocol {
    
        var name : String {
        
            get {
            
                return self.firstName + " " + self.lastName
            }
        }
        
        var age : String {
        
            get {
            
                return "\(self.studentAge)"
            }
        }
        
        var description : String {
        
            get {
            
                return self.hobby
            }
        }
        
    }  
    

    TeacherModelAdapter.swift

    import UIKit
    
    // TeacherModel 类适配器
    
    class TeacherModelAdapter: TeacherModel, ProfileProtocol {
    
        var name : String {
            
            get {
                
                return self.teacherName
            }
        }
        
        var age : String {
            
            get {
                
                return "\(self.teacherAge)"
            }
        }
        
        var description : String {
            
            get {
                
                return self.major
            }
        }
    }  
    

    CommanAdapter.swift

    import UIKit
    
    // 对象适配器
    
    class CommanAdapter: ProfileProtocol {
        
        var model : AnyObject
        
        init(model : AnyObject) {
            
            self.model = "Error Model"
            
            if model.dynamicType == StudentModel.self {
            
                self.model = model as! StudentModel
                
            } else if model.dynamicType == TeacherModel.self {
            
                self.model = model as! TeacherModel
            }
        }
    
        var name : String {
            
            get {
    
                if self.model.dynamicType == StudentModel.self {
                
                    let studentModel = model as! StudentModel
                    
                    return studentModel.firstName + " " + studentModel.lastName
                    
                } else if self.model.dynamicType == TeacherModel.self {
                
                    let teacherModel = model as! TeacherModel
                    
                    return teacherModel.teacherName
                }
                
                return "Error Name"
            }
        }
        
        var age : String {
            
            get {
                
                if self.model.dynamicType == StudentModel.self {
                    
                    let studentModel = model as! StudentModel
                    
                    return "\(studentModel.studentAge)"
                    
                } else if self.model.dynamicType == TeacherModel.self {
                    
                    let teacherModel = model as! TeacherModel
                    
                    return "\(teacherModel.teacherAge)"
                }
                
                return "Error Age"
            }
        }
        
        var description : String {
            
            get {
                
                if self.model.dynamicType == StudentModel.self {
                    
                    let studentModel = model as! StudentModel
                    
                    return studentModel.hobby
                    
                } else if self.model.dynamicType == TeacherModel.self {
                    
                    let teacherModel = model as! TeacherModel
                    
                    return teacherModel.major
                }
                
                return "Error Description"
            }
        }
        
    }
    

    ViewController.swift

    import UIKit
    
    class ViewController: UIViewController {
    
        var cardView : CardView!
        
        override func viewDidLoad() {
            
            super.viewDidLoad()
    
            self.buildCardView()
            
            // 我们要实现一个名片,但是model提供的数据并不能直接给CardView使用,这样的情况就需要我们使用适配器模式
            // 我们定义一个协议来满足CardView对数据的要求,并为CardView添加方法 loadData(data : ProfileProtocol)来加载数据
            
            self.useClassAdapter()
            
    //        self.useObjectAdapter()
        }
        
        /**
         创建名片View
         */
        func buildCardView() {
        
            self.cardView = CardView(frame: CGRect(x: 50, y: 50, width: 250, height: 200))
            self.view.addSubview(self.cardView)
        }
        
        /**
         使用类适配器
         */
        func useClassAdapter() {
        
            let studentModel = StudentModelAdapter()
            studentModel.firstName  = "Jim"
            studentModel.lastName   = "Green"
            studentModel.studentAge = 17
            studentModel.hobby      = "Play BasketBall"
            
            self.cardView.loadData(studentModel)
        }
        
        /**
         使用对象适配器
         */
        func useObjectAdapter() {
        
            let teacherModel = TeacherModel()
            teacherModel.teacherName = "Steve Jobs"
            teacherModel.teacherAge  = 45
            teacherModel.major       = "Coding"
            
            let commonAdapter = CommanAdapter(model: teacherModel)
            
            self.cardView.loadData(commonAdapter)
        }
    }
    

    下载源码

    SwiftAdapterPattern

    相关文章

      网友评论

        本文标题:【设计模式】适配器模式

        本文链接:https://www.haomeiwen.com/subject/atlphttx.html