الكود حي ومات. الجزء الثاني الإجراءات والخصائص

آخر مرة كتبت أن أسماء الأشياء لها أهمية كبيرة ، وأنها تحتاج إلى اختيارها بعناية مع الاهتمام بالتفاصيل. اسم سيء يخيف ولا يسمح لفهم جوهر ما يحدث. ولكن ما هو جوهر هذا؟


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


حول هذا - في المقال.


جدول دورة المحتويات


  1. الكائنات
  2. الإجراءات والخصائص
  3. الرمز كنص

الإجراءات


الهجمات الشخصية ، يدافع ، يتهرب ، يطلق النار من القوس ، ويستخدم نوبات ، ويلوح شفرة. يعكس الاسم الكائن ، ولكن الكائن نفسه يتحرك ، كرد فعل ، في العمل. خلاف ذلك ، كنا نتحدث عن الجداول في Excel.


في C # ، الإجراءات هي الطرق والوظائف. ولنا: الأفعال ، ذرات الحركة الكلامية. الأفعال تتحرك الوقت ، بسببها الكائنات موجودة وتتفاعل. عندما يكون هناك تغيير - يجب أن يكون هناك فعل.


اضعي


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


على سبيل المثال ، هناك IPullRequest مع خاصية Status ، والتي يمكن IPullRequest أو IPullRequest أو Merged . يمكنك كتابة pullRequest.Status = Status.Declined ، ولكن هذا هو نفسه قول "تعيين طلب التجمع إلى الحالة الملغاة" ، أمر حتمي. أقوى بكثير هو pullRequest.Decline() ، وبالتالي ، pullRequest.Approve() ، pullRequest.Merge() .


الفعل النشط هو الأفضل من واضع ، ولكن ليس كل الأفعال هي.


صوت سلبي


PerformPurchase ، DoDelete ، MakeCall .


كما هو الحال في HeroManager يتم إخفاء اسم مهم من قبل Manager بلا معنى ، لذلك في PerformMigration - Perform . بعد كل شيء ، على قيد الحياة أكثر - مجرد Migrate !


تعمل الأفعال النشطة على تحديث النص: ليس "ضرب" ، ولكن "ضرب" ؛ ليس "صنع تأرجح" ، ولكن "لوح" ؛ ليس "اتخذ قرارًا" ، ولكن " اتخذ " . حتى في التعليمات البرمجية: PerformApplicationApply ؛ DoDeleteDelete ؛ PerformPurchasePurchase ، Buy . (لكن DealDamage استقرت ، على الرغم من أنه في حالات نادرة قد يكون الهدف من Attack .)


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


أفعال قوية


بعض الكلمات تنقل ظلال المعنى أفضل من غيرها. إذا كتبت "شرب كوبًا من الماء" ، فسيكون ذلك بسيطًا وواضحًا. لكن "استنزف كوبًا من الماء" - مجازيًا ، أقوى.


لذلك يمكن التعبير عن التغيير الصحي للاعب من خلال player.Health = X أو player.Health = X ، ولكن المزيد من player.RestoreHealth الخلابة هي player.RestoreHealth .


أو ، على سبيل المثال ، نحن نعرف Stack ليس عن طريق Add/Remove ، ولكن عن طريق Push/Pop .


أفعال قوية ونشطة تشبع الكائن مع السلوك ، إذا لم تكن محددة للغاية.


أجزاء زائدة عن الحاجة


كما هو الحال مع ManualResetEvent ، فكلما اقتربنا من الحدود الداخلية التقنية لـ .NET ، والتي ستكون معقدة وسيكون من الجيد التعبير عنها ببساطة ، كلما كانت تفاصيل وتجاوزات واجهة برمجة التطبيقات أكثر ثراءً.


يحدث أنك تحتاج إلى القيام ببعض الأعمال في سلسلة رسائل أخرى ، ولكن حتى لا تهتم بإنشاء هذا البرنامج وإيقافه. في C # هناك ThreadPool لهذا. هنا فقط هو بسيط "القيام بالعمل" هنا - QueueUserWorkItem ! ما نوع عنصر العمل ( WorkItem ) وما يمكن أن يكون ، إن لم يكن المستخدم ( User ) ، غير واضح. سيكون أسهل بكثير - ThreadPool.Run أو ThreadPool.Execute .


مثال آخر إن التذكر ومعرفة وجود تعليمات مقارنة ومبادلة ذرية (CAS) أمر جيد ، ولكن نقلها نظيفًا إلى الكود ليس هو الحل الأفضل. Interlocked.CompareExchange(ref x, newX, oldX) أدنى من Interlocked.CompareExchange(ref x, newX, oldX) Atomically.Change(ref x, from: oldX, to: newX) (باستخدام المعلمات المسماة).


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


تكرار


UsersRepository.AddUser ، Benchmark.ExecuteBenchmark ، AppInitializer.Initialize ، UniversalMarshaller.Marshal ، Logger.LogError .


كما قلت في الجزء الأخير ، التكرار يؤدي إلى تآكل المعنى ، ويضغط المساحة.


ليس UsersRepository.AddUser ، لكن UsersRepository.Add ؛ ليس Directory.CreateDirectory ، ولكن Directory.Create ؛ ليس HttpWebResponse.GetResponseStream ، ولكن HttpWebResponse.Stream ؛ ليس Logger.LogError ، ولكن Log.Error .


القمامة الجميلة


Check كلمة متعددة الجوانب. يمكن CheckHasLongName إما إرجاع bool أو رمي استثناء إذا كان لدى المستخدم اسم طويل جدًا. الأفضل هو bool HasLongName أو void EnsureHasShortName . حتى قابلت CheckRebootCounter ، والتي ... في الداخل ، CheckRebootCounter تشغيل IIS!


Enumerate - من نفس السلسلة. هناك طريقة Directory.EnumerateDirectories(path) في .NET: لسبب ما ، يتم تحديد أن المجلدات سيتم سردها ، على الرغم من أن path.Directories() Directories.Of(path) أو path.Directories() .


Calc كثير من الأحيان يتم تقليل Calculate - Calculate ، على الرغم من أنها تبدو أكثر مثل رواسب الكالسيوم.


Proc هو اختصار آخر يتوهم للعملية.


الكلمات Base ، Impl ، Internal ، Raw الطفيلية التي تشير إلى تعقيد الأشياء.


في المجموع


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


الآن وبعد أن اكتشفنا الحركة و "المؤثرات الخاصة" ، دعونا نلقي نظرة على كيفية وصف العلاقات بين الكائنات.


الخصائص


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


في C # ، الخصائص والعلاقات هي طرق (عادة ما تبدأ بـ Get ) ، getters (خصائص ذات نص get معين) ، والحقول. ولكن بالنسبة لنا هو: الكلمات - الإضافات التي تعبر عن انتماء كائن إلى آخر. على سبيل المثال ، يتمتع اللاعب بصحة - Player.Health ، والذي يتوافق تقريبًا مع "صحة اللاعب" الإنجليزية.


ما هو الأكثر حيرة اليوم هو أساليب العمل وأساليب الملكية.


الفعل بدلا من الاسم


GetDiscount ، CalculateDamage ، FetchResult ، ComputeFov ، CreateMap .


يسمع التسويات في كل مكان: يجب أن تبدأ الطرق بالأفعال. نادراً ما ترى أي شخص يشكك: هل هذا صحيح حقًا؟ بعد كل شيء ، لا يمكن أن يكون هناك فرق كبير بين Player.Health و Player.Health() . دع السجلات تكون مختلفة في سياقها ، فهي تعني نفس الشيء.


لنفترض أنه في IUsersRepository ، من IUsersRepository بعض GetUser(int id) . لماذا ، لتمثيل المستخدم ، فكر في نوع من الإيصال ( Get )؟ سيكون أكثر دقة - User(int id) !


وحقا: لا FetchResult() ، ولكن Result() ؛ ليس GetResponse() ، لكن Response() ؛ ليس CalculateDamage() ، ولكن Damage() .


نقاش DDD واحد يعطي مثالاً على الكود "الجيد": DiscountCalculator مع طريقة CalculateDiscountBy(int customerId) . ليس هناك فقط تكرار متماثل على الوجه - DiscountCalculator.CalculateDiscount ، فقد حددوا أيضًا أنه يتم حساب الخصم. وماذا يسأل المرء ماذا يفعل معها؟


سيكون أقوى من الانتقال من الكيان نفسه - Discount باستخدام static decimal Of(Customer customer, Order order) للاتصال _discountCalculator.CalculateDiscountBy(customerId) من Discount.Of(customer, order) - هو أبسط من _discountCalculator.CalculateDiscountBy(customerId) ، ويتوافق مع لغة واحدة.


أحيانًا ، عند حذف الفعل ، نفقد شيئًا ، كما يقول ، في CreateMap() : قد لا يكون الاستبدال المباشر بـ Map() كافيًا. الحل الأفضل هو NewMap() : مرة أخرى ، الكائن في الرأس ، وليس الإجراء.


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


آخر


الخصائص والأساليب التي تعبر عن العلاقات بين الأشياء هي أيضًا كائنات ، وبالتالي ، فإن ما سبق ذكره في كثير من النواحي ينطبق عليها.


على سبيل المثال ، التكرار في الخصائص: ليس Thread.CurrentThread ، لكن Thread.Current ؛ ليس Inventory.InventoryItems . عناصر Inventory.InventoryItems ، ولكن Inventory.Items . Inventory.Items ، الخ.


في المجموع


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


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


في أول مقالتين من السلسلة ، أردت أن أوضح مدى أهمية العمل ليس فقط على الخوارزمية ، ولكن أيضًا على الكلمة ؛ كيف تحدد الأسماء محتوى ما يسمى ؛ كيف رمز زائدة ومضاعفة يحرك القارئ بعيدا.


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

Source: https://habr.com/ru/post/ar447674/


All Articles