设计模式总结之四行为型模式(2)

六、策略模式

 

策略模式

作用:

策略模式(对象行为型)定义了算法家族Strategy,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

要点:

1、定义算法的公共接口Strategy

2、定义算法连接的上下文类Context,其中保存一个Strategy的引用,Context中的contextTodo()调用的是strategy.todo();

备注:

        策略模式就是用来封装算法的,但在实践中,几乎可以用他来封装任何类型的规则,需要在不同时间应用不同的业务规则的地方,就可以考虑使用策略模式处理这种变化的可能性

         继承提供了一种支持多种算法或行为的方法,我们可以直接生成一个类A的子类BCD,从而给他以不同的行为,但这样会将行为硬行编制到父类A中,而将算法的实现与类A的实现混合起来,从而使得类A难以理解、维护和扩展,而且还不能动态地改变算法。仔细分析后发现,其实他们之间的唯一差别就是所使用的算法或行为,如果将算法封装在独立的策略Strategy类中,这样就可以独立于类A改变它,让它易于切换、理解和扩展。

 

七、中介者模式

中介者模式

 

 

作用:

(对象行为型)用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使耦合松散,而且可以独立地改变它们之间的交互。

要点:

1、定义一个国家接口Country,包含一个公用的算法todo()

2、定义一个中介者(联合国机构)接口Mediator,包含协调多个Country工作的coordinate()算法。

实现Country接口创建多个国家,每个国家都包含一个联合国机构Mediator的引用。并实现各自的外交处理方法todo()

3、定义一个安理会MediatorImpl实现联合国机构Mediator接口,包含所有国家Country实现类的引用。实现接口Mediatorcoordinate()方法,处理各国之间发起的请求。

4、客户端只调用country.todo()方法,mediator. coordinate()则在Country实现类内部,被隐式调用。

备注:

        中介者模式很容易在系统中应用,也很容易在系统中误,当系统出现了“多对多”交互复杂的对象群时,不要急于使用中介模式,而要先反思你的系统在设计上是不是合理。

        中介者模式一般用于一组定义良好的对象,但通信复杂的场合。以有想定制一个分布在多个类中的行为,而又不想生成太多子类的场合。

面向对象设计中鼓励将行为分布到各个对象中,这种分布可能会导致对象间有许多连接,可能每一个对象都需要知道其它许多对象,对象间的大量相互连接使得一个对象不大可能在没有其他对象的支持下工作。这对于应对变化是不利的,任何较大的改动都困难重重,中介者模式通过将集体行为封装成一个单独的中介者对象来避免这个问题。中介者负责控制和协调这些对象间的交互。让这些对象不再相互引用,从而减少了相互连接的数目。

 

八、解释器模式

解释器模式

 

作用

解释器模式(类行为型)定义一种语言,并用不同的解释器用来解释语言内容

要点:

1、定义语言类Context

2、定义解释器接口Expression,以Context实例为参数,定义解释方法interpret()

3、客户端通过不同实现不同的Expression,去分别解析Context中的内容,终结符表达式TerminalExpress实现与文法中终结符相关联的解释操作,非终结符表达式NonterminalExpression包含了一组Expression引用来解释不同的表达式。

/** 客户端 */

publicclass Client {

  publicstaticvoid main(String[]  args) {

    Context con = new Context(true);

    Expression and  = new And(new Is(),new Not());

    and.interpret(con);

  }

}

/**  与操作 */

publicclass And implements  Expression {

    private  Expression left;

    private  Expression right;

    public  And(Expression left, Expression right) {

       this.left = left;

       this.right = right;

    }

    publicboolean  interpret(Context text) {

       returnleft.interpret(text)  && right.interpret(text);

    }

}

/** 当前值 */

publicclass Is implements  Expression {

   publicboolean  interpret(Context text) {

      return  text.value();

   }

}

 

/** 非当前值 */

publicclass Not implements  Expression {

   publicboolean  interpret(Context text) {

      return  !text.value();

   }

}

 

备注

如果一种特定类型的问题发生的频率足够高,那么就可以考虑将该问题的各个实例表述为一个简单语言中的句子,然后通过构建一个解释器,解释这些句子以达到解决问题的目的。

解释器模式通过类来定义一个文法规则,可以通过继承来改变和扩展方法规则。但也正因为解释器为文法中的每一条规则至少定义了一个类,因此也使得包含许多规则的文法变得难以管理和维护,此时不建议使用解释器模式.解释器模式与命令模式的区别在于,解释器模式用于组合可执行对象形式工具集,这些对象来自于对某公共操作提供各种解释的类层次结构。而命令模式的意图仅仅是将多个请求封装在一个对象中.可以说解释器模式是命令模式的子模式。

解释器模式也类似于组合模式,组合模式通常会为单个对象和群组对象定义一个公共接口。不过,组合模式一般来讲对象的组织结构是相同的,当然它也支持不同方式的组织结构。而解释器模式通常会涉及不同类型的组合结构(所以说解释器通常处于组合模式之上)。

 

九、备忘录模式

 

备忘录模式

作用:

备忘录模式(对象行为型)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。以便以后恢复到先前保存的状态。

要点:

1、将需要保存的内部状态封装成类Memento

2、建立外部保存类Manager,里面包含Memento实例。

3、创建Originator,建立save()方法,用于返回Memento实例,客户端将该实例保存至manager中。同时originator也可通过rollback()方法恢复到先前状态。

备注:

备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么结合使用备忘录模式来存储可撤销操作的状态。

 

十、迭代器模式

 

迭代器模式

作用:迭代器模式(对象行为型)提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露该对象的内部表示。

要点

1、定义Iterator接口,里面包含取头元素,下一元素,判断是否有下一元素等方法2、定义集合Collection接口,通过iterator()方法获取一个Iterator实例。

3、实现Collection接口,创建数据集合类型CollectionImpl,通过List缓存所有的数据元素。

4、实现Iterator接口,创建针对CollectionImpl的迭代器IteratorImpl,其中保存一个CollectionImpl的引用,用于访问其中的元素。

备注:

迭代器模式的关键思想就是将对列表的访问和遍历从列表对象中分离出来并放入一个迭代器对象中,迭代器类定义一个访问该列表元素的接口,交负责跟踪当前的元素,知道哪些元素已经遍历过。

迭代器模式分享了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。当需要遍历一个聚集对象,而不去考虑这些对象的具体是什么时,就可以考虑用迭代器模式。

 

十一、访问者模式

访问者模式

 

作用:

访问者模式(对象行为型)把对数据元素的处理从数据结构中分离。通过一个作用于某对象结构中各元素的操作。使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

要点:

1、定义访问者Visitor接口,包含所有访问不同类型元素的方法。

2、定义Element接口,accept()方法用于接收一个访问者Visitor

3、根据集合对象中的不同元素种类,实现Element,通过accept对不同元素的访问权限进行控制,如果可以访问,则调用在Visitor中对应的访问方法Visitor.visitXElement()进行访问。

4、客户端使用时,只需要创建一个Visitor实例,然后通过遍历包含Element的集合对象,通过element.accept执行相应的操作。

/**客户端 */

publicclass Client {

    publicstaticvoid main(String[]  args) {

       List<Element>  list = new ArrayList<Element>();

       list.add(new AElement());

       list.add(new BElement());

       Visitor  visOne = new VisitorImpl();//访问者一

       Visitor  visTwo = new VisitorImpl2();//访问者二

       for (Element element  : list) {

           element.accept(visOne);

           element.accept(visTwo);

       }

    }

}

/** 类型A元素 */

publicclass AElement implements Element {

   publicvoid accept(Visitor  visitor) {

       visitor.visitAElement();

   }

}

/** 类型B元素 */

publicclass BElement implements Element {

    publicvoid accept(Visitor  visitor) {

       visitor.visitBElement();

    }

}

/**  访问者具体实现 */

publicclass VisitorImpl implements Visitor {

   publicvoid visitAElement()  {

       System.out.println("one");

   }

   publicvoid visitBElement()  {

       System.out.println("two");

   }

}

/**  访问者具体实现 */

publicclass VisitorImpl2 implements Visitor {

   publicvoid visitAElement()  {

       System.out.println("一");

   }

   publicvoid visitBElement()  {

       System.out.println("二");

   }

}

 

备注:

访问者模式把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化,访问者模式在对数据元素增加新的操作方面变得容易,但是由于访问者集合了所有数据结构的访问方法,如果要增加一种数据结构Element则变得尤为困难,因此访问者模式适用于数据结构相对稳定的系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值