nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

Abstract Factory パターン [C#]

Abstract Factory パターン [C#]

Abstract Factory パターンを記載します。

Abstract Factoryパターンを使うことによって、クラスの使用者は、具象クラスを直接扱わずに、具職クラスのインスタンスを取得できる。
(Main関数で扱っているのは、抽象クラスのみである。)

クラス図

f:id:nprogram:20181104232706p:plain

実行イメージ

f:id:nprogram:20181104235003p:plain

using System;
using System.Collections.Generic;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            CurryRiceAbstractFactory tomatoCurry = CreateFactory("Tomato Curry Rice");
            tomatoCurry.Order();


            CurryRiceAbstractFactory indianCurryRice = CreateFactory("Indian Curry Rice");
            indianCurryRice.Order();

            Console.ReadLine();
        }

        private static CurryRiceAbstractFactory CreateFactory(String str)
        {
            if (str == "Tomato Curry Rice")
            {
                return new TomatoCurryFactory(str);
            }
            else if (str == "Indian Curry Rice")
            {
                return new IndianCurryRice(str);
            }

            return null;
        }

        public abstract class CurryRiceAbstractFactory
        {
            private string Name;
            private Soup Soup;
            private List<Spice> SpiceList = new List<Spice>();
            private List<Ingredients> IngredientsList = new List<Ingredients>();
            private List<Vegetable> VegetableList = new List<Vegetable>();


            abstract public Soup GetSoup();
            abstract public List<Spice> GetSpiceList();
            abstract public List<Ingredients> GetIngredientsList();
            abstract public List<Vegetable> GetVegetableList();

            public void Order()
            {
                Console.WriteLine("---- Get a " + GetName() + " Recipe ----");
                GetRecipe();
                Console.WriteLine();

                Console.WriteLine("---- Cooking a " + GetName() + " ----");
                Cut();
                StirFry();
                Boil();
                Serve();
                Console.WriteLine();
            }

            public string GetName()
            {
                return this.Name;
            }

            public void SetName(string someName)
            {
                this.Name = someName;
            }

            public void Cut()
            {
                Console.WriteLine("Cut");
            }

            public void Boil()
            {
                Console.WriteLine("Boil");
            }

            public void StirFry()
            {
                Console.WriteLine("Stir fry");
            }

            public void Serve()
            {
                Console.WriteLine("Here you are. This is " + GetName());
            }

            public void GetRecipe()
            {
                Console.WriteLine("---- Soup ----");
                Console.WriteLine(GetSoup().Name);

                Console.WriteLine("---- Spice ----");
                GetSpiceList().ForEach(item =>
                {
                    Console.WriteLine(item.Name);

                });

                Console.WriteLine("---- Ingredients ----");
                GetIngredientsList().ForEach(item =>
                {
                    Console.WriteLine(item.Name);

                });

                Console.WriteLine("---- Vegetable ----");
                GetVegetableList().ForEach(item =>
                {
                    Console.WriteLine(item.Name);

                });
            }
        }

        public class TomatoCurryFactory : CurryRiceAbstractFactory
        {
            public TomatoCurryFactory(string str)
            {
                SetName(str);
            }

            public override Soup GetSoup()
            {
                return new TomatoSoup();
            }

            public override List<Spice> GetSpiceList()
            {
                List<Spice> list = new List<Spice>();

                list.Add(new GaramMasala());
                list.Add(new Turmeric());

                return list;
            }

            public override List<Ingredients> GetIngredientsList()
            {
                List<Ingredients> list = new List<Ingredients>();

                list.Add(new Pork());

                return list;
            }

            public override List<Vegetable> GetVegetableList()
            {
                List<Vegetable> list = new List<Vegetable>();

                list.Add(new Tomato());
                list.Add(new Carrot());

                return list;
            }

        }

        public class IndianCurryRice : CurryRiceAbstractFactory
        {
            public IndianCurryRice(string str)
            {
                SetName(str);
            }

            public override Soup GetSoup()
            {
                return new OnionSoup();
            }

            public override List<Spice> GetSpiceList()
            {
                List<Spice> list = new List<Spice>();

                list.Add(new GaramMasala());
                list.Add(new Turmeric());

                return list;
            }

            public override List<Ingredients> GetIngredientsList()
            {
                List<Ingredients> list = new List<Ingredients>();

                list.Add(new Chicken());

                return list;
            }

            public override List<Vegetable> GetVegetableList()
            {
                List<Vegetable> list = new List<Vegetable>();

                list.Add(new Tomato());
                list.Add(new Carrot());
                list.Add(new GreenPapper());

                return list;
            }
        }

        #region Spice
        public abstract class Spice
        {
            public string Name;
            public string Color;
        }

        public class GaramMasala : Spice
        {
            public GaramMasala()
            {
                this.Name = "Garam masala";
                this.Color = "Yellow";
            }

        }

        public class Turmeric : Spice
        {
            public Turmeric()
            {
                this.Name = "Turmeric";
                this.Color = "Yellow";
            }
        }
        #endregion Spice

        #region Soup
        public abstract class Soup
        {
            public string Name;
        }

        public class OnionSoup : Soup
        {
            public OnionSoup()
            {
                this.Name = "Onion soup";
            }
        }

        public class TomatoSoup : Soup
        {
            public TomatoSoup()
            {
                this.Name = "Tomato soup";
            }
        }
        #endregion Soup

        #region Ingredients
        public abstract class Ingredients
        {
            public string Name;
        }

        public class Pork : Ingredients
        {
            public Pork()
            {
                this.Name = "Pork";
            }
        }

        public class Beef : Ingredients
        {
            public Beef()
            {
                this.Name = "Beef";
            }
        }

        public class Chicken : Ingredients
        {
            public Chicken()
            {
                this.Name = "Chicken";
            }
        }
        #endregion Ingredients

        #region Vegetables
        public abstract class Vegetable
        {
            public string Name;
        }

        public class Carrot : Vegetable
        {
            public Carrot()
            {
                this.Name = "Carrot";
            }
        }

        public class GreenPapper : Vegetable
        {
            public GreenPapper()
            {
                this.Name = "GreenPapper";
            }
        }

        public class Tomato : Vegetable
        {
            public Tomato()
            {
                this.Name = "Tomato";
            }
        }
        #endregion Vegetables
    }
}

以下の記事に記載されています。

http://www.techscore.com/tech/DesignPattern/AbstractFactory.html/