ভিজিটর প্যাটার্ন বোঝা


16

আমার কাছে ক্লাসগুলির একটি শ্রেণিবিন্যাস রয়েছে যা জিইউআই নিয়ন্ত্রণগুলি উপস্থাপন করে। এটার মতো কিছু:

Control->ContainerControl->Form

আমাকে এমন একটি ধারাবাহিক অ্যালগরিটম বাস্তবায়ন করতে হবে যা বিভিন্ন স্টাফ করার মতো জিনিসগুলির সাথে কাজ করে এবং আমি ভাবছি যে ভিজিটর প্যাটার্নটি সবচেয়ে পরিষ্কার সমাধান হবে। উদাহরণস্বরূপ একটি অ্যালগরিদম গ্রহণ করা যাক যা বস্তুর শ্রেণিবিন্যাসের একটি এক্সএমএল প্রতিনিধিত্ব তৈরি করে। 'ক্লাসিক' পদ্ধতির ব্যবহার করে আমি এটি করব:

public abstract class Control
{
    public virtual XmlElement ToXML(XmlDocument document)
    {
        XmlElement xml = document.CreateElement(this.GetType().Name);
        // Create element, fill it with attributes declared with control
        return xml;
    }
}

public abstract class ContainerControl : Control
{
    public override XmlElement ToXML(XmlDocument document)
    {
        XmlElement xml = base.ToXML(document);
        // Use forech to fill XmlElement with child XmlElements
        return xml;
    }
}

public class Form : ContainerControl
{
    public override XmlElement ToXML(XmlDocument document)
    {
        XmlElement xml = base.ToXML(document);
        // Fill remaining elements declared in Form class
        return xml;
    }
}

তবে আমি কীভাবে এটি ভিজিটর প্যাটার্ন দিয়ে করব তা নিশ্চিত নই। এটি হল প্রাথমিক বাস্তবায়ন:

public class ToXmlVisitor : IVisitor
{
    public void Visit(Form form)
    {
    }
}

যেহেতু এমনকি বিমূর্ত ক্লাসগুলি বাস্তবায়নে সহায়তা করে আমি কীভাবে টক্সএলএমভিসিটারে সঠিকভাবে এটি করব তা নিশ্চিত নই?

আমি যে কারণে ভিজিটর প্যাটার্নটি বিবেচনা করছি তা হ'ল কিছু অ্যালগরিদমের প্রকল্পে ক্লাসগুলি প্রয়োগ করা হয় না এবং সেখানে বিভিন্ন ধরণের অ্যালগোরিদম রয়েছে যাতে রেফারেন্সের প্রয়োজন হয় না তাই আমি বড় ক্লাসগুলি এড়িয়ে চলেছি।


আপনার প্রশ্ন কি?
gnat

মূলত কীভাবে দর্শনার্থীর প্যাটার্নটি ব্যবহার করে ToXML () পদ্ধতিটি পুনরায় লিখতে হয়।
নেজরেলি


লিঙ্কের জন্য ধন্যবাদ। গতিশীল প্রেরণে traditionalতিহ্যবাহী দর্শনার্থীদের ধরণ সরল করে তবে এটি খুব বেশি পরিবর্তন হয় না।
নেজরেলি

@ নেজরেলি হ্যাঁ এটি করে। এটি এমন ক্লাসগুলির সাথে কাজ করে যা ভিজিটর প্যাটার্নকে সমর্থন করে না, যেমন আপনি উইন্ডোজ ফর্মগুলি নিয়ন্ত্রণ করছেন।
ক্রিস ভ্যান্ডারমোটেন

উত্তর:


17

ভিজিটর প্যাটার্ন হ'ল প্রোগ্রামিং ভাষাগুলিতে দ্বৈত বাইন্ডিং অনুকরণ করার ব্যবস্থা যা কেবলমাত্র একক বাঁধাই সমর্থন করে। দুর্ভাগ্যক্রমে, উক্তিটি খুব বেশি বিষয়গুলিকে স্পষ্ট করতে পারে না, তাই আমাকে একটি সাধারণ উদাহরণ দিয়ে ব্যাখ্যা করতে দিন।

.NET এবং C # তে, আপনি যে প্ল্যাটফর্মটি ব্যবহার করছেন, বস্তুগুলি ToString()ফাংশনটি ব্যবহার করে স্ট্রিংগুলিতে রূপান্তরিত হতে পারে । এই ফান্টেশনটি কী করে, যেমন কোডটি কার্যকর করা হচ্ছে তা আপনি যে ধরণের বস্তুটিতে প্রয়োগ করছেন তার উপর নির্ভর করে (এটি একটি ভার্চুয়াল পদ্ধতি)। কোন কোডটি কার্যকর করা হয় তা একটি জিনিসের উপর নির্ভর করে, যা একধরণের অবজেক্টের, তাই ব্যবহূত ব্যবস্থাকে একক বাঁধাই বলে।

তবে আমি যদি প্রতিটি বস্তুর বিভিন্ন ধরণের জন্য একটি স্ট্রিংতে রূপান্তর করতে একাধিক উপায় থাকতে চাই? স্ট্রিংগুলিতে অবজেক্টগুলিকে রূপান্তর করার জন্য যদি আমি দুটি উপায় থাকতে চাই, যাতে কোডটি কার্যকর করা হয় যা দুটি জিনিসের উপর নির্ভর করে: কেবলমাত্র বস্তুটি রূপান্তরিত হয় না, আমরা যেভাবে এটি রূপান্তর করতে চাই তাও?

