C# Interpreter Pattern Kullanımı - OOP Design Pattern

Interpreter tasarım deseni, behavior grubununa ait, belli bir düzen veya kurala bağlı olan metinlerin sayısal veya mantıksal olarak işlenmesi gereken durumlarda kullanılır. dofactory.com a göre kullanım oranı %20 civarındadır.




Dofactory.com’da roma rakamlarının sayısal karşılığını bulan programa yer verilmiş bu pattern’i çok güzel açıklıyor bakmanızı tavsiye ederim.

UML şemasından göreceğiniz gibi TerminalExpression ile NonterminalExpression isimli iki farklı Exrepssion tipi vardır. Roma rakamlarından yola çıkarsak Roma rakamlarındaki her bir harf TerminalExpression’dur. Roma rakamları ile 4 işlem yapmak isteseydik toplama, çarpma gibi ifadeler NonterinalExpression olacaktı. 


Biz örneğimizin basit olması için NonterminalExpression kullanmıyacağız. Çok kullanılan bir pattern olmadığı için örnek bulmakta zorlandım ama şöyle bir şey yapabiliriz. Örneğin bir entegrasyon çalışıyor ve bize “SIYSI” gibi bir string ifade geliyor. 

S = DEPARTMAN: SATIS DEPARTMANI, MALIYET:10
I = DEPARTMAN: INSAN KAYNAKLARI, MALIYET:20
Y = DEPARTMAN: YAZILIM, MALIYET:30

Bizden istenen ise bu stringi charlara bölüp gelen değerin şirkete maliyetini bulmamız. Bunu yapmak için Interpreter tasarım desenini kullanabiliriz.



Kod:

    // Context class
    public class Context
    {
        public string Formula { get; set; }
        public int TotalCost { get; set; }
    }
    // Expression
    public abstract class DepartmentExpression
    {
        public abstract void Interpret(Context context);
    }
    // TerminalExpression
    public class HRExpression:DepartmentExpression
    {
        public override void Interpret(Context context)
        {
            context.TotalCost += 20;
        }
    }
    // TerminalExpression
    public class SoftwareExpression:DepartmentExpression
    {
        public override void Interpret(Context context)
        {
            context.TotalCost += 30;
        }
    }
    // TerminalExpression
    public class SalesExpression : DepartmentExpression
    {
        public override void Interpret(Context context)
        {
            context.TotalCost += 30;
        }
    }
//Client
    class Program
    {
        static List<DepartmentExpression> CreateExpressionTree
            (string formula)
        {
            // Expression ağacı oluşturulur
            List<DepartmentExpression> tree = new List<DepartmentExpression>();

            foreach (char role in formula)
            {
                if (role == 'S')
                    tree.Add(new SalesExpression());
                else if (role == 'I')
                    tree.Add(new HRExpression());
                else if (role == 'Y')
                    tree.Add(new SoftwareExpression());
            }
            return tree;
        }

        static void RunExpression(Context context)
        {
            foreach (DepartmentExpression expression in CreateExpressionTree
                  (context.Formula))
            {
                // TerminalExpression tiplerine ait harf sembolleri 
                // buradaki metod çağrısındada gönderilebilir.
                expression.Interpret(context); 
            }
            Console.WriteLine("{0} için maliyet {1}"
                          , context.Formula, context.TotalCost);
        }

        static void Main(string[] args)
        {
            Context context = new Context { Formula = "SIYSI" };
            RunExpression(context);

            Console.ReadLine();
        }
    }
Çıktı:



0 yorum :

Yorum Gönder