بحث هذه المدونة الإلكترونية

الثلاثاء، 25 مايو 2010

Proxy Pattern



Proxy Pattern

-        هذاالنمط يدعم العناصر التي تتحكم في انشاء عناصر اخرى او الوصول اليها وغالبا ما يكون ال proxy كائن صغير و Public  و يمثل او يكون بديل الى كائن اخر معقد وprivate
 
فهذا النمط عبارة عن ال class التي تقوم بانشاء اوالتحكم او تسهيل اوحماية الولوج لعنصر آخر ويكون للبروكسي والكائن الاخر نفس الانترفيس

مثال : 

class SubjectAccessor
    {
        public interface ISubject

        {
            string Request();
        }

        private class Subject:ISubject

        {

            public string Request()

            {
                return "Subject Request " + "Choose left door\n";
            }
        } 

        public class Proxy : ISubject
        {
            Subject subject; 

            public string Request()
            {
                // A virtual proxy creates the object only on its first method call

                if (subject == null)

                {
                    Console.WriteLine("Subject inactive");
                    subject = new Subject();
                }

                Console.WriteLine("Subject active");
                return "Proxy: Call to " + subject.Request();
            }
        } 


        public class ProtectionProxy : ISubject
        {
            // An authentication proxy first asks for a password
            Subject subject;
            string password = "Abracadabra"

            public string Authenticate(string supplied)
            {

                if (supplied != password)

                    return "Protection Proxy: No access";

                else
                    subject = new Subject();

                return "Protection Proxy: Authenticated";

            }

            public string Request()
            {
                if (subject == null)

                    return "Protection Proxy: Authenticate first";

                else return "Protection Proxy: Call to " +  subject.Request();
            }
        }
    } 


class Client : SubjectAccessor
    {
        static void Main()
        {
            Console.WriteLine("Proxy Pattern\n");

            ISubject subject = new Proxy();

            Console.WriteLine(subject.Request());

            Console.WriteLine(subject.Request()); 

            ProtectionProxy subject1 = new ProtectionProxy();

            Console.WriteLine(subject1.Request());

            Console.WriteLine((subject1 as ProtectionProxy).Authenticate("Secret"));

            Console.WriteLine((subject1 as ProtectionProxy).Authenticate("Abracadabra"));

            Console.WriteLine(subject1.Request());
        }
    } 

 قمنا في البداية بعمل  كلاس SubjectAccessor والتي تحوي العنصر
الاساسي الذي سنعمل عليه و نوعين من البروكسي والانترفيس الذي قمنا بالوراثة منه.

في البداية قمنا بتعريف الكلاس التي سوف نقوم بعمل البروكسي لها وهي Subject

-        واما البروكسي الاول وهو Proxyفعمله كما نرى ان يتاكد من عدم انشاء الاوبجيكت الا في حالة استدعاء احد خواصه او وظائفه وهذا البروكسي يكون مفيد جدا مع الاوبجيكت ذات الحجم الكبير
-        اما البروكسي الثاني وهو ProtectionProxy فهو يتاكد من الحماية قبل انشاء الاوبجيكت فيقوم من التاكد عن الباسورد مثلا فاذا كانت صحيحة قام بانشاء الاوبجيكت

