欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#設(shè)計(jì)模式實(shí)現(xiàn)之迭代器模式

 更新時(shí)間:2021年08月11日 09:46:24   作者:SpringSun  
迭代器模式把對(duì)象的職責(zé)分離,職責(zé)分離可以最大限度減少彼此之間的耦合程度,從而建立一個(gè)松耦合的對(duì)象,這篇文章主要給大家介紹了關(guān)于C#設(shè)計(jì)模式實(shí)現(xiàn)之迭代器模式的相關(guān)資料,需要的朋友可以參考下

前言:

迭代器模式平時(shí)用的不多,因?yàn)椴还蹸#還是Java都已經(jīng)幫我封裝了,但是你是否知道平時(shí)經(jīng)常在用的東西本質(zhì)是怎么回事呢。

看完迭代器模式你就知道C# foreach循環(huán)是怎么實(shí)現(xiàn)的了,我的另一篇C# Foreach循環(huán)本質(zhì)與枚舉器就講解了foreach的本質(zhì),其中用到的就是迭代器模式。

按照慣例,例子走起。(寫了幾個(gè)小時(shí)瀏覽器崩潰,我看見在自動(dòng)保存啊,結(jié)果沒內(nèi)容,再擼一遍精簡(jiǎn)點(diǎn)的吧)

一、餐館合并菜單

現(xiàn)在有兩個(gè)餐館和并,其中一個(gè)餐館做早餐,一個(gè)做晚餐。他們都有自己管理菜單的方式,現(xiàn)在兩個(gè)餐館合并需要對(duì)菜單進(jìn)行統(tǒng)一管理,先讓我來看看他們?cè)瓉淼臉幼印?br />

兩個(gè)菜單的菜單項(xiàng)都是一樣的

    public class MenuItme
    {
        //名字
        public string Name { get; set; }
        //描述
        public string Description { get; set; }
        //是否素菜
        public bool Vegetarian { get; set; }
        //價(jià)格
        public double Price { get; set; }

        public MenuItme(string name, string description, bool vegetarian, double price) {
            Name = name;
            Description=description;
            Vegetarian = vegetarian;
            Price = price;
        }
    }

  早餐菜單,使用List管理,不限制長(zhǎng)度

    public class BreakFastMenu
    {
        private List<MenuItme> menuItmes;
        public BreakFastMenu()
        {
            menuItmes = new List<MenuItme>();
            AddItem("梅菜扣肉餅", "好吃", false, 7);
            //菜單項(xiàng)...
        }

        public void AddItem(string name, string description, bool vegetarian, double price)
        {
            MenuItme menuItme = new MenuItme(name, description, vegetarian, price);
            menuItmes.Add(menuItme);
        }

        public List<MenuItme> GetMenuItmes()
        {
            return menuItmes;
        }
    }

  晚餐菜單,使用數(shù)組管理,限制長(zhǎng)度為6

    public class DinerMenu
    {
        static readonly int Max_Items = 6;
        private int numberOfImtes = 0;
        private MenuItme[] menuItmes;
        public DinerMenu()
        {
            menuItmes = new MenuItme[Max_Items];
            AddItem("爆炒癩蛤蟆", "講究火候", false, 42);
            //菜單項(xiàng)...
        }

        public void AddItem(string name, string description, bool vegetarian, double price)
        {
            MenuItme menuItme = new MenuItme(name, description, vegetarian, price);
            if (numberOfImtes >= Max_Items)
            {
                Console.WriteLine("菜單已滿");
            }
            else
            {
                menuItmes[numberOfImtes] = menuItme;
                numberOfImtes++;
            }
        }

        public MenuItme[] GetMenuItmes()
        {
            return menuItmes;
        }
    }

  當(dāng)兩個(gè)餐館合并后需要打印早餐和晚餐菜單給顧客用。

            BreakFastMenu breakFastMenu = new BreakFastMenu();
            List<MenuItme> breakFastMenus = breakFastMenu.GetMenuItmes();

            DinerMenu dinerMenu = new DinerMenu();
            MenuItme[] dinerMenus = dinerMenu.GetMenuItmes();
            //打印早餐
            for (int i = 0; i < breakFastMenus.Count; i++)
            {
                Console.WriteLine(breakFastMenus[i].Name);
            }
            //打印晚餐
            for (int i = 0; i < dinerMenus.Length; i++)
            {
                Console.WriteLine(dinerMenus[i].Name);
            } 

