设计模式沉思录_1

  1. 文件和目录的设计.
    1. 首先,必须有两个对象,File和Directory.
    2. 想以相同的方式处理文件和目录,所以必须有一个共通的接口Node.
      1. 对于以相同的方式处理那些不能适用于两者的操作时.
      2. 例如:Node GetChild(n).必须返回Node类型以在返回值上再次调用GetChild.也就要求必须在Node接口上定义该方法.
      3. 适用Composite模式的关键:想要表示对象的"部分-整体"层次结构,树结构支持任意的复杂度,以统一的方式处理结构中的对象.
      4. .
      5. Composite的坏处:每个对象的类和其他对象的类没有区别.区别只能在运行时才显露.
        1. 存储子节点时,应使用什么数据结构.
        2. 是否应该在Component类中声明添加和删除子节点的操作.
    3.  文件的创建和添加.
      1. 首先,文件的创建应该是用户的责任.目录只负责收养子节点. void adopt(Node Child).
      2. 相应地,目录可以解除该责任.void orphan(Node Child).但此时该节点依然存在,只是不属于该目录而已.
      3. 对于mkdir命令,传入的是一个路径,我们必须递归处理该路径,然后在最后一层上创建新目录,并收养它.
        1. 问题在于递归处理路径时,调用Node节点的GetChild来检查该Node是否有对应的子路径,返回的是Node类型,因为深入文件系统层次时,我们并不知道是文件还是目录.
        2. 所以,我们还是必须把adopt和orphan方法定义在Node上.只是Node中默认实现为抛出异常(或者其它的,代表不能进行该操作的).
        3. 然后在mkdir函数中,对于递归处理路径的结果,判断是否是目录,如果是目录就递归调用mkdir,如果是文件,就抛出异常(不正确的传入路径).
        4. 这就带来了不统一性的问题.但是对于这种不允许在Leaf上调用Leaf有关的操作时,是必须的.编译器必须知道这种区别.
        5. 这种不统一性,通常会带来简单性和扩展性.
    4. 引入代用品(快捷方式)
      1. 模式的选择:
        1. 考虑设计中那些部分是可变的
        2. 看那些模式的目的与要解决的问题对应.
        3. 我们选择Proxy模式:当我们需要对一个对象进行引用,但是该引用需要具备比简单指针更复杂的功能时.

        4.  Proxy的接口和Subject一致,所以能替代任何的Subject对象.Node代表了Subject对象.
        5. 新增一个继承自Node的Link类来代表Proxy,其内部有一个Node类型的对象指向RealSubject.(因为File和Directory有相同的接口.)
    5. 不对已有类进行改动就添加新操作.访问权限.
      1. Node现在承担了两种模式的责任,组件和代理模式.这是"密集"复合模式.可能会造成一个模式被实现后,可能丢失的问题.
      2. Node接口的关键是找出一组基本够用的最小的操作集合.
      3. 但是对于那么要以不同的方式处理不同的节点类型的操作.例如输入内容的cat命令.File和Directory会有不同的行为.我们为了引入该操作,必须修改既存的类?
      4.  我们也可以把该功能放入客户端代码,但是这样做的话,必须在该代码中进行向下转型.这太恶心了.
      5. 使用Visitor模式:表示一个用来处理某对象结构中各个元素的操作.无需修改待处理元素的类,就可以定义新的操作.
      6. 首先,在Node类中定义void accept(Vistor v).
      7. 然后,在各个子类中分别实现{v.visit(this);}.虽然3个子类的实现代码一样,但是由于this是不一样的,所以效果是不一样的.
      8. 再然后,在Class Visitor{ visit(File);visit(Directory);visit(Link);}.
      9. 客户端代码: Visitor cat; node.accept(cat);
      10. 当我们想添加另外的功能时.
        1. 首先,Visitor是一个接口.
        2. 然后,对于每一中功能,派生一个Visitor出来.
        3. 我们可以将Visitor接口中的3个重载函数重新定义.VisitFile(File);VisitDirectory(Directory);VisitLink(Link);
        4. Visitor模式的问题:
          1. 被访问的类层次结构是否稳定?是否会经常定义新的Node子类,这会代理修改Visitor类层次中的所有类.
          2. 如果所有的visitor对新的Node子类都不感兴趣,那么可以在VisitNode函数中进行默认处理.
          3. 但是只有一中类型的visitor对新子类感兴趣是,我们至少要修改该visitor和visitor基类.
          4. Visitor和Node类层次结构之间创建了循环依赖关系.任何一个基类的接口修改.都得重新编译.
    6. 单用户文件系统的保护
      1. 对不可写的节点进行保护,使之无法删除.我们采用了对析构函数进行保护的方法.声明为protected,这样在Node类层次结构之外的类是无法删除一个Node的.
      2. 谁来定义删除操作?在Node基类中定义destroy.
      3. 模板方法:将destroy定义为


posted on 2012-11-23 14:26  RobynHYB  阅读(397)  评论(0编辑  收藏  举报

导航