zoukankan      html  css  js  c++  java
  • 十三、行为型模式之解释器、迭代器-----《大话设计模式》

    一、解释器模式

        给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

    适用:当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。

    缺点:解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。建议当文法非常复杂时,使用其他的计数如语法分析程序或编译生成器来处理。

    image

        abstract class AbstractExpression
        {
            public abstract void Interpret(Context context);
        }
        
        //终结符表达式
        class TerminalExpression : AbstractExpression
        {
            public override void Interpret(Context context)
            {
                Console.WriteLine("终端解释器");
            }
        }
        
        //非终结符表达式,对文法中每一条规则都需要一个具体的非终结符表达式类
        class NonterminalExpression : AbstractExpression
        {
            public override void Interpret(Context context)
            {
                Console.WriteLine("非终端解释器");
            }
        }
        class Context
        {
            private string input;
            public string Input
            {
                get { return input; }
                set { input = value; }
            }
    
            private string output;
            public string Output
            {
                get { return output; }
                set { output = value; }
            }
        }
            static void Main(string[] args)
            {
                Context context = new Context();
                IList<AbstractExpression> list = new List<AbstractExpression>();
                list.Add(new TerminalExpression());
                list.Add(new NonterminalExpression());
                list.Add(new TerminalExpression());
                list.Add(new TerminalExpression());
    
                foreach (AbstractExpression exp in list)
                {
                    exp.Interpret(context);
                }
    
                Console.Read();
            }

    二、迭代器模式

        提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示,例如foreach。IEumerator支持对非泛型集合的简单迭代接口。

    适用:当需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑使用迭代器模式。

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

    image

        abstract class Iterator
        {
            //定义开始、下一个、判断结尾、当前对象等抽象方法,统一接口
            public abstract object First();
            public abstract object Next();
            public abstract bool IsDone();
            public abstract object CurrentItem();
        }
    
        class ConcreteIterator : Iterator
        {
           //定义了具体聚集对象
            private ConcreteAggregate aggregate;
            private int current = 0;
    
           //初始化时将具体的聚集对象传入
            public ConcreteIterator(ConcreteAggregate aggregate)
            {
                this.aggregate = aggregate;
            }
    
            //得到聚集的第一个对象
            public override object First()
            {
                return aggregate[0];
            }
            //得到聚集的下一个对象
            public override object Next()
            {
                object ret = null;
                current++;
    
                if (current < aggregate.Count)
                {
                    ret = aggregate[current];
                }
    
                return ret;
            }
            //返回当前的聚集对象
            public override object CurrentItem()
            {
                return aggregate[current];
            }
            //判断当前遍历是否到结尾,到结尾返回true
            public override bool IsDone()
            {
                return current >= aggregate.Count ? true : false;
            }
    
        }
    
        class ConcreteIteratorDesc : Iterator
        {
            private ConcreteAggregate aggregate;
            private int current = 0;
    
            public ConcreteIteratorDesc(ConcreteAggregate aggregate)
            {
                this.aggregate = aggregate;
                current = aggregate.Count - 1;
            }
    
            public override object First()
            {
                return aggregate[aggregate.Count - 1];
            }
    
            public override object Next()
            {
                object ret = null;
                current--;
                if (current >= 0)
                {
                    ret = aggregate[current];
                }
    
                return ret;
            }
    
            public override object CurrentItem()
            {
                return aggregate[current];
            }
    
            public override bool IsDone()
            {
                return current < 0 ? true : false;
            }
    
        }
    //创建迭代器 
        abstract class Aggregate
        {
            public abstract Iterator CreateIterator();
        }
    
        class ConcreteAggregate : Aggregate
        {
            //声明一个List泛型变量,用于存放聚合对象
            private IList<object> items = new List<object>();
            public override Iterator CreateIterator()
            {
                return new ConcreteIterator(this);
            }
            
            //返回聚集总个数
            public int Count
            {
                get { return items.Count; }
            }
            //声明一个索引器
            public object this[int index]
            {
                get { return items[index]; }
                set { items.Insert(index, value); }
            }
        }
    static void Main(string[] args)
            {
                ConcreteAggregate a = new ConcreteAggregate();
    
                a[0] = "大鸟";
                a[1] = "小菜";
                a[2] = "行李";
                a[3] = "老外";
                a[4] = "公交内部员工";
                a[5] = "小偷";
    
                Iterator i = new ConcreteIterator(a);
                object item = i.First();
                while (!i.IsDone())
                {
                    Console.WriteLine("{0} 请买车票!", i.CurrentItem());
                    i.Next();
                }
    
                Console.Read();
            }

    三、总结

        书中最后一个案例主要针对设计思路进行了讲解,比较简单,在实际操作过程中遇到的问题远比此复杂的多。看书多遍只是为了对这些设计模式有一个系统的了解,使用还是需要通过实际的项目来活学活用。

        附录B中的书籍可以学习,有些时候书籍出版时间并不代表没有阅读意义,而其涉及的原理是现在依赖开发平台做程序时需要的关键思路。

    image

    image

  • 相关阅读:
    codeforces 616B Dinner with Emma
    codeforces 616A Comparing Two Long Integers
    codeforces 615C Running Track
    codeforces 612C Replace To Make Regular Bracket Sequence
    codeforces 612B HDD is Outdated Technology
    重写父类中的成员属性
    子类继承父类
    访问修饰符
    方法的参数
    实例化类
  • 原文地址:https://www.cnblogs.com/shanymen/p/4842186.html
Copyright © 2011-2022 走看看