zoukankan      html  css  js  c++  java
  • 基本模式

    • Layer Supertype层超类型
      • 某一类型充当一层中所有类型的超类型.(DomainObject).
      • 运行机制
        • 当软件某一层中所有对象有公共特征时,可以将这些特征提取到一个超类上去.
    • Separated Interface分离接口
      • 在一个包中定义接口,而在另一个与之分离的保重实现该接口.
        • 为了减少系统部件间的耦合,将类分组,然后组织成包,并限制包间的依赖关系.同时约定包间调用的约束.
        • 但是,可能会出现与包间通用的一般性依赖关系有冲突的调用关系.
        • 此时,使用分离接口.一个包中定义接口,而在另一个包中实现它.
        • 分离接口为入口提供了一个很好的插入点.
      • 运行机制
        • 实现类对接口存在依赖,反之没有.
        • 所以,实现包到接口包有依赖.其它包仅依赖于接口包,而忽略掉实现包.
        • 当然,还是需要将接口和实现连接起来
          • 可以在编译时使用另一个独立的包来完成.
          • 或者在软件配置时使用插件模式.
        • 接口的放置位置
          • 当只有一个客户,或者所有客户都在同一包中.则可以将接口放在客户包中.由客户负责定义接口.
          • 若有多个客户包,则定义一个第三方的接口包比较好.或者需要有实现包来定义接口规范时.
      • 使用时机
        • 需要打破两个部分之间的依赖时
          • 一层需要调用另一层的代码,但是调用者却不知道被调用者的存在.如领域层调用数据映射层.
          • 需要调用别人的函数,但是不想与他们提供的API产生依赖.
          • 框架包中包含了一些通常情况的抽象代码,而框架包需要调用一些特定应用代码.
        • 该模式的依赖管理过于复杂
          • 对于小系统,在创建对象时与实现类建立依赖,而后只使用接口就可以了.
          • 保持接口和实现的分离需要额外的工作.一般还需要创建接口和实现的工程类.
          • 只有当需要打破依赖关系,或者同一接口有多个独立的实现时,才需要使用分离接口.
          • 一般吧实现和接口放在一起,将来需要时在重构即可.
    • Registry注册表
      • 一个well-known对象,其他对象通过它可以找到公共的对象和服务.
        • 在定位某一对象时,需要从管理对象入手.当没有合适的初始对象时,需要某种查找方法.
      • 运行机制
        • 在注册表接口中使用静态方法.
          • 方便其他类查找.
        • 数据的保存,应首先考虑数据的作用域
          • 不同作用域要求不同的实现,但是有一致的接口.
          • 进程.
            • 可以使用静态域.
            • 但是静态域的问题是不可替换性.
            • 也可以考虑Singleton.但是这样的问题在于多线程时的复杂同步代码.
          • 线程.使用词典.以线程为键,值为线程的数据对象.
          • 会话.使用词典.
        • 分割
          • 以使用方式而非实现来分割.可以有N个Registry.
      • 使用时机
        • Registry本质上是一个全局数据.
        • 一般使用常规的对象间引用来访问对象.有多种替代方案
          • 通过参数传递常用数据.问题是会在N层中出现无谓的参数传递开销.
          • 在对象创建时把指向公共数据的引用传递给它.当数据只被部分类使用时比较合适.
        • 每当增加新类型的数据时,都需要更新Registry.
        • 好处是显示的方法接口.
          • 使用映射存储全局数据,是隐式的.
    • Value Object值对象
      • 一个如货币/日期范围这样的小而简单的对象,判等时并不根据其ID.
        • 类似于原始类型.
      • 运行机制
        • 值对象是小对象,引用对象是大对象.
        • 关键区别还是判等方法.引用对象基于标识.值对象基于类内部的属性值.
        • 值对象小且易于创建,作为参数传递时传值而不是引用.
        • 值对象应作为嵌入值/序列化LOB,而非完整记录来进行持久化.
      • 使用时机.
        • 判等不基于标识.小且易于创建.
    • Special Case特殊情况
      •  
      • 针对特殊情况提供特殊行为的子类
        • 空值.破坏多态性.必须在可能为空的环境中加入判断.如果多个地方有相似的判空逻辑,造成了冗余代码.
        • 数字中的"无限"....
        • 处理:返回一个特殊情况.它具有与调用者预期相同的接口.而非返回空值或某个奇怪的值.
      • 运行机制
        • 创建一个特殊情况子类,重置所有的方法,提供一些无害的行为.
        • 通常不需要区分是否是特殊情况(是否是空客户).
        • NaN就是特殊情况的实例.
      • 使用时机
        • 当很多地方都需要对某一特定类的实例进行条件检测,然后做相同的动作时.
    • Plugin插件
      • 在配置时而非编译时进行类链接.
        • 代码需要在多个环境中运行,且每个环境下对特定行为需要不同的实现时.通常会使用分离接口模式.
        • 之后,工厂方法负责在特定环境下返回需要的实现.
        • 当工厂数目变多时,难以维护以后的变更.
        • 插件模式通过提供集中化的,运行时配置来解决.
      • 运行机制
        • 首先,通过分离接口来定义那些在不同环境下有不同实现的行为.
        • 然后使用基本工厂模式.
        • 特定环境下,接口与那个实现连接的指定需要在一个单独的,代码之外的地方进行声明,以获取可管理性.
          • txt即可很好的描述链接规则.
          • 插件工厂只是简单滴读取txt,来查找当前环境下所需接口对应哪一个具体实现项,然后返回该相应实现.
        • 与实现的链接必须在运行时动态进行,这样在重新配置后无需重新编译.
          • 配合反射机制.工厂可以动态地构建实现对象.
          • 配置文件必须包含从接口名到实现类型的映射.
      • 使用时机
        • 行为在不同运行环境下要求不同的实现时,应该使用插件模式.
    • Service Stub服务桩
      • 在测试时移出对有问题的服务的依赖.
        • 对于第三方的服务.在开发阶段.使用真实的服务来进行测试是很难实现的(远程的,耗时的...)
        • 在测试时,用运行在本地的,快速的,位于内存中的服务桩来代替第三方服务来推进开发进度.
      • 运行机制
        • 首先,使用入口来定义一个服务的访问点.入口应该是一个分离接口.
        • 然后,针对该入口接口,有一个调用实际服务的实现(发布时),和一个服务桩的实现(测试时).
        • 所需的入口实现以插件的方式载入.
        • 服务桩的关键在于简单.
        • 也就是单元测试中的Mock Object.模拟对象.
    • Record Set记录集
      • 表格数据在内存中的表现形式.
        • 看起来像数据库查询的结果.但是可以在其上附加业务逻辑部件.
        • 能够断开记录集与其数据源链接的能力.可以序列化记录集,从而将其作为DTO来传输.
        • 可以当做工作单元的一种形式.对其中数据的更新,可以使用乐观离线锁来检测是否存在冲突,没有冲突时将数据回写到DB中.
  • 相关阅读:
    P2679 子串
    线段树优化建边
    P2444 [POI2000]病毒
    P3966 [TJOI2013]单词
    4327: JSOI2012 玄武密码
    UVA1449 Dominating Patterns
    P1250 种树
    P2255 [USACO14JAN]记录奥林比克
    SP283 NAPTIME
    P3436 [POI2006]PRO-Professor Szu
  • 原文地址:https://www.cnblogs.com/robyn/p/3529573.html
Copyright © 2011-2022 走看看