لماذا تلتزم بـ get-set وليس car.speed() وcar.speed(55) على التوالي؟

StackOverflow https://stackoverflow.com/questions/2051713

سؤال

وبصرف النظر عن الوضوح الذي لا لبس فيه، لماذا يجب أن نتمسك بما يلي:
car.getSpeed() و car.setSpeed(55)
عندما يمكن استخدام هذا أيضًا:car.speed() و car.speed(55)

أعلم أن get() و set() مفيدان لإبقاء أي تغييرات على عضو البيانات قابلة للإدارة من خلال الاحتفاظ بكل شيء في مكان واحد.

ومن الواضح أيضًا أنني أفهم ذلك car.speed() و car.speed(55) هي نفس الدالة، مما يجعل هذا الأمر خاطئًا، ولكن بعد ذلك في PHP وأيضًا في Zend Framework، يتم استخدام نفس الإجراء في GET وPOST وعمليات إعادة النشر.
في VB وC#، هناك "خصائص"، ويستخدمها الكثيرون، الأمر الذي أثار اشمئزاز الأصوليين الذين سمعتهم، وهناك أشياء في روبي مثل 5.times و .each, .to_i إلخ.
ولديك التحميل الزائد للمشغل، والوراثة المتعددة، والوظائف الافتراضية في C++، ومجموعات معينة منها يمكن أن تدفع أي شخص إلى الجنون.

أقصد أن أقول إن هناك العديد من النماذج والطرق التي يتم بها القيام بالأشياء بحيث يبدو من الغريب أنه لم يجرب أحد التركيبة المحددة التي ذكرتها.

أما بالنسبة لي، فسببي هو أنه كذلك قصيرة وأنظف للقراءة الرمز.
هل أنا مخطئ جدًا، أو مخطئ قليلاً، هل هذا غريب جدًا وبالتالي لا يُستخدم، أم ماذا أيضًا؟

إذا قررت البقاء على صواب، فيمكنني استخدام ذلك car.speed() و car.setSpeed(55).
هل هذا خطأ بأي شكل من الأشكال (فقط حذف "الحصول" )؟

شكرا على أي تفسيرات.

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

المحلول

إذا اتصلت بـ car.speed()، فقد أعتقد أنني أخبر السيارة بالسرعة، وبعبارة أخرى، زيادة السرعة وكسر الحد الأقصى للسرعة.ليس من الواضح أنه حاصل.

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

أيضًا، عندما تقول أن القراءة أكثر وضوحًا، يمكنني أن أزعم أنه يجب علي إلقاء نظرة للأمام لفهم كيفية قراءتها:

car.speed()

قرأت "سرعة السيارة..." ثم رأيت أنه لا يوجد رقم، لذا قمت بالمراجعة وفكرت في "الحصول على سرعة السيارة".

car.getSpeed()

قرأت "لهذه السيارة، احصل على السرعة"

car.setSpeed(55)

قرأت "لهذه السيارة، اضبط السرعة على 55"

يبدو أنك قد استشهدت بشكل أساسي بميزات أخرى للغة باعتبارها مربكة، ثم استخدمت ذلك كدفاع لجعل الحروف/المحددات أكثر إرباكًا؟يبدو الأمر وكأننا نعترف بأن ما اقترحته أكثر إرباكًا.تكون هذه الميزات مربكة في بعض الأحيان بسبب مدى غرضها العام.في بعض الأحيان يمكن أن تكون التجريدات أكثر إرباكًا، لكنها في النهاية تخدم غالبًا غرض كونها أكثر قابلية لإعادة الاستخدام.أعتقد أنك إذا أردت الجدال لصالح السرعة () والسرعة (55)، فأنت تريد إظهار كيف يمكن أن يتيح ذلك إمكانيات جديدة للمبرمج.

من ناحية أخرى، تحتوي لغة C# على شيء يشبه ما تصفه، نظرًا لأن الخصائص تتصرف بشكل مختلف كأداة getter أو setter اعتمادًا على السياق الذي يتم استخدامه فيه:

Console.WriteLine(car.Speed); //getter

car.Speed = 55 //setter

ولكن على الرغم من أنها خاصية واحدة، إلا أن هناك قسمين منفصلين من التعليمات البرمجية لتنفيذ الحصول والإعداد، ومن الواضح أن هذه عبارة عن مُحضر/أداة ضبط وليست سرعة دالة، لأنها تحذف () للخصائص.لذا من الواضح أن car.speed() هي دالة، ومن الواضح أن car.speed هي دالة حاصلة على الخاصية.

نصائح أخرى

IMHO، يعد أسلوب C# الذي يحتوي على خصائص مثل السكر النحوي لطرق الحصول والضبط هو الأكثر تعبيرًا.