按照這種做法我們總是需要處理兩個(gè)菜單,如果要打印素食,那么也需要循環(huán)遍歷兩個(gè)菜單。

假如加入第三家餐廳合并,我們就需要循環(huán)處理三次,顯然這種方式會(huì)讓我們系統(tǒng)難以維護(hù)。

接下來看我們?nèi)绾芜M(jìn)行改進(jìn)

二、改進(jìn)菜單實(shí)現(xiàn)

計(jì)模式就是要封裝變化的部分,很明顯,這里變化是:不同的集合類所造成的遍歷,我們?nèi)绾畏庋b遍歷集合
不管早餐還是晚餐我們都要用到中括號(hào)[ ] 來取菜單項(xiàng),集合長(zhǎng)度來限制長(zhǎng)度。
現(xiàn)在我們要?jiǎng)?chuàng)建一個(gè)對(duì)象,將他稱為迭代器(Iterator),利用它來封裝“遍歷集合內(nèi)的每個(gè)對(duì)象的過程”。

  對(duì)于List

            Iterator iterator = breakFastMenu.CreateIterator();
            while (iterator.HasNext)
            {
                MenuItme menuItme = iterator.Next();

            }

  對(duì)于數(shù)組

            Iterator iterator = dinerFastMenu.CreateIterator();
            while (iterator.HasNext)
            {
                MenuItme menuItme = iterator.Next();

            }

現(xiàn)在兩個(gè)集合的遍歷都統(tǒng)一了,而這種方式正是迭代器模式。關(guān)于迭代器我們需要知道的第一件事情,就是它依賴于一個(gè)迭代器接口。

這個(gè)接口可能有HasNext()方法高數(shù)我們是否在這個(gè)集合中還有更多的元素。

Next()方法返回這個(gè)集合中的下一個(gè)對(duì)象。一旦我們有了這個(gè)接口,就可以為各種對(duì)象集合實(shí)現(xiàn)迭代器。

