دیزاین پترن Visitor

دیزاین پترن Visitor

Behavioral DESIGN PATTERNS

یکی از زیرشاخه های الگوهای طراحی، Behavioral Design Patterns است. تمرکز و وظیفه اصلی این دیزاین پترن ها تعامل اشیاء و جداسازی وظایف آن ها  از یکدیگر است.

Visitor Design Pattern

دیزاین پترن Visitor یکی از زیرشاخه های الگوهای طراحی از نوع Behavioral است.

الگوی طراحی Visitor نشان دهنده عملیاتی است که باید روی عناصر یک ساختار شی انجام شود. این الگو به شما امکان می دهد بدون تغییر کلاس عناصری که بر روی آنها کار می کند ، یک عملیات جدید تعریف کنید.

میزان استفاده : کم

پیاده سازی دیزاین پترن Visitor

فرض کنید میخواهیم میوه و کتاب را با هم بفروشیم. اینترفیس ItemElement را به شکل زیر داریم.

interface ItemElement
    {
        int accept(ShoppingCartVisitor visitor);
    }

در این اینترفیس متدی به نام accept داریم که کلاس های Fruit (میوه) و Book (کتاب) باید آن را پیاده سازی کنند.

class Fruit : ItemElement
    {
        private int pricePerKg;
        private int weight;
        private String name;
        public Fruit(int priceKg, int wt, String nm)
        {
            this.pricePerKg = priceKg;
            this.weight = wt;
            this.name = nm;
        }

        public int getPricePerKg()
        {
            return pricePerKg;
        }

        public int getWeight()
        {
            return weight;
        }

        public String getName()
        {
            return this.name;
        }

        public int accept(ShoppingCartVisitor visitor)
        {
            return visitor.visit(this);
        }
    }
class Book : ItemElement
    {
        int price;

        private String isbnNumber;

        public Book(int cost, String isbn)
        {
            this.price = cost;
            this.isbnNumber = isbn;
        }

        public int getPrice()
        {
            return price;
        }

        public String getIsbnNumber()
        {
            return isbnNumber;
        }

        public int accept(ShoppingCartVisitor visitor)
        {
            return visitor.visit(this);
        }
    }

همانطور که در کدهای بالا مشخص است ما در متد accept از visitor متد visit را با پارامتر ورودی همین کلاس (this) صدا زدیم.
حالا ببینیم این visitor چی هست.

 class ShoppingCartVisitorImpl : ShoppingCartVisitor
    {
        public int visit(Book book)
        {
            int cost = 0;
            if (book.getPrice() > 50)
            {
                cost = book.getPrice() - 5;
            }
            else
                cost = book.getPrice();

            Console.WriteLine("Book ISBN::" + book.getIsbnNumber() + " cost =" + cost);
            return cost;
        }

        public int visit(Fruit fruit)
        {
            int cost = fruit.getPricePerKg() * fruit.getWeight();
            Console.WriteLine(fruit.getName() + " cost = " + cost);
            return cost;
        }
    }

متد visit برای کتاب به یک نحوی در حال محاسبه قیمت است و برای میوه به نحو دیگر.
پس ما با صدا زدن متد visit در کلاس میوه داریم قیمت میوه ها را محاسبه میکنیم و در کلاس کتاب داریم قیمت کتاب را با تخفیفش محاسبه میکنیم.
حالا به سراغ متد main برویم.

 static void Main(string[] args)
        {
            try
            {
                ItemElement[] items = new ItemElement[] { new Book(20, "1234"),
                   new Book(100, "5678"), new Fruit(10, 2, "Banana"),
                   new Fruit(5, 5, "Apple") };
                int total = calculatePrice(items);

                Console.WriteLine("Total Cost = " + total);
            }
            catch (Exception ex)
            {
                ShowError(ex.Message);
            }
            Console.ReadLine();
        }
        private static int calculatePrice(ItemElement[] items)
        {
            ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();
            int sum = 0;
            foreach (ItemElement item in items)
            {
                sum = sum + item.accept(visitor);
            }
            return sum;
        }

    }

با توجه به کد بالا ما زمانی که میخواهیم قیمت کل را محاسبه کنیم تک به تک آیتمها را فقط کافیه متد acceptاش را صدا بزنیم. تک به تک بر اساس نوع آن محاسبه میشود و به فاکتور ما اضافه میشود.

حالا شما فرض کنید که میخواهید یک آیتم جدید (تافته جدا بافته) به این سبد خرید اضافه کنید. به نظر شما کار سختی در پیش دارید؟
پاسخ سوال خیر است. چرا؟
چون خیلی راحت، کافی است یک کلاسی داشته باشیم که از ItemElement ارث ببرد تا متد accept را داشته باشد. سپس یک متد به کلاس Visitorمان که همان ٖShoppingCartVisitorImpl است بر اساس کلاس جدیدمان اضافه میکنیم.
و زمانی که مشتری اقدام به خرید این جنس کرد خیلی راحت قیمتش را محاسبه و به فاکتور درج میکنیم.
و چقدر این دیزاین پترن ها کار ما را راحت کرده اند.

برای آموزش رایگان در مورد انواع دیزاین پترن ها و معماری های نرم افزار می توانید به این آموزش مراجعه نمایید:

معماری نرم افزار مهم ترین پترن های معماری نرم افزار

دیزاین پترن یا الگوی طراحی چیست؟

دیزاین پترن  در حقیقت راه حل مسائل طراحی نرم افزار هستند که بارها و بارها در دنیای توسعه نرم افزار تکرار میشوند. الگوهایی از طراحی قابل استفاده مجدد (reusable) و تعامل اشیاء.

پرینت صفحه

هولوسن

با من یاد بگیر

آموزش های بیشتر در وبسایت هولوسن : https://holosen.net

بدون نظر

**پرسش و پاسخ** سوال خود مطرح کنید.
امتیاز شما*