JavaRush /مدونة جافا /Random-AR /قواعد كتابة التعليمات البرمجية: من إنشاء النظام إلى العمل...

قواعد كتابة التعليمات البرمجية: من إنشاء النظام إلى العمل مع الكائنات

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

نظام

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

مراحل تصميم النظام

  1. النظام البرمجي - تصميم التطبيق بشكل عام.
  2. الفصل إلى أنظمة فرعية/حزم - تحديد الأجزاء القابلة للفصل منطقيًا وتحديد قواعد التفاعل بينها.
  3. تقسيم الأنظمة الفرعية إلى فئات – تقسيم أجزاء النظام إلى فئات وواجهات محددة، بالإضافة إلى تحديد التفاعل بينها.
  4. يعد تقسيم الفئات إلى طرق تعريفًا كاملاً للطرق الضرورية للفئة بناءً على مهمة هذه الفئة. تصميم الطريقة - تعريف تفصيلي لوظيفة الطرق الفردية.
عادة، يكون المطورون العاديون مسؤولين عن التصميم، ويكون مهندس التطبيق مسؤولاً عن العناصر الموضحة أعلاه.

المبادئ والمفاهيم الرئيسية لتصميم النظام

لغة التهيئة البطيئة لا يقضي التطبيق وقتًا في إنشاء كائن حتى يتم استخدامه، مما يؤدي إلى تسريع عملية التهيئة وتقليل تحميل أداة تجميع البيانات المهملة. لكن لا ينبغي أن تبالغ في هذا الأمر، لأن هذا قد يؤدي إلى انتهاك النمطية. قد يكون من المفيد نقل جميع خطوات التصميم إلى جزء معين، على سبيل المثال، main، أو إلى فئة تعمل مثل المصنع . أحد جوانب الكود الجيد هو عدم وجود كود معياري متكرر بشكل متكرر. كقاعدة عامة، يتم وضع هذا الرمز في فئة منفصلة بحيث يمكن استدعاؤه في الوقت المناسب. AOP بشكل منفصل، أود أن أذكر البرمجة الموجهة نحو الجانب . يتم ذلك عن طريق تقديم منطق شامل للبرمجة، أي أنه يتم وضع التعليمات البرمجية المتكررة في فئات - جوانب، ويتم استدعاؤها عند الوصول إلى شروط معينة. على سبيل المثال، عند الوصول إلى طريقة باسم معين أو الوصول إلى متغير من نوع معين. في بعض الأحيان قد تكون الجوانب مربكة، لأنه ليس من الواضح على الفور من أين يتم استدعاء الكود، ولكن مع ذلك، فهذه وظيفة مفيدة للغاية. على وجه الخصوص، عند التخزين المؤقت أو التسجيل: نضيف هذه الوظيفة دون إضافة منطق إضافي إلى الفئات العادية. يمكنك قراءة المزيد عن OAP هنا . 4 قواعد لتصميم الهندسة المعمارية البسيطة وفقا لكينت بيك
  1. التعبير - يتم تحقيق الحاجة إلى هدف واضح للفصل من خلال التسمية الصحيحة وصغر الحجم والالتزام بمبدأ المسؤولية الفردية (سننظر إليها بمزيد من التفصيل أدناه).
  2. الحد الأدنى من الفصول والأساليب - في رغبتك في تقسيم الفصول الدراسية إلى أصغر وأحادية الاتجاه قدر الإمكان، يمكنك الذهاب بعيدًا (antipattern - shotgunning). يدعو هذا المبدأ إلى إبقاء النظام مضغوطًا وعدم المبالغة في ذلك، وإنشاء فئة لكل عطسة.
  3. عدم وجود تكرار - التعليمات البرمجية الإضافية التي تسبب الارتباك هي علامة على سوء تصميم النظام ويتم نقلها إلى مكان منفصل.
  4. تنفيذ جميع الاختبارات - يتم التحكم في النظام الذي اجتاز جميع الاختبارات، حيث أن أي تغيير قد يتسبب في فشل الاختبارات، مما يمكن أن يوضح لنا أن التغيير في المنطق الداخلي للطريقة أدى أيضًا إلى تغيير في السلوك المتوقع.
SOLID عند تصميم النظام، من المفيد مراعاة مبادئ SOLID المعروفة: S - المسؤولية الفردية - مبدأ المسؤولية الفردية؛ O - مفتوح - مغلق - مبدأ الانفتاح/القرب؛ L - استبدال ليسكوف - مبدأ استبدال باربرا ليسكوف؛ I - فصل الواجهة - مبدأ فصل الواجهة؛ د - انقلاب التبعية - مبدأ انقلاب التبعية؛ لن نتناول كل مبدأ على وجه التحديد (هذا خارج نطاق هذه المقالة قليلًا، ولكن يمكنك معرفة المزيد هنا )

واجهه المستخدم

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

فصل

قواعد كتابة التعليمات البرمجية: من إنشاء النظام إلى العمل مع الكائنات - 3دعونا نلقي نظرة على التنظيم الداخلي للفصول الدراسية. أو بالأحرى بعض الآراء والقواعد التي يجب اتباعها عند إنشاء الفصول الدراسية. عادة، يجب أن يبدأ الفصل الدراسي بقائمة من المتغيرات، مرتبة بترتيب معين:
  1. الثوابت الساكنة العامة
  2. الثوابت الثابتة الخاصة؛
  3. متغيرات المثيلات الخاصة.
بعد ذلك هناك مُنشئات مختلفة بالترتيب من عدد أقل إلى عدد أكبر من الوسائط. تليها طرق من الوصول الأكثر انفتاحًا إلى الطرق الأكثر إغلاقًا: كقاعدة عامة، توجد الأساليب الخاصة التي تخفي تنفيذ بعض الوظائف التي نريد تقييدها في الأسفل.

حجم الصف

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

أشياء

قواعد كتابة التعليمات البرمجية: من إنشاء النظام إلى العمل مع الكائنات - 5

التغليف

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

قانون ديميتر

يمكنك أيضًا التفكير في قانون ديميتر: وهو عبارة عن مجموعة صغيرة من القواعد التي تساعد في إدارة التعقيد على مستوى الفصل والطريقة. لذا، لنفترض أن لدينا كائنًا Carوله طريقة - move(Object arg1, Object arg2). وبحسب قانون ديميتر تقتصر هذه الطريقة على استدعاء:
  • طرق الكائن نفسه Car(وبعبارة أخرى، هذا)؛
  • طرق الكائنات التي تم إنشاؤها في move;
  • أساليب تمرير الكائنات كوسائط - arg1, arg2;
  • طرق الكائنات الداخلية Car(نفس هذا).
وبعبارة أخرى، فإن قانون ديميتر يشبه إلى حد ما قاعدة الأطفال - يمكنك التحدث مع الأصدقاء، ولكن ليس مع الغرباء .

بنية البيانات

بنية البيانات عبارة عن مجموعة من العناصر ذات الصلة. عند النظر إلى كائن ما باعتباره بنية بيانات، فهو عبارة عن مجموعة من عناصر البيانات التي تتم معالجتها بطرق، ويعني وجودها ضمنيًا. أي أنه كائن غرضه تخزين وتشغيل (معالجة) البيانات المخزنة. يتمثل الاختلاف الرئيسي عن الكائن العادي في أن الكائن عبارة عن مجموعة من الأساليب التي تعمل على عناصر البيانات التي يكون وجودها ضمنيًا. هل تفهم؟ في الكائن العادي، يكون الجانب الرئيسي هو الأساليب، وتهدف المتغيرات الداخلية إلى تشغيلها بشكل صحيح، ولكن في بنية البيانات يكون الأمر على العكس من ذلك: تدعم الأساليب وتساعد في العمل مع العناصر المخزنة، وهي العناصر الرئيسية هنا. أحد أنواع بنية البيانات هو كائن نقل البيانات (DTO) . هذه فئة تحتوي على متغيرات عامة ولا توجد طرق (أو طرق القراءة/الكتابة فقط) التي تمرر البيانات عند العمل مع قواعد البيانات، والعمل مع تحليل الرسائل من المقابس، وما إلى ذلك. عادةً، لا يتم تخزين البيانات الموجودة في مثل هذه الكائنات لفترة طويلة ويتم تخزينها تم تحويله على الفور تقريبًا إلى الكيان الذي يعمل معه تطبيقنا. والكيان بدوره هو أيضًا بنية بيانات، ولكن الغرض منه هو المشاركة في منطق الأعمال على مستويات مختلفة من التطبيق، في حين أن DTO هو نقل البيانات من/إلى التطبيق. مثال DTO:
@Setter
@Getter
@NoArgsConstructor
public class UserDto {
    private long id;
    private String firstName;
    private String lastName;
    private String email;
    private String password;
}
كل شيء يبدو واضحا، ولكن هنا نتعرف على وجود الهجينة. الهجينة هي كائنات تحتوي على طرق للتعامل مع المنطق المهم وتخزين العناصر الداخلية وطرق الوصول (الحصول عليها/تعيينها). مثل هذه الكائنات فوضوية وتجعل من الصعب إضافة أساليب جديدة. لا ينبغي استخدامها، لأنه ليس من الواضح ما هو المقصود منها - تخزين العناصر أو أداء بعض المنطق. يمكنك أن تقرأ عن الأنواع المحتملة من الكائنات هنا .

مبادئ خلق المتغيرات

قواعد كتابة التعليمات البرمجية: من إنشاء النظام إلى العمل مع الكائنات - 6دعونا نفكر قليلاً في المتغيرات، أو بالأحرى، نفكر في المبادئ التي قد تكون لإنشائها:
  1. من الناحية المثالية، يجب عليك الإعلان عن المتغير وتهيئته مباشرة قبل استخدامه (بدلاً من إنشائه ونسيانه).
  2. كلما أمكن، قم بإعلان المتغيرات كنهائية لمنع قيمتها من التغيير بعد التهيئة.
  3. لا تنس متغيرات العداد (عادةً ما نستخدمها في نوع ما من الحلقات for، أي أنه يجب ألا ننسى إعادة تعيينها، وإلا فقد يؤدي ذلك إلى كسر منطقنا بالكامل).
  4. يجب أن تحاول تهيئة المتغيرات في المُنشئ.
  5. إذا كان هناك خيار بين استخدام كائن مع أو بدون مرجع ( new SomeObject())، فاختر بدون ( )، حيث سيتم حذف هذا الكائن، بمجرد استخدامه، أثناء عملية تجميع البيانات المهملة التالية ولن يضيع الموارد.
  6. جعل عمر المتغيرات أقصر ما يمكن (المسافة بين إنشاء المتغير وآخر وصول).
  7. قم بتهيئة المتغيرات المستخدمة في الحلقة مباشرة قبل الحلقة، وليس في بداية الطريقة التي تحتوي على الحلقة.
  8. ابدأ دائمًا بالنطاق الأكثر محدودية وقم بتوسيعه فقط إذا لزم الأمر (يجب أن تحاول جعل المتغير محليًا قدر الإمكان).
  9. استخدم كل متغير لغرض واحد فقط.
  10. تجنب المتغيرات ذات المعاني الخفية (المتغير محتار بين مهمتين، مما يعني أن نوعه غير مناسب لحل إحداهما).
قواعد كتابة التعليمات البرمجية: من إنشاء النظام إلى العمل مع الكائنات - 7

طُرق

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

  2. القاعدة الثانية هي أن الكتل الموجودة في الأوامر ifو elseو whileوما إلى ذلك لا ينبغي أن تكون متداخلة بشكل كبير: وهذا يقلل بشكل كبير من سهولة قراءة التعليمات البرمجية. من الناحية المثالية، يجب ألا يزيد التعشيش عن كتلتين {}.

    يُنصح أيضًا بجعل التعليمات البرمجية الموجودة في هذه الكتل مضغوطة وبسيطة.

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

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

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

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

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

  7. إذا كانت الطريقة تحتوي على عدد كبير من الوسائط الواردة (القيمة القصوى هي 7، ولكن يجب أن تفكر فيها بعد 2-3)، فأنت بحاجة إلى تجميع بعض الوسائط في كائن منفصل.

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

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

  10. try/catchلا يبدو الأمر جميلًا جدًا بطبيعته، لذا فإن الخطوة الجيدة هي نقله إلى طريقة منفصلة متوسطة (طريقة للتعامل مع الاستثناءات):

    public void exceptionHandling(SomeObject obj) {
        try {
            someMethod(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
لقد تحدثت عن تكرار التعليمات البرمجية أعلاه، ولكني سأضيفها هنا: إذا كان لدينا طريقتان مع أجزاء متكررة من التعليمات البرمجية، فنحن بحاجة إلى نقلها إلى طريقة منفصلة، ​​الأمر الذي سيزيد من ضغط كل من الطريقة والطريقة. فصل. ولا تنسى الأسماء الصحيحة. سأخبرك بتفاصيل التسمية الصحيحة للفئات والواجهات والأساليب والمتغيرات في الجزء التالي من المقالة. وهذا كل ما لدي لهذا اليوم. قواعد كتابة التعليمات البرمجية: من إنشاء النظام إلى العمل مع الكائنات - 9قواعد الكود: قوة التسمية الصحيحة، والتعليقات الجيدة والسيئة
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION