Java经典23种设计模式之行为型模式(四)

本文介绍11种行为型设计模式里的策略模式、模板方法、访问者模式。

一、策略模式

定义一系列的算法,把它们每个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

1.Strategy定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法。

public abstract class Strategy {
    public abstract void method();
}

2.ConcreteStrategy以Strategy接口实现某具体算法。

public class *trategyImplA extends Strategy {

    public voi* method() {
        System.out.println("这是第一个实现");
    }
}

public class StrategyImplB extends Strategy {

    public void method() {
        System.out.println("这是第二个实现");
    }
}

public class StrategyImplC extends Strategy {

    public void method() {
        Syst*m.out.println("这是第三个实现");
    }
}

3.Context用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Stategy访问它的数据。

pub*ic class Context {

Strategy stra;
    
    public Cont*xt(Strategy stra) {
        this.stra = stra;
    }
    
    pub*ic void doMethod() {
        stra*method();
    }
}

测试代码:

public class Test {

    public static void main(String[] ar*s) {
        Context ctx = new C*ntext(new StrategyImplA());
        ctx.doMethod();

        ctx = new Context(new *trategyImplB());
        ctx.doMethod();

        ctx = new Context(new StrategyImplC());
        ctx.doMethod();
    }
}

适应性:

1.许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
2.需要使用一个算法的不同变体。
3.算法使用客户不应该知*的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4*一个类定义了多种行为,并且这些行为在这个类的操作中以*个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

二、模板方法

定义每个操作中的算法的骨架,*将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

1.AbstractClass定义抽象的原语操作(primitiveoperation),具体的子类将重定义它们以实现一个算法的各步骤。实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。

public abstract class Template {

public abstract void print();
    
    public void update() {
        System.out.println("开始打印");
        for (int i = 0; i < 10; i++) {
            print();
        }
    }
}

2.ConcreteClass实现*语操作以完成算法中与特定子类相关的步骤。

public class TemplateConcrete extends Template {

@override
    public void print() {
        System.out.println("这是子类的实现");
    }
}

测试代码:

public class Test {

pu*lic static void main(String[] args) {
        Te*plate temp = new TemplateConcrete();
        temp.update();
    }
}

适用性:

1.一次性实现一个算法的不变的部分,并将可变的*为留给子类来实现。
    2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有*码中的不同之处,并且将不同之处分离为新的操作。最后,用*个调用这些新的操作的模板方法来替换这些不同的代码。
    3.控制子类扩展。

三、访问者模式

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

1.Visitor为该对象结构中ConcreteEle*ent的每一个类声明一个Visit操作。该操作的名字和特征标识了发送*isit请求给该访问者的那个类。这使得访问者可以确定正被访问元素*具体的类。这样访问者就可以通过该元素的特定接口直*访问它。

public interface Visitor {

public void visitString(StringElement stringE);
    
    public void visitFloat(FloatElement floatE);
    
    public void visitCollection(Collection collection); 
}

2.Concret*Visitor实现每个由Visitor声明的操作。每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。Concret*Visitor*该算法提供了上下文并存*它的局部状态。
这一状态常常在遍历该结构的过程中累*结果。

public class C*ncreteVisitor implements Visitor {

    public void visitCollectio*(Collection colle*tion) {
        // TODO Auto-generated method stub
        Iterator iterator = collection.iterator();
        while (iterator.hasNext()) {
            Object o = iterato*.next();
            if (o in*tanceof Visitable) {
                (*Visitable)o).accept(this);
            }
        }
    }

    public void visitFloat(FloatElement floatE) {
        System.out.println(floatE.getFe*));
    }

    public void visitString(StringElement stringE) {
        System.out.println(stringE.getSe());
    }
}

3.Element
      定义一个Accept操作,它以一个访问者为参数。

public interface Visitabl* {

publ*c void accept(Visitor visitor);
}

4.ConcreteElement
      实现Accept操作,该操作以一个访问者为参数。

public class FloatElement implements Visitable {

    private Float fe;

    public FloatElement(Float fe) {
        this.fe = fe;
    }

    public Float getFe() {
        return this.fe;
    }

    public void accept(Visitor visitor) {
        visitor.*isitFloat(this);
    }
}

public class StringElement implements Visitable *

    private String se;

    public String*lement(String se) {
        this.se = se;
    }

    public String getS*() {
        return thi*.se;
    }

    public void accept(Visitor visitor) {
        visitor.visitString(this);
    }
}

测试代码:

public class Test {

    public static void main(String[] args) {
        Visitor visitor = new ConcreteVisitor();
        StringElement se = new StringElement("abc");
        s*.accep*(visitor);

        Fl*atElement fe = new FloatElement(n*w Float(1.5));
        fe.accept(visitor);
        S*stem.out.println("===========");
        List result = new ArrayList();
        result.add(new StringEle*ent("abc"));
        result.a*d(new StringElement("abc"));
        result.add(*ew StringElement("abc"));
        result.add(new FloatElement(new Float(1.5)));
        result.add(new FloatElement(new Float(1.5)));
        result.add(new FloatElement(new Float(1.5)));
        visitor.visitCollection(result);
    }
}

适应性:

1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操*。
   2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,*你想避免让这些操作“污染”这些对象的类。
      Visitor使得你可以将相关的操作集中起来定义在一个类中。
      当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
    3.定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。
      改变对象结构类需要重定义对所有访问者的接口,这可能*要很大的代价。
      如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

时间: 2024-10-17 11:42:20

Java经典23种设计模式之行为型模式(四)的相关文章

Java经典23种设计模式之行为型模式(三)

本文接着介绍11种行为型模式里的备忘录模式.观察者模式.状态模式. 一.备忘录模式 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态.还是比较好理解的. 1.Memento 备忘录存储原发器对象的内部状态,这个类就是要存储的对象的状态.状态需要多少个变量,在Memento里就写多少个变量. public class Memento { private String state; public Meme*to(String st

Java经典23种设计模式之行为型模式(一)

行为型设计模式有11种,分别是Chain of Responsibility ( 责任链模式 ).Command ( 命令模式 ).Interpreter ( 解释器模式 ) .Iterator ( 迭代器模式 ).Mediator ( 中介者模式 ) .Memento ( 备忘录模式 ) .Observer ( 观察者模式 ).State ( 状态模式 ) .Strategy ( 策略模式 ).TemplateMethod ( 模板方法 ).Visitor ( 访问者模式 ),本文介绍这11种

Java经典23种设计模式之行为型模式(二)

本文接着介绍行为型模式里的解释器模式.迭代器模式.中介者模式. 一.解释器模式Interpret 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言的中的句子. 1.AbstractExpression(抽象表达式) 声明一个抽象的解释操作,这个接口为抽象语法树中全部的节点所共享. public abstract class Expression {    abstract void interpret(Context ctx);} 2.Expression

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式.代理模式. 一.享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到.其概念:运用共享内存技术最大限度的支持大量细粒度的对象.这个概念给的有些抽象,说白了就是如果内存中存在某个对象A,如果再次需要使用对象A的时候如果内存中有A这个对象就直接使用它,不要再次new了.如果没有,则重新new一个.基于这个特点,享元模式使用时一般会给待访问对象传递一个Tag,用来标识这个对象,而且要同时使用抽象工厂的方法进行访

Java经典23种设计模式之结构型模式(一)

结构型模式包括7种:适配器模式.桥接模式.组合模式.装饰模式.外观模式.享元模式.代理模式. 本文主要介绍适配器模式和桥接模式. 一.适配器模式(Adapter) 适配器模式其实很简单,就像手机充电器一样,手机需要5V的,而插座出来是220V.因此需要充电器变压就ok.再比如,一个之会说汉语的和一个只会说英语的无法沟通,那就中间请个翻译.所有的交流通过翻译,翻译翻给会说英语的,就能完成一次单项交流的.链接1 中的例子非常生动形象了.总结一下,无非就是有个通用的接口(称为Target),如果一切顺

Java经典23种设计模式之结构型模式(二)

接上篇,本文介绍结构型模式里的组合模式.装饰模式.外观模式. 一.组合模式(Composite) 组合模式:将对象组合成树形结构,表示"部分--整体"的层次结构.最终达到单个对象和组合对象的使用具有一致性.单看这句话貌似有点抽象,其实比较简单. 以李云龙的独立团为例,目的要统计赵嘉宇一战共歼灭敌人多少个.最高的级别是团,一个团有若干个营,一个营有若干个排,一个排有若干个战士.(为了简化问题,排下面就不设行政单位了).很自然的,李云龙给营长开会回去给老子统计.营长回去给各个排长开会,赶紧

java中23种设计模式之18-原型模式(Prototype pattern)

class Something{ public String something=null;}class Prototype implements Cloneable{ private String name; public Something aSomething=new Something(); public void setName(String name) { this.name=name; } public String getName() { return name; } publi

Java经典23种设计模式之创造型模式(二)

本文记录5种创造型模式的剩下两种:建造者模式(Builder).原型模式(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示.一个完整的建造者模式包含以下几个概念: 1.产品类 Product public class Person { private String head; private String body; private String foot; public String getHead() { ret

Java经典23种设计模式之创造型模式(一)

设计模式被称为程序猿的内功,之前零零散散的看过一大部分,但自己么有总结过.故此次在这里总结下.值得一提的是,设计模式并不是Java所特有.由于一直搞Android.这里就用Java为载体.最经典的设计模式有23种,分三个大类型: 创建型模式(5) .结构型模式(7).行为型模式(11),5 + 7 +11 = 23.网上一搜也都是一大把了,这里不过个人作的记录.本文记录创造型模式里的工厂方法(Factory Method).抽象工厂(Abstract Factory).单例模式这三种.力求透彻.