現(xiàn)在我們對(duì)晚餐菜單進(jìn)行改造,首先我們需要定義一個(gè)迭代器接口

    public interface Iterator
    {
        bool HasNext();
        Object Next();
    }

  加入一個(gè)晚餐菜單迭代器

    public class DinerMenuIterator : Iterator
    {
        MenuItme[] menuItmes;
        int position = 0;

        public DinerMenuIterator(MenuItme[] menuItmes)
        {
            this.menuItmes = menuItmes;
        }
        public bool HasNext()
        {
            //由于數(shù)組是固定長(zhǎng)度,不僅要檢查數(shù)組,還要檢查指定位置是否為空,如果為空后面就沒有菜單項(xiàng)了
            if (position >= menuItmes.Length || menuItmes[position] == null)
                return false;
            else
                return true;
        }

        public object Next()
        {
            MenuItme menuItme = menuItmes[position];
            position++;
            return menuItme;
        }
    }

  用迭代器改寫晚餐菜單

    public class DinerMenu
    {
        static readonly int Max_Items = 6;
        private int numberOfImtes = 0;
        private MenuItme[] menuItmes;
        public DinerMenu()
        {
            menuItmes = new MenuItme[Max_Items];
            AddItem("爆炒癩蛤蟆", "講究火候", false, 42);
            //菜單項(xiàng)...
        }

        public void AddItem(string name, string description, bool vegetarian, double price)
        {
            MenuItme menuItme = new MenuItme(name, description, vegetarian, price);
            if (numberOfImtes >= Max_Items)
            {
                Console.WriteLine("菜單已滿");
            }
            else
            {
                menuItmes[numberOfImtes] = menuItme;
                numberOfImtes++;
            }
        }
        public Iterator CreateIterator()
        {
            return new DinerMenuIterator(menuItmes);
        }
        //public MenuItme[] GetMenuItmes()
        //{
        //    return menuItmes;
        //}
    }

  同理我們?yōu)樵绮图尤氲?br />

    public class BreakFastIterator: Iterator
    {
        List<MenuItme> menuItmes;
        int position = 0;

        public BreakFastIterator(List<MenuItme> menuItmes)
        {
            this.menuItmes = menuItmes;
        }
        public bool HasNext()
        {
            if (position >= menuItmes.Count)
                return false;
            else
                return true;
        }

        public object Next()
        {
            MenuItme menuItme = menuItmes[position];
            position++;
            return menuItme;
        }
    }

  用迭代器改寫早餐菜單

    public class BreakFastMenu
    {
        private List<MenuItme> menuItmes;
        public BreakFastMenu()
        {
            menuItmes = new List<MenuItme>();
            AddItem("梅菜扣肉餅", "好吃", false, 7);
            //菜單項(xiàng)...
        }

        public void AddItem(string name, string description, bool vegetarian, double price)
        {
            MenuItme menuItme = new MenuItme(name, description, vegetarian, price);
            menuItmes.Add(menuItme);
        }
        public Iterator CreateIterator()
        {
            return new BreakFastIterator(menuItmes);
        }
        //public List<MenuItme> GetMenuItmes()
        //{
        //    return menuItmes;
        //}
    }

  好了,讓我們?cè)囈辉嚨鞴ぷ髑闆r


三、迭代器模式

 經(jīng)過第二步我們基本已經(jīng)實(shí)現(xiàn)迭代器模式,最后我們?cè)俑牧家幌麓蛴〔藛?,并?duì)菜單進(jìn)行統(tǒng)一接口的管理。

定義一個(gè)Menu接口

     public interface Menu
    {
        Iterator CreateIterator();
    }

讓早餐晚餐都實(shí)現(xiàn)Menu接口,并封裝一個(gè)新的菜單打印

    public class NewMenu
    {
        Menu breakFastMenu;
        Menu dinerMenu;
        public NewMenu(Menu breakFastMenu, Menu dinerMenu) {
            this.breakFastMenu = breakFastMenu;
            this.dinerMenu = dinerMenu;
        }

        public void PrintMenu() {


            Iterator breakFastIterator = breakFastMenu.CreateIterator();
            Console.WriteLine("新菜單--------早餐");
            PrintMenu(breakFastIterator);
            Console.WriteLine("新菜單--------晚餐");
            Iterator dinerIterator = dinerMenu.CreateIterator();
            PrintMenu(dinerIterator);
        }

        private void PrintMenu(Iterator iterator) {
            while (iterator.HasNext())
            {
                //取得下一個(gè)項(xiàng)
                MenuItme menuItme = (MenuItme)iterator.Next();
                Console.WriteLine(menuItme.Name);
            }
        }
    }


迭代器模式定義:

迭代器模式:提供一種方法順序訪問一個(gè)集合對(duì)象中的各個(gè)元素,而又不暴露其內(nèi)部的表示。

迭代器模式讓我們能游走于集合內(nèi)的每一個(gè)元素,而又不暴露其內(nèi)部的表示。

把游走的任務(wù)放在迭代器上,而不是集合上。這樣簡(jiǎn)化了集合的接口和實(shí)現(xiàn),也讓責(zé)任各得其所。

總結(jié)

到此這篇關(guān)于C#設(shè)計(jì)模式實(shí)現(xiàn)之迭代器模式的文章就介紹到這了,更多相關(guān)C#迭代器模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論