سؤال

ما هي العوامل التي تحدد النهج الأكثر ملاءمة؟

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

المحلول

أعتقد أن كلاهما لهما مكانهما.

لا يجب أن تستخدم ببساطة DoSomethingToThing(Thing n) فقط لأنك تعتقد أن "البرمجة الوظيفية جيدة".وبالمثل لا ينبغي عليك ببساطة استخدام Thing.DoSomething() لأن "البرمجة الشيئية جيدة".

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

على سبيل المثال، إذا كان جزء "الجملة" الذي ترغب في التركيز عليه هو الكائن، فيجب عليك استخدام النمط OO.

مثال:

fileHandle.close();

في معظم الأوقات، عندما تقوم بتمرير مقابض الملفات، فإن الشيء الرئيسي الذي تفكر فيه هو تتبع الملف الذي تمثله.

مكافحة المثال:

string x = "Hello World";
submitHttpRequest( x );

في هذه الحالة، يعد إرسال طلب HTTP أكثر أهمية بكثير من السلسلة التي تمثل النص، لذلك submitHttpRequst(x) من الأفضل أن x.submitViaHttp()

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

networkConnection.submitHttpRequest(x)

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

نصائح أخرى

لكي تكون موجهًا للكائنات، أخبر، لا تسأل: http://www.pragmaticprogrammer.com/articles/tell-dont-ask.

لذا، Thing.DoSomething() بدلاً من DoSomethingToThing(Thing n).

إذا كنت تتعامل مع الحالة الداخلية لشيء ما، فإن Thing.DoSomething() يكون أكثر منطقية، لأنه حتى إذا قمت بتغيير التمثيل الداخلي لـ Thing، أو كيفية عمله، فلن يلزم أن يتغير الكود الذي يتحدث إليه.إذا كنت تتعامل مع مجموعة من الأشياء، أو تكتب بعض الأساليب المساعدة، فقد يكون النمط الإجرائي DoSomethingToThing() أكثر منطقية أو أكثر مباشرة؛ولكن لا يزال من الممكن عادةً تمثيلها كتابع على الكائن الذي يمثل تلك المجموعة:على سبيل المثال

GetTotalPriceofThings();

ضد

Cart.getTotal();

يعتمد الأمر حقًا على مدى توجه التعليمات البرمجية الخاصة بك للكائنات.

  1. شيء. افعل شيئًا يكون مناسبًا إذا كان الشيء هو موضوع الجملة.
    • DoSomethingToThing(الشيء ن) يكون مناسبًا إذا كان الشيء هو موضوع الجملة.
    • ThingA.DoSomethingToThingB(ThingB م) هو مزيج لا مفر منه، لأنه في جميع اللغات التي يمكنني التفكير فيها، تنتمي الوظائف إلى فئة واحدة وليست مملوكة للطرفين.لكن هذا منطقي لأنه يمكن أن يكون لديك موضوع وكائن.

الصوت النشط أكثر وضوحًا من الصوت السلبي، لذا تأكد من أن الجملة تحتوي على موضوع ليس مجرد "الكمبيوتر".وهذا يعني، استخدام النموذج 1 والنموذج 3 بشكل متكرر، واستخدام النموذج 2 نادرًا.

للتوضيح:

// Form 1:  "File handle, close."
fileHandle.close(); 

// Form 2:  "(Computer,) close the file handle."
close(fileHandle);

// Form 3:  "File handle, write the contents of another file handle."
fileHandle.writeContentsOf(anotherFileHandle);

أنا أتفق مع أوريون، ولكنني سأعيد صياغة عملية اتخاذ القرار.

لديك اسم وفعل / مفعول به وعمل.

  • إذا كانت العديد من الكائنات من هذا النوع ستستخدم هذا الإجراء، فحاول جعل الإجراء جزءًا من الكائن.
  • بخلاف ذلك، حاول تجميع الإجراء بشكل منفصل، ولكن مع الإجراءات ذات الصلة.

أنا أحب أمثلة الملف/السلسلة.هناك العديد من عمليات السلسلة، مثل "SendAsHTTPReply"، والتي لن تحدث لسلسلة متوسطة، ولكنها تحدث غالبًا في إعداد معين.ومع ذلك، ستغلق دائمًا ملفًا (نأمل)، لذا فمن المنطقي تمامًا وضع إجراء الإغلاق في واجهة الفصل الدراسي.

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

لا توجد معلومات كافية تقريبًا هنا.يعتمد الأمر على ما إذا كانت لغتك تدعم البنية "Thing.something" أو ما يعادلها (على سبيل المثال.إنها لغة OO).إذا كان الأمر كذلك، فهو أكثر ملاءمة لأن هذا هو نموذج OO (يجب أن يرتبط الأعضاء بالكائن الذي يتصرفون عليه).بأسلوب إجرائي، بالطبع، DoSomethingtoThing() هو خيارك الوحيد...أو شيء يفعل شيئا ()

