代理模式
代理模式目的是为外部访问者提供一个代理对象,使得外部访问者不直接访问某个对象的情况下,通过代理类访问对象方法,产生的缺点就是会延迟相应方法的访问,其用法可分为静态代理和动态代理
静态代理
类图
实现
- 被代理对象的对外接口
interface Service {
fun visit()
}
- 被代理对象本体
class RealServer constructor( name:String):Service {
private val serverName:String=name
override fun visit() {
TODO("Not yet implemented")
}
}
- 代理类(核心)
class ProService constructor(name:String): Service {
private val realService:RealServer= RealServer(name)
override fun visit() {
realService.visit()
}
}
代理类只有被代理类的实例,对外接口部分都有被代理类执行,为其他对象提供一种代理以控制对这个对象的访问
动态代理
动态代理是程序运行时生成对目标的访问接口,常用的有JDK代理和CGLIB代理
代理模式的特点在于隔离,隔离调用类和被调用类的关系,通过一个代理类去调用,因此代理模式不需要传入原有的对象,内部会持有原有对象的实现
装饰器模式
装饰器模式主要对现有的类对象进行包裹和封装,以期望在不改变类对象及其类定义的情况下,为对象添加额外功能,这种装饰可以无限套用,套用过度可能使源码难以理解和管理
类图
实现
- 对象接口类
interface IShape {
fun draw()
}
- 原始类,(类比原始需求)
class Circle : IShape {
override fun draw() {
Log.i("test","draw a Circle")
}
}
- 装饰器 ,实现被装饰类相同接口,并要求传入被装饰对象(核心)
//装饰器抽象
abstract class CircleDecortor constructor(ishape:IShape) :IShape {
protected val shape:IShape=ishape
override fun draw() {
shape.draw()
}
}
- 增强类,装饰器实例,(类比新加需求)
class CircleColor constructor( ishape: IShape) : CircleDecortor(ishape) {
override fun draw() {
super.draw()
drawColor()
}
private fun drawColor(){
Log.i("test","draw color")
}
}
5.使用
public fun initDecortor(){
val circle : Circle= Circle();
circle.draw()
val circleColor=CircleColor(circle);
circleColor.draw()
}
装饰器模式特点在于增强,他的特点是被装饰类和所有的装饰类必须实现同一个接口,而且必须持有被装饰的对象,可以无限装饰,被装饰对象通过构造函数传入,上面的例子中
CircleColor
增强了Circle
类,装饰器的draw()
方法运行时也会自行被装饰器的该方法。
#适配器模式
把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法工作的两个类能够在一起工作,所以这种模式使用一般出现在已经写了某个类情况下,现场景不能直接使用该类,通过添加新接口使得该类得以复用
类适配器
通过类继承实现适配,继承Target的接口,继承Adaptee的实现
类图
实现
- 定义新接口
//目标接口
interface IClient {
fun request()
}
- 继承适配类并实现新接口(核心),通过调用父类实现对新接口填充
//适配器类
class Adapter :BeAdapter(),IClient {
override fun request() {
super.adapteRequest()
}
}
3.使用
public fun initAdapter(){
val client:IClient=Adapter()
client.request()
}
对象适配器
通过类对象组合实现适配
类图
实现
- 通过内部持有被适配对象,重新实现接口,与代理的写法很像,但目的完全不同,适配器是为了新的接口,代理是为了隔离原对象,实现的是原接口
class ObjAdapter : IClient {
private val adapter=BeAdapter()
override fun request() {
adapter.adapteRequest()
}
}
- 使用
public fun initObjAdapter(){
val client:IClient=ObjAdapter()
client.request()
}
适配器的特点在于兼容,适配器模式需要实现新的接口,代理,装饰器模式是与原对象实现同一个接口,而适配器类则是匹配新接口