যদি আমাদের দ্বৈত বাইন্ডিং থাকে তবে এটি সুন্দরভাবে সমাধান করা যেতে পারে। তবে সি # সহ বেশিরভাগ ওও ভাষাগুলি কেবলমাত্র একক বাঁধাই সমর্থন করে।

দ্বৈত বাইন্ডিংকে দুটি সফল একক বাঁধার মধ্যে পরিণত করে দর্শকের ধরণটি সমস্যার সমাধান করে।

আমাদের উপরের উদাহরণে এটি রূপান্তর করতে অবজেক্টে একটি ভার্চুয়াল পদ্ধতি ব্যবহার করবে, যা রূপান্তর অ্যালগরিদম প্রয়োগকারী অবজেক্টে দ্বিতীয় ভার্চুয়াল পদ্ধতিটিকে কল করে।

তবে এটি সূচিত করে যে আপনি যে বিষয়টির উপরে অ্যালগোরিদম প্রয়োগ করতে চান তার জন্য এটির সাথে সহযোগিতা করা দরকার: এতে বেকড ভিজিটর প্যাটার্নটির জন্য সমর্থন থাকতে হবে।

আপনি .NET এর উইন্ডোজ ফর্ম ক্লাসগুলি ব্যবহার করছেন বলে মনে হয়, যা দর্শকদের বিন্যাসের জন্য সমর্থন করে না। আরও নির্দিষ্টভাবে, তাদের একটি public virtual void Accept(IVisitor)পদ্ধতি থাকা দরকার যা স্পষ্টতই তাদের নেই।

তাহলে, বিকল্প কি? ভাল,। নেট কেবলমাত্র একক বাঁধাই সমর্থন করে না, এটি গতিশীল বাঁধাই সমর্থন করে, যা দ্বৈত বাঁধার চেয়ে আরও শক্তিশালী।

কীভাবে সেই কৌশলটি প্রয়োগ করতে হবে সে সম্পর্কে আরও তথ্যের জন্য, যা আপনাকে আপনার সমস্যার সমাধান করতে দেবে (যদি আমি এটি ভালভাবে বুঝতে পারি) তবে বিদায়ী দর্শকের দিকে একবার নজর দিন ।

হালনাগাদ:

আপনার নির্দিষ্ট সমস্যায় কৌশলটি প্রয়োগ করতে, প্রথমে আপনার এক্সটেনশন পদ্ধতিটি সংজ্ঞায়িত করুন:

public static XmlDocument ToXml(this Control control)
{
    XmlDocument xml = new XmlDocument();
    XmlElement root = xml.CreateElement(control.GetType().Name);
    xml.AppendChild(root);

    Visit(control, xml, root);

    return xml;
}

গতিশীল প্রেরক তৈরি করুন:

private static void Visit(Control control, XmlDocument xml, XmlElement root)
{
    dynamic dynamicControl = control; //notice the 'dynamic' type.
                                      //this is the key to dynamic dispatch

    VisitCore(dynamicControl, xml, root);
}

তারপরে নির্দিষ্ট পদ্ধতিগুলি পূরণ করুন:

private static void VisitCore(Control control, XmlDocument xml, XmlElement root)
{
    // TODO: specific Control handling
}

private static void VisitCore(ContainerControl control, XmlDocument xml, XmlElement root)
{
    // call the "base" method
    VisitCore(control as Control, xml, root);

    // TODO: specific ContainerControl handling
    // for example:
    foreach (Control child in control.Controls)
    {
        XmlElement element = xml.CreateElement(child.GetType().Name);
        root.AppendChild(element);

        // call the dynamic dispatcher method
        Visit(child, xml, element);
    }
}

private static void VisitCore(Form control, XmlDocument xml, XmlElement root)
{
    // call the "base" method
    VisitCore(control as ContainerControl, xml, root);

    // TODO: specific Form handling
}

নেট মধ্যে ডায়নামিক প্রেরণটি আসলে বেশ শক্তিশালী .. তবে আমি লক্ষ্য করেছি এটি কিছুটা ... ভাল .. ধীর হতে পারে তবে এটি কোডের একক লাইনে যা দর্শনার্থীর সাথে একাধিক ক্লাস এবং ইন্টারফেসগুলিতে সেভ্রাল রেখা গ্রহণ করে
নিউটোপিয়ান

তবুও, ডায়নামিক প্রেরণটি আমার সমস্যার সমাধান করবে না কারণ আমার টক্সএইচএমএল অ্যালগরিদম আমাকে উত্তরাধিকার শৃঙ্খলে সমস্ত ধরণের 'দেখার' প্রয়োজন to আমার উদাহরণে এটি সফলভাবে এক্সএমএল রূপান্তরকরণের জন্য কন্ট্রোল, কনটেইনারকন্ট্রোল এবং ফর্মটি দেখার প্রয়োজন।
নেজরেলি

@ নেজরেলি এটি আপনার সমস্যার সমাধান করতে পারে, কীভাবে তা দেখানোর জন্য আমি আমার উত্তর আপডেট করেছি।
ক্রিস ভ্যান্ডারমোটেন

গতিশীল পরিবর্তনশীল সংজ্ঞায় একটি মন্তব্য যুক্ত করার অনুমতি নিয়েছি। কোডটি স্পট করার আগে এটি আমাকে দুটি পড়তে লাগল এবং এটি পুরো গল্পের মূল বিষয়।
ক্রিশ্দি ডায়াকোনস্কু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.