سؤال

لقد بحثت في هذا التفسير على ويكيبيديا, وتحديدا C++ العينة ، و تفشل في التعرف على الفرق بين مجرد تحديد 3 فئات ، وخلق حالات و يدعو لهم و هذا المثال.ما رأيته كان مجرد وضع اثنين من الفئات الأخرى في هذه العملية و لا يمكن أن نرى حيث لن يكون هناك فائدة.الآن أنا متأكد من أنا في عداد المفقودين شيء واضح (خشب الأشجار) - هلا شرح لي أحدكم باستخدام نهائي العالم الحقيقي سبيل المثال ؟


ما يمكن أن تجعل من إجابات حتى الآن يبدو لي أن تكون أكثر تعقيدا من هذا:

have an abstract class: MoveAlong with a virtual method: DoIt()
have class Car inherit from MoveAlong, 
     implementing DoIt() { ..start-car-and-drive..}
have class HorseCart inherit from MoveAlong, 
     implementing DoIt() { ..hit-horse..}
have class Bicycle inherit from MoveAlong, 
     implementing DoIt() { ..pedal..}
now I can call any function taking MoveAlong as parm 
passing any of the three classes and call DoIt
Isn't this what Strategy intents? (just simpler?)

[تحرير-تحديث] وظيفة أود أن أشير إلى أعلاه يتم استبدال مع فئة أخرى في MoveAlong سيكون السمة التي يتم تعيين وفقا للحاجة استنادا إلى خوارزمية تنفيذها في هذه الفئة الجديدة.(على غرار ما هو موضح في الإجابة المقبولة.)


[تحرير-تحديث] الختام

نمط استراتيجية وانها تستخدم ، ولكن انا مؤمن قوي في قبلة ، وسوف تميل إلى أكثر وضوحا وأقل obfuscatory التقنيات.معظمها منذ أن كنت تريد أن تمر على سهولة الصيانة البرمجية (و لأنني على الأرجح سوف يكون الشخص الذي لديك لجعل التغييرات!).

هل كانت مفيدة؟

المحلول

هذه النقطة هو فصل الخوارزميات إلى الفئات التي يمكن أن تكون في الوتر في وقت التشغيل.على سبيل المثال, دعونا نقول لديك تطبيق يشمل على مدار الساعة.هناك العديد من الطرق المختلفة التي يمكنك رسم على مدار الساعة, ولكن بالنسبة للجزء الأكبر الأساسية وظيفة هو نفسه.حتى تتمكن من إنشاء عرض على مدار الساعة واجهة:

class IClockDisplay
{
    public:
       virtual void Display( int hour, int minute, int second ) = 0;
};

ثم لديك الخاص بك على مدار الساعة الفئة التي يتم التوصيل إلى جهاز توقيت التحديثات على مدار الساعة عرض مرة واحدة في الثانية.لذلك سيكون لديك شيء من هذا القبيل:

class Clock
{
   protected:
      IClockDisplay* mDisplay;
      int mHour;
      int mMinute;
      int mSecond;

   public:
      Clock( IClockDisplay* display )
      {
          mDisplay = display;
      }

      void Start(); // initiate the timer

      void OnTimer()
      {
         mDisplay->Display( mHour, mMinute, mSecond );
      }

      void ChangeDisplay( IClockDisplay* display )
      {
          mDisplay = display;
      }
};

ثم في وقت التشغيل يمكنك إنشاء الخاصة بك على مدار الساعة مع عرض مناسب الدرجة.أيهل يمكن أن يكون ClockDisplayDigital, ClockDisplayAnalog, ClockDisplayMartian كل تنفيذ IClockDisplay واجهة.

في وقت لاحق بحيث يمكنك إضافة أي نوع من جديد عرض على مدار الساعة من خلال خلق طبقة جديدة دون الحاجة إلى فوضى مع الخاص بك على مدار الساعة الصف دون الحاجة إلى تجاوز الأساليب التي يمكن أن تكون الفوضى للحفاظ على التصحيح.

نصائح أخرى

في جافا يمكنك استخدام الشفرات إدخال تيار فك تشفير مثل ذلك:

String path = ... ;
InputStream = new CipherInputStream(new FileInputStream(path), ???);

ولكن تيار الشفرات لا علم خوارزمية تشفير ما كنت تنوي استخدام أو كتلة حجم الحشو استراتيجية الخ...خوارزميات جديدة سوف تضاف في كل وقت حتى hardcoding لهم ليس من العملي.بدلا من ذلك نحن نمر في الشفرات استراتيجية كائن أن أقول ذلك كيفية تنفيذ فك التشفير...