أفضّل الكائنات النشطة التي تغلف العمليات بدلاً من الحروف والمحددات، بحيث تحصل على كائنات أكثر ثراءً من الناحية الدلالية.

على سبيل المثال، على الرغم من أن ADT بدلاً من كائن الأعمال، حتى vector في C++ يحتوي على وظائف مقترنة:

size_type capacity() const // how many elements space is reserved for in the vector  
void reserve(size_type n)  // ensure space is reserved for at least n elements 

و

void push_back ( const T& ) // inserts an element at the end
size_type size () const     // the number of elements in the vector

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

لمعلوماتك، يستخدم Objective-C car.speed() و car.setSpeed(55) (إلا في بناء جملة مختلف، [car speed] و [car setSpeed:55].

الأمر كله يتعلق بالاتفاقية.

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

FWIW أفضّل فئة. اسم () للحصول على، و class.verb() للواضع.في بعض الأحيان يكون الفعل مجرد setNoun()، لكن في أحيان أخرى لا يكون كذلك.ذلك يعتمد على الاسم.على سبيل المثال:

my_vector.size() 

إرجاع الحجم، و

my_vector.resize(some_size) 

يغير الحجم.

النهج الرائع في التعامل مع العقارات ممتاز جدًا، IMHO، http://groovy.codehaus.org/Groovy+Beans

يجب أن تكون المعايير النهائية للتعليمات البرمجية الخاصة بك كما يلي:

  1. هل يعمل بشكل صحيح؟
  2. هل من السهل إصلاحه إذا انكسر؟
  3. هل من السهل إضافة ميزات جديدة في المستقبل؟
  4. هل من السهل أن يأتي شخص آخر ويصلحه/يعززه؟

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

استخدم الأسلوب الذي يناسبك، فقط كن متسقًا بشأنه، وستكون على ما يرام.

هذه مجرد مسألة اتفاقية.في Smalltalk، يتم تنفيذ الأمر بالطريقة التي تقترحها ولا أذكر أنني سمعت أي شخص يشتكي من ذلك.الحصول على سرعة السيارة هو car speed, ، وضبط سرعة السيارة على 55 هو car speed:55.

إذا كنت سأغامر بالتخمين، فسأقول إن السبب وراء عدم انتشار هذا الأسلوب هو السطرين اللذين أتت إلينا البرمجة كائنية التوجه:C++ والهدف-C.في لغة C++ (وحتى في وقت مبكر جدًا من تاريخها)، ترتبط الأساليب ارتباطًا وثيقًا بوظائف لغة C، ويتم تسمية وظائف لغة C بشكل تقليدي على غرار setWhatever() ولا يوجد بها تحميل زائد لأعداد مختلفة من الوسائط، بحيث يتم الحفاظ على النمط العام للتسمية.تم الحفاظ على Objective-C إلى حد كبير بواسطة شركة NeXT (التي أصبحت فيما بعد شركة Apple)، وكانت شركة NeXT تميل إلى تفضيل الإسهاب في واجهات برمجة التطبيقات الخاصة بها وخاصة التمييز بين الأنواع المختلفة من الأساليب - إذا كنت تفعل أي شيء سوى الوصول إلى خاصية ما، أرادت شركة NeXT فعلًا لنوضح.لذلك أصبح هذا هو التقليد في Cocoa، وهي المكتبة القياسية الفعلية لـ Objective-C هذه الأيام.

إنها اتفاقية Java لديها اتفاقية من الحروف والمحددات C# لها خصائص، والبايثون لديها حقول عامة وتميل أطر عمل JavaScript إلى استخدام field() للحصول على وfield(value) لتعيينها

وبصرف النظر عن الوضوح الذي لا لبس فيه، لماذا يجب أن نتمسك بما يلي:car.getspeed () و car.setspeed (55) عندما يمكن استخدام ذلك أيضًا:car.speed() وcar.speed(55)

لأنه في جميع اللغات التي واجهتها، car.speed() و car.speed(55) هي نفسها من حيث بناء الجملة.مجرد النظر إليهما بهذه الطريقة، يمكن أن يُرجع كلاهما قيمة، وهذا ليس صحيحًا بالنسبة للأخيرة إذا كان من المفترض أن تكون أداة ضبط.

ماذا لو كنت تنوي الاتصال بالضابط ولكنك نسيت أن تضع الحجة؟الكود صالح، لذلك لا يشكو المترجم، ولا يلقي خطأ وقت التشغيل الفوري؛إنها حشرة صامتة.

.() يعني أنه فعل.no () تعني أنه اسم.

   car.Speed = 50;
   x = car.Speed
   car.Speed.set(30)
   car.setProperty("Speed",30)

لكن

   car.Speed()

يعني الأمر بتجاوز الحد الأقصى للسرعة.

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