سيكون DoSomethingToThing(Thing n) أكثر من نهج وظيفي في حين أن Thing.DoSomething() سيكون أكثر من نهج موجه للكائنات.

هذا هو خيار البرمجة الشيئية مقابل البرمجة الإجرائية :)

أعتقد أن مزايا OO الموثقة جيدًا تنطبق على Thing.DoSomething()

فيما يلي بعض العوامل التي يجب مراعاتها:

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

حتى لو كنت لا تعمل بلغة OO، حيث سيكون لديك Thing.DoSomething()، لسهولة القراءة الشاملة للتعليمات البرمجية الخاصة بك، مع وجود مجموعة من الوظائف مثل:

ThingDosomething () thingdoanothertask () thingwedosomethingelse ()

ثم

شيء آخر يفعل شيئًا ()

وما إلى ذلك أفضل بكثير.

كل التعليمات البرمجية التي تعمل على "الشيء" موجودة في مكان واحد.بالطبع، يجب تسمية "DoSomething" والمهام الأخرى بشكل متسق - بحيث يكون لديك ThingOneRead()، وThingTwoRead()...الآن يجب أن تحصل على نقطة.عندما تعود إلى العمل على الكود خلال اثني عشر شهرًا، ستقدر تخصيص الوقت لجعل الأمور منطقية.

بشكل عام، إذا كان "شيئًا ما" عبارة عن إجراء يعرف "الشيء" كيفية القيام به بشكل طبيعي، فيجب عليك استخدام thing.doSomething().يعد هذا تغليفًا جيدًا لـ OO، وإلا فسيتعين على DoSomethingToThing(thing) الوصول إلى المعلومات الداخلية المحتملة لـ "thing".

على سبيل المثال، bill.getTotal()

إذا لم يكن "شيء ما" جزءًا من نموذج مجال "الشيء" بشكل طبيعي، فإن أحد الخيارات هو استخدام طريقة مساعدة.

على سبيل المثال:Logger.log(فاتورة)

إذا كان من المحتمل أن يؤدي القيام بشيء ما لكائن ما إلى نتيجة مختلفة في سيناريو آخر، فأنا أقترح عليك oneThing.DoSomethingToThing(anotherThing).

على سبيل المثال، قد يكون لديك شيئين لحفظ شيء ما في برنامجك، لذلك قد تتبنى DatabaseObject.Save(thing) SessionObject.Save(thing) سيكون أكثر فائدة من thing.Save() أو thing.SaveToDatabase أو thing.SaveToSession() .

نادرًا ما أقوم بتمرير أي معلمات إلى الفصل الدراسي، إلا إذا كنت أستعيد الخصائص العامة.

للإضافة إلى إجابة أيون، يعتمد الأمر على الشيء وما تريد فعله به.لذا، إذا كنت تكتب شيئًا، وقام DoSomething بتغيير الحالة الداخلية للشيء، فإن أفضل طريقة هي Thing.DoSomething.ومع ذلك، إذا كان الإجراء يتجاوز مجرد تغيير الحالة الداخلية، فإن DoSomething(Thing) يكون أكثر منطقية.على سبيل المثال:

Collection.Add(Thing)

أفضل من

Thing.AddSelfToCollection(Collection)

وإذا لم تكتب شيئًا، ولا يمكنك إنشاء فئة مشتقة، فليس لديك خيار سوى القيام بشيء ما (شيء)

حتى في البرمجة الشيئية قد يكون من المفيد استخدام استدعاء دالة بدلاً من الطريقة (أو في هذا الصدد استدعاء طريقة لكائن آخر غير تلك التي نسميها عليه).تخيل إطار عمل بسيط لاستمرارية قاعدة البيانات حيث تريد فقط استدعاء save() على كائن ما.بدلاً من تضمين عبارة SQL في كل فئة ترغب في حفظها، وبالتالي تعقيد التعليمات البرمجية، ونشر SQL في جميع أنحاء التعليمات البرمجية وجعل تغيير محرك التخزين PITA، يمكنك إنشاء واجهة تحدد save(Class1)، save(Class2) ) إلخ.وتنفيذها.ثم ستتصل فعليًا بقاعدة البيانات dataSaver.save(class1) وستحصل على كل شيء في مكان واحد.

يجب أن أتفق مع كيفن كونر

ضع في اعتبارك أيضًا المتصل بأي من النموذجين.من المحتمل أن يكون المتصل وسيلة لكائن آخر يفعل بالتأكيد شيئًا ما لشيءك :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top