代理模式在软件开发中经常用到,它是指为对象提供一种的代理,以控制对这个对象的直接访问。代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。
代理模式分文:静态代理和动态代理
优点: 1、职责清晰。 2、高扩展性。 3、智能化。
缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
使用场景:按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。
注意事项: 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
把一项能力抽象成接口,让真实类和代理类同时实现,然后让代理类持有真实类的引用对象,在代理类实现的接口方法中来调用真实类对应的接口方法,在外部想使用真实类的这项能力的时候,通过调用代理类的方法来达到调用真实类的方法,这样外部就不能直接访问和修改真实类了,只能通过代理类,而代理类我们只暴露了我们想让外部访问和修改的逻辑,这就起到了保护真实类的作用,同时我们还可以在代理类中增加一些真实类没有的功能的代码,这样就起到了增强真实类的作用。
- //小明 通过 张三 通过送礼物去追求 小红
- //把送礼物这个能力抽象成接口
- interface GiveGift {
- fun giveFlowers()
- fun giveChocolate()
- fun giveDolls()
- }
-
- //真实的追求者
- class Pursuit(val name: String) : GiveGift {
- override fun giveFlowers() {
- print("${name}送鲜花")
- }
-
- override fun giveChocolate() {
- print("${name}送巧克力")
- }
-
- override fun giveDolls() {
- print("${name}送洋娃娃")
- }
- }
-
- //代理 帮真实追求者送礼物的
- //参数是被追求者的名字
- class Proxy(val pursuedName : String) : GiveGift {
- //在代理类中,被追求者和追求者互相不认识,达到了保护的作用
- var pursuit: GiveGift? = null
-
- override fun giveFlowers() {
- run{
- pursuit ?: Pursuit("小明")
- }.giveFlowers()
- print("给$pursuedName")
- println()
- }
-
- override fun giveChocolate() {
- run{
- pursuit ?: Pursuit("小明")
- }.giveChocolate()
- print("给$pursuedName") //代理认识被追求者,起到了增强的作用,没有简单地代理送礼物的功能,而是帮助追求者送给了代理认识的人
- println()
- }
-
- override fun giveDolls() {
- run{
- pursuit ?: Pursuit("小明")
- }.giveDolls()
- print("给$pursuedName")
- println()
- }
-
- }
-
- fun main() {
- //真实追求者小明
- val pursuit = Pursuit("小明")
- val proxyZhangSan = Proxy("小红")
- proxyZhangSan.pursuit = pursuit
- proxyZhangSan.giveDolls()
- proxyZhangSan.giveFlowers()
- proxyZhangSan.giveChocolate()
- }