سنقومالان بعرض مثال اخر

    class SpaceBookSystem
    { 
        private class SpaceBook
        {
            static SortedList<string,SpaceBook> community = new SortedList<string, SpaceBook>(100);

            string pages;
            string name;
            string gap = "\n\t\t\t\t";
            static public bool IsUnique(string name)
            {
                return community.ContainsKey(name);
            }
            internal SpaceBook(string n)
            {
                name = n;
                community[n] = this;
            }

            internal void Add(string s)
            {
                pages += gap + s;

                Console.WriteLine(gap + "======== " + name + "'s SpaceBook =========");

                Console.WriteLine(pages);
                Console.WriteLine(gap+ "==========================");
            }

            internal void Add(string friend, string message)
            {
                community[friend].Add(message);
            }

            internal void Poke(string who,string friend)
            {
                community[who].pages += gap + friend + " poked you";
            }
        } 

        // The Proxy
        public class MySpaceBook
        {
            // Combination of a virtual and authentication proxy
            SpaceBook mySpaceBook;
            string password;
            string name;
            bool loggedIn = false;         

            void Register()
            {
                Console.WriteLine("Let's register you for SpaceBook");
                do
                {
                    Console.WriteLine("All SpaceBook names must be unique");
                    Console.Write("Type in a user name: ");
                    name = Console.ReadLine();
                } while (SpaceBook.IsUnique(name));

                Console.Write("Type in a password: ");

                password = Console.ReadLine();

                Console.WriteLine("Thanks for registering with SpaceBook");

            }

            bool Authenticate()

            {
                Console.Write("Welcome " + name + ". Please type in your password: ");
                string supplied = Console.ReadLine();

                if (supplied == password)
                {
                    loggedIn = true;

                    Console.WriteLine("Logged into SpaceBook");

                    if (mySpaceBook == null)

                        mySpaceBook = new SpaceBook(name);
                    return true;
                }

                Console.WriteLine("Incorrect password");
                return false;
            }
            public void Add(string message)
            {
                Check();
                if (loggedIn)
                     mySpaceBook.Add(message);
            }

            public void Add(string friend, string message)
            {
                Check();

                if (loggedIn)
                    mySpaceBook.Add(friend, name + " said: " + message);

            }

            public void Poke(string who)
            {
                Check();

                if (loggedIn)
                    mySpaceBook.Poke(who, name);
            }

            void Check()
            {
                if (!loggedIn)
                {
                    if (password == null)
                        Register();
                    if (mySpaceBook== null)
                        Authenticate();
                }
            }
        }
    }

    // The Client

    class ProxyPattern : SpaceBookSystem
    {
        static void Main()
        {
            MySpaceBook me = new MySpaceBook();

            me.Add("Hello world");
            me.Add("Today I worked 18 hours");
           MySpaceBook tom = new MySpaceBook();
            tom.Poke("Judith ");
            tom.Add("Judith ""Poor you");
            tom.Add("Off to see the Lion King tonight");
        }
    }
-        هذا عبارة عن فيس بوك مصغر . الكلاس الاساسية التي تقوم بالعمل فعليا هي SpaceBook فهي التي تقوم بعمل ال Authenticate وال Add و ال Check اما الكلاس الاخرى وهي MySpaceBook فهي كلاس البروكسي ووظيفتها هي ان تكون وسيط بين المستخدم والكلاس الاصلية التي تقوم بالعمل وتتاكد من الضوابط التي نريد وضعها لكي تدخل الى النظام ... فاذا تاكد البروكسي من ان كلمة السر سليمة وان الاسم غير موجود من قبل و ....الخ فسوف يقوم باشاء العنصر الاصلي والبدا بالعمل اما اذا خلافت الضوابط الموضوعة فسوف يمنع انشاء العنصر وبذلك نكون قد وفرنا في استهلاك المصادر من الجهاز

الخلاصة :
استخدام البروكسي يكون في الغالب في احدى الحالات التالية:

-        عندما نريد التحكم في الدخول.
-        الولوج الى انظمة بعيدة (remote access).
-        عندما يكون الاوبجيكت كبير الحجم ويستهلك موارد كثرة.
-        عدم انشاء الاوبجيكت الا في حالة استخدام احدى وظائفه.
-        بعد اتمام انشاء الاوبجيكت يقوم البروكسي بادارة محتوياته من استدعاء دوال بداخله وهكذا.
-        عندما تريد ان يكون لديك اوبجيكت محلي يدير اوبجيكت اخر بعيد.

ليست هناك تعليقات:

إرسال تعليق