12.ProxyPattern - QDDCoder/LZLearniOS GitHub Wiki

代理模式

解释地址 https://www.runoob.com/design-pattern/proxy-pattern.html

在代理模式Proxy Pattern一个类代表另一个类的功能这种类型的设计模式属于结构型模式在代理模式中我们创建具有现有对象的对象以便向外界提供功能接口意图为其他对象提供一种代理以控制对这个对象的访问主要解决在直接访问对象时带来的问题比如说要访问的对象在远程的机器上在面向对象系统中有些对象由于某些原因比如对象创建开销很大或者某些操作需要安全控制或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦我们可以在访问此对象时加上一个对此对象的访问层何时使用想在访问一个类时做一些控制如何解决增加中间层关键代码实现与被代理类组合优点1职责清晰2高扩展性3智能化缺点1由于在客户端和真实主题之间增加了代理对象因此有些类型的代理模式可能会造成请求的处理速度变慢2实现代理模式需要额外的工作有些代理模式的实现非常复杂使用场景按职责来划分通常有以下使用场景1远程代理2虚拟代理3Copy-on-Write 代理4保护Protect or Access代理5Cache代理6防火墙Firewall代理7同步化Synchronization代理8智能引用Smart Reference代理注意事项1和适配器模式的区别适配器模式主要改变所考虑对象的接口而代理模式不能改变所代理类的接口2和装饰器模式的区别装饰器模式为了增强功能而代理模式是为了加以控制

1.创建一个接口

protocol Image {
    func display()
}

2.创建实现接口的实体类。

class RealImage: NSObject,Image {
    var fileName:String?
    init(withFileName fileName:String) {
        super.init()
        self.fileName = fileName
        loadFromDisk(withFileName: fileName)
    }
    
    func display() {
        if let fileName = fileName {
            print("Displaying: "+fileName)
        }
    }
    
    func loadFromDisk(withFileName fileName:String)  {
        print("Loading: "+fileName)
    }
}

//代理层
class ProxyImage:NSObject,Image {
    private var realImage:RealImage?
    private var fileName:String=""
    
    init(withFileName fileName:String) {
        super.init()
        self.fileName = fileName
    }
    
    func display() {
        if realImage == nil {
            realImage = RealImage(withFileName: fileName)
        }
        realImage?.display()
    }
}
  • 测试

let image = ProxyImage(withFileName: "test_10mb.jpg")
//图像从磁盘加载
image.display()
print("")
//图像不需要从磁盘加载
image.display()
  • 测试结果

Loading: test_10mb.jpg
Displaying: test_10mb.jpg

Displaying: test_10mb.jpg
⚠️ **GitHub.com Fallback** ⚠️