设计模式之结构型模式

结构型模式

  核心作用: 是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题
  分类: 适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式
汇总:

  • 代理模式: 为真实对象提供一个代理,从而控制对真实对象的访问
  • 适配模式: 使原本由于接口不兼容不能一起工作的类可以一起工作
  • 桥接模式: 处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联
  • 组合模式: 将对象组合成树状结构以表示"部分和整体"层次结构,使得客户可以统一的调用叶子对象和容器对象
  • 装饰模式: 动态地给一个对象添加额外的功能,比继承灵活
  • 外观模式: 为子系统提供统一的调用接口,使得子系统更加容易使用
  • 亨元模式: 运用共享技术有效的实现管理大量细粒度对象,节省内存,提高效率

适配器adapter模式

  将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作

  模式中的角色

  • 目标接口(Target): 客户所期待的接口。目标可以是具体的或抽象的类也可以是接口
  • 需要适配的类(Adaptee): 需要适配的类或适配者类
  • 适配器(Adapter): 通过包装一个需要适配的对象,把原接口转换成目标接口
     
    工作中的场景
  • 经常用来做旧系统改造和升级
  • 如果我们的系统开发之后再也不需要维护,那么很多模式都是没有必要的,但是不幸的是,事实却是维护一个系统的代价往往是开发一个系统的倍数

标题代理模式(Proxy pattern)

  通过代理,控制对象的访问
  可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理,(即AOP的微观实现)
  核心角色
    抽象角色: 定义代理角色和真实角色的公共对外方法
    真实角色: 实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用关注真正的业务逻辑
    代理角色: 实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作
    将统一的流程控制放到代理角色中处理

  应用场景
    安全代理: 屏蔽对真实角色的直接访问
    远程代理: 通过代理类处理远程方法调用(RMI)
    延迟加载: 先加载轻量级的代理对象,真正需要再加载真实对象
    比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来进行大图片的打开

  分类
    静态代理(静态定义代理类)
    动态代理(动态生成代理类)
      JDK自带的动态代理
      javaassist字节码操作库实现
      cglib
      ASM(底层使用指令,可维护性较差)
  动态代理的优点
    抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和统一的处理众多的方法
  JDK自带的动态代理
    java.lang.reflect.Proxy
      作用:动态生成代理类和对象
    java.lang.reflect.InvocationHandler(处理器接口)
      可以通过invoke方法实现对真实角色的代理访问
      每次通过Proxy生成代理类对象时都要指定对应的处理器对象
  应用场景
    mybatis中实现拦截器插件
    AspectJ的实现
    spring中AOP的实现
      日志拦截
      声明式事务处理

桥接模式

处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联
  桥接模式总结
    桥接模式可以取代多 层继承的方案,多层继承违背了单一职责原则,复用性较差,类的个数也非常多,桥接模式可以极大的减少子类的个数,从而降低管理和维护的成本
    桥接模式极大的提高了系统可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则。
  实际开发中的应用场景
    JDBC驱动程序
    AWT中的Peer架构
    银行日志管理:
      • 格式分类:操作日志、交易日志、异常日志
      • 距离分类:本地记录日志、异地记录日志
    人力资源系统中的奖金计算模块:
      • 奖金分类:个人奖金、团体奖金、激励奖金。
      • 部门分类:人事部门、销售部门、研发部门。
    OA系统中的消息处理:
      • 业务类型:普通消息、加急消息、特急消息
      • 发送消息方式:系统内消息、手机短信、邮件

组合模式

  使用场景: 把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象
  核心: 抽象构建(Component)角色:定义了叶子和容器构建的共同点
      叶子(Leaf)构件角色:无子节点
      容器(Composite)构件角色:有容器特征,可以包含子节点
  工作流程
    组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子
    当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行,其中,使用了递归调用的机制对整个结构进行处理

装饰模式(decorator)

  动态的为一个对象增加新的功能
  装饰模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能,使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀
  实现细节
    Component抽象构件角色
      真实对象和装饰对象有相同的接口,这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互
    ConcreteCompoent具体构件角色(真实对象)
      io流中的FileInputStream、OutputStream
    Decorator装饰角色
      持有一个抽象构件的引用,装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能
    ConcreteDecorator具体装饰角色
      负责给构件对象增加新的责任
  总结
    装饰模式(Decorator)也叫做包装器模式(Wrapper)
    装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类
    
  优点
    扩展对象功能,比继承灵活,不会导致类个数急剧增加
    可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
    具体构建类和具体装饰类可以独立变化,用户可以根据需要增加增加新的具体构建子类和具体装饰子类
  缺点
    产生很多小对象,大量小对象占据内存,一定程度上影响性能
    装饰模式易于出错,调试排查比较麻烦
    
  装饰模式和桥接模式的区别
    两个模式都是为了解决过多子类对象问题,但它们有因不一样,桥模式是对象自身实现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能

外观模式

  一个软件实体应当尽可能少的与其他实体发生相互作用
  为子系统提供统一的入口,封装子系统的复杂性,便于客户端调用

享元模式

  内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的对象,我们可以通过享元模式,节省内存。
  享元模式以共享的方式高效地支持大量细粒度对象的重用
  享元对象能做到共享的关键是区分了内部状态和外部状态
    内部状态: 可以共享,不会随环境变化而改变
    外部状态: 不可以共享,会随环境变化而改变
    
  围棋软件设计
    每个围棋棋子都是一个对象
      可以共享的称之为内部状态:颜色、形状、大小
      不可以共享的称之为外部状态:位置
      
  享元模式实现
    FlyweightFactory享元工厂类
      创建并管理享元对象,享元池一般设计成键值对
    FlyWeight抽象享元类
      通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态
    ConcreteFlyWeight具体享元类
      为内部状态提供成员变量进行存储
    UnsharedConcreteFlyWeight非共享享元类
      不能被共享的子类可以设计为非共享享元类
      
  优点
    极大减少内存中对象的数量
    相同或相似对象内存中只存一份,极大的节约资源,提高系统性能
    外部状态相对独立,不影响内部状态
  缺点
    模式较复杂,使程序逻辑复杂化
    为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态使运行时间变长。用时间换取了空间

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值