String path = ... ;
Cipher strategy = ... ;
InputStream = new CipherInputStream(new FileInputStream(path), strategy);

بشكل عام يمكنك استخدام نمط استراتيجية في أي وقت لديك أي كائن أن يعرف ما فإنه يحتاج إلى القيام به ولكن لا كيف أن تفعل ذلك.مثال جيد آخر هو تخطيط المديرين في الأرجوحة ، على الرغم من أن في هذه الحالة أنه لم ينجح تماما كما نرى تماما GridBag بالنسبة مسلية التوضيح.

ملحوظة::هناك نوعان من أنماط في العمل هنا ، كما التغليف من تيارات في تيارات مثال الديكور.

هناك فرق بين استراتيجية قرار/اختيار.معظم الوقت ونحن سوف يكون التعامل مع القرارات/الخيارات في المدونة ، وأدرك لهم باستخدام لو()/التبديل() يبني.نمط استراتيجية مفيدة عندما تكون هناك حاجة إلى فصل المنطق/الخوارزمية من الاستخدام.

كمثال, التفكير في آلية الاقتراع ، حيث سيكون للمستخدمين التحقق من الموارد/التحديثات.ونحن الآن قد تريد بعض priveliged إعلام المستخدمين مع تحولا أسرع وقت أو مع مزيد من التفاصيل.Essentailly منطق تستخدم التغييرات استنادا إلى أدوار المستخدمين.استراتيجية المنطقي من تصميم/هندسة معمارية وجهة نظر, في المستويات الدنيا من تحبب أنه ينبغي أن يكون دائما موضع تساؤل.

استراتيجية نمط يسمح لك باستغلال polimorphism دون توسيع الطبقة الرئيسية.في جوهرها ، هي وضع كل متغير أجزاء في استراتيجية واجهة تطبيقات و الطبقة الرئيسية المندوبين لهم.إذا كان الهدف الرئيسي الخاص بك يستخدم سوى استراتيجية واحدة, انها تقريبا نفس وجود مجردة (ظاهري) طريقة تطبيقات مختلفة في كل فئة فرعية.

استراتيجية النهج يقدم بعض الفوائد:

  • يمكنك تغيير الاستراتيجية في وقت التشغيل - قارن هذا إلى تغيير نوع الفئة في وقت التشغيل ، والذي هو أكثر صعوبة بكثير ، مترجم محددة من المستحيل على غير طرق افتراضية
  • أحد أهم فئة يمكن استخدام واحد أو أكثر من الاستراتيجيات التي تسمح لك أن تتحد لهم بطرق متعددة.النظر في الفئة التي يمشي شجرة وتقييم وظيفة على أساس كل عقدة و النتيجة الحالية.هل يمكن أن يكون المشي استراتيجية (العمق أولا أو اتساع الأول) وحساب استراتيجية (بعض functor - أي'عد أرقام إيجابية' أو 'مجموع').إذا كنت لا تستخدم استراتيجيات, سوف تحتاج إلى تنفيذ فرعية لكل تركيبة من المشي/حساب.
  • رمز هو أسهل للحفاظ على تعديل أو فهم الاستراتيجية لا تتطلب منك أن تفهم كل الهدف الرئيسي

العيب هو أن في كثير من الحالات ، نمط استراتيجية هو مبالغة - التبديل/حالة المشغل هناك لسبب ما.النظر في بدء بسيطة التحكم في تدفق البيانات (التبديل/الحالة أو إذا) ثم فقط إذا كان من الضروري الانتقال إلى فئة التسلسل الهرمي إذا كان لديك واحد أو أكثر من أبعاد تقلب استخراج استراتيجيات للخروج منه.مؤشرات الدالة تقع في مكان ما في منتصف هذا التواصل.

القراءة الموصى بها:

طريقة واحدة للنظر في هذا الأمر هو عندما يكون لديك مجموعة متنوعة من الإجراءات التي تريد تنفيذ تلك الإجراءات يتم تحديدها في وقت التشغيل.إذا قمت بإنشاء hashtable أو قاموس من الاستراتيجيات, هل يمكن استرجاع تلك الاستراتيجيات التي تتوافق مع القيادة القيم أو المعايير.مرة واحدة فرعية محددة ، يمكنك ببساطة تكرار قائمة الاستراتيجيات وتنفيذها في الخلافة.

وأحد الأمثلة الملموسة على أن يكون الحساب مجموع النظام.المعلمات الخاصة بك أو الأوامر تكون قاعدة الأسعار المحلية الضرائب ضريبة المدينة, الدولة ضريبة الأرض الشحن خصم القسيمة.المرونة التي تدخل في الاعتبار عند التعامل مع الاختلاف من أوامر - بعض الدول ليس لديها ضريبة المبيعات ، في حين أوامر أخرى سوف تحتاج إلى تطبيق القسيمة.يمكنك حيوي تعيين ترتيب العمليات الحسابية.طالما كنت قد استحوذ على جميع الحسابات الخاصة بك ، يمكنك استيعاب جميع تركيبات دون إعادة تجميع.

هذا تصميم نمط يسمح تغلف الخوارزميات في الطبقات.

الفئة التي يستخدم استراتيجية فئة العميل ، تنفصل من تنفيذ خوارزمية.يمكنك تغيير خوارزميات التنفيذ ، أو إضافة خوارزمية جديدة دون الحاجة إلى تعديل العميل.هذا يمكن أيضا أن يتم بشكل حيوي:يمكن للعميل اختيار خوارزمية أنه سيتم استخدام.

على سبيل المثال, تخيل أحد تطبيقات التي تحتاج إلى حفظ صورة إلى ملف ؛ الصورة يمكن حفظها في صيغ مختلفة (PNG, JPG ...).ترميز خوارزميات سوف تنفذ في فئات مختلفة تقاسم نفس واجهة.فئة العميل اختيار واحد اعتمادا على تفضيل المستخدم.

في ويكيبيديا سبيل المثال ، تلك الحالات التي يمكن تمريرها إلى الدالة التي لا يجب أن تهتم أي فئة الحالات التي تنتمي إليها.وظيفة يدعو فقط execute على وجوه مرت و اعلم أن الحق شيء سيحدث.

مثال نموذجي من نمط استراتيجية هو كيفية عمل الملفات في يونكس.نظرا ملف واصف ، يمكنك قراءة ، كتابة ، الإستطلاع ذلك ، تسعى إلى إرسال ioctlق ، وما إلى ذلك ، دون الحاجة إلى معرفة ما إذا كنت تتعامل مع الملف, دليل, الأنابيب, مأخذ التوصيل ، جهاز ، إلخ.(طبعا بعض العمليات مثل التماس لا تعمل على أنابيب ومآخذ.ولكن يقرأ ويكتب سوف تعمل على ما يرام في هذه الحالات.)

هذا يعني أنه يمكنك كتابة التعليمات البرمجية عام للتعامل مع كل هذه الأنواع المختلفة من "الملفات" ، دون الحاجة إلى كتابة رمز منفصل للتعامل مع الملفات مقابل الدلائل ، إلخ.Unix نواة يعتني تفويض يدعو إلى اليمين رمز.

الآن, هذا هو نمط استراتيجية كما تستخدم في النواة البرمجية ، ولكن لم يتم تحديد أنه يجب أن يكون رمز المستخدم فقط في العالم الحقيقي سبيل المثال.:-)

نمط استراتيجية يعمل على فكرة بسيطة أي"صالح التكوين على الميراث" بحيث استراتيجية/خوارزمية يمكن تغييرها في وقت التشغيل.ولتوضيح ذلك دعونا نأخذ مثالا على ذلك حيث نحن بحاجة إلى تشفير رسائل مختلفة استنادا إلى نوع مثلارسالة البريد, ChatMessage.... الخ

class CEncryptor
{
    virtual void encrypt () = 0;
    virtual void decrypt () = 0;
};
class CMessage
{
private:
    shared_ptr<CEncryptor> m_pcEncryptor;
public:
    virtual void send() = 0;

    virtual void receive() = 0;

    void setEncryptor(cost shared_ptr<Encryptor>& arg_pcEncryptor)
    {
        m_pcEncryptor =  arg_pcEncryptor;
    }

    void performEncryption()
    {
        m_pcEncryptor->encrypt();
    }
};

الآن في وقت التشغيل يمكنك إنشاء رسائل مختلفة الموروثة من CMessage (مثل CMailMessage:العامة CMessage) مع مختلف encryptors (مثل CDESEncryptor:العامة CEncryptor)

CMessage *ptr = new CMailMessage();
ptr->setEncryptor(new CDESEncrypto());
ptr->performEncryption();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top