في تطوير البرمجيات، تعد صيانة التعليمات البرمجية والإرشاد والمرونة أمرًا مهمًا لنجاح المشروع على المدى الطويل. تمت صياغة مبادئ SOLID لتوجيه المطورين في إنشاء تعليمات برمجية يسهل فهمها وتعديلها وتوسيعها. في هذه المقالة سنتحدث عن كل مبدأ من مبادئ SOLID الخمسة وكيفية استخدامها مع أمثلة عملية في لغة Java.
ينص مبدأ المسؤولية الفردية (SRP) على أن الفصل يجب أن يكون لديه سبب واحد فقط للتغيير، أي أنه يجب أن يكون لديه مسؤولية واحدة داخل النظام.
// Antes de aplicar o SRP class ProductService { public void saveProduct(Product product) { // Lógica para salvar o produto no banco de dados } public void sendEmail(Product product) { // Lógica para enviar um email sobre o produto } }
// Após aplicar o SRP class ProductService { public void saveProduct(Product product) { // Lógica para salvar o produto no banco de dados } } class EmailService { public void sendEmail(Product product) { // Lógica para enviar um email sobre o produto } }
في المثال، نفصل مسؤولية حفظ المنتج في قاعدة البيانات عن مسؤولية إرسال رسائل البريد الإلكتروني حول المنتج. وهذا يسهل التغييرات المستقبلية، حيث أن التغييرات في إرسال رسائل البريد الإلكتروني لم تعد تؤثر على منطق حفظ المنتج.
يقترح المبدأ المفتوح/المغلق (OCP) أن الكيانات البرمجية (الفئات، الوحدات، الوظائف، إلخ) يجب أن تكون مفتوحة للتوسيع، ولكنها مغلقة للتعديل. ويتم تحقيق ذلك من خلال استخدام التجريد والميراث.
// Exemplo inicial violando o OCP class AreaCalculator { public double calculateArea(Rectangle[] rectangles) { double area = 0; for (Rectangle rectangle : rectangles) { area = rectangle.width * rectangle.height; } return area; } }
// Exemplo após aplicar o OCP interface Forma { double calculateArea(); } class Rectangle implements Forma { private double width; private double height; public Rectangle(double width, double height) { this.width = width; this.height = height; } @Override public double calculateArea() { return width * height; } } class AreaCalculator { public double calculateArea(Forma [] formas) { double area = 0; for (Forma formas: formas) { area = forma.calculateArea(); } return area; } }
في هذا المثال الثاني، كانت فئة AreaCalculator في البداية تعتمد بشكل مباشر على فئة Rectangle. هذا يعني أنك إذا أردت إضافة نوع آخر من الأشكال، مثل دائرة أو مثلث، فستحتاج إلى تعديل فئة AreaCalculator، وبالتالي انتهاك OCP. مع إنشاء واجهة الشكل، أصبحت فئة AreaCalculator قادرة على استقبال أشكال هندسية جديدة دون تعديل الكود الموجود.
ينص مبدأ استبدال ليسكوف (LSP) على أن كائنات الفئة الفائقة يجب أن تكون قابلة للاستبدال بكائنات من فئاتها الفرعية دون التأثير على سلامة النظام. بمعنى آخر، يجب أن يكون سلوك الفئات الفرعية متسقًا مع سلوك الفئات الفائقة.
// Classe base class Bird { public void fly() { // Método padrão que imprime "Flying" System.out.println("Flying"); } } // Classe derivada que viola o LSP class Duck extends Bird { @Override public void fly() { // Sobrescrita que imprime "Ducks cannot fly" System.out.println("Ducks cannot fly"); } }
المشكلة: تتجاوز فئة Duck طريقة fly () لطباعة "البط لا يستطيع الطيران"، وبالتالي تغيير السلوك الافتراضي المحدد في فئة الطيور الأساسية، وهو أن جميع الطيور تطير ("تحلق"). هذا ينتهك LSP لأن أي كود يتوقع أن يطير كائن Bird أو فئاته الفرعية لن يعمل بشكل صحيح مع البطة، والتي نعلم بالفعل أنها لا تطير.
// Classe derivada que respeita o LSP interface Bird { void fly(); } class Eagle implements Bird { @Override public void fly() { System.out.println("Flying like an Eagle"); } } class Duck implements Bird { @Override public void fly() { throw new UnsupportedOperationException("Ducks cannot fly"); } }
مع هذا النهج، يمكن استبدال Eagle وDuck حيث يُتوقع وجود طائر، دون كسر التوقعات التي حددتها واجهة Bird. يشير الاستثناء الذي طرحه Duck بوضوح إلى أن البط لا يطير، دون تعديل سلوك الطبقة المتفوقة بطريقة قد تسبب مشاكل غير متوقعة في الكود.
يقترح مبدأ فصل الواجهة (ISP) أن واجهات الفصل يجب أن تكون خاصة بالعملاء الذين يستخدمونها. يؤدي هذا إلى تجنب الواجهات "السمينة" التي تتطلب تنفيذ أساليب لا يستخدمها العملاء.
// Exemplo antes de aplicar o ISP interface Worker { void work(); void eat(); void sleep(); } class Programmer implements Worker { @Override public void work() { // Lógica específica para programar } @Override public void eat() { // Lógica para comer } @Override public void sleep() { // Lógica para dormir } }
// Exemplo após aplicar o ISP interface Worker { void work(); } interface Eater { void eat(); } interface Sleeper { void sleep(); } class Programmer implements Worker, Eater, Sleeper { @Override public void work() { // Lógica específica para programar } @Override public void eat() { // Lógica para comer } @Override public void sleep() { // Lógica para dormir } }
في المثال، قمنا بتقسيم واجهة العامل إلى واجهات أصغر (العمل، تناول الطعام، النوم) للتأكد من أن الفئات التي تنفذها لديها فقط الأساليب التي تحتاجها. وهذا يمنع الفئات من الاضطرار إلى تنفيذ أساليب غير ذات صلة بها، مما يحسن وضوح التعليمات البرمجية وتماسكها.
يقترح مبدأ انعكاس التبعية (DIP) أن الوحدات عالية المستوى (مثل فئات الأعمال أو التطبيقات، التي تنفذ قواعد العمل الرئيسية) لا ينبغي أن تعتمد على وحدات منخفضة المستوى (فئات البنية التحتية، مثل الوصول إلى البيانات الخارجية و الخدمات التي تدعم العمليات رفيعة المستوى). كلاهما يجب أن يعتمد على التجريدات.
// Exemplo antes de aplicar o DIP class BackendDeveloper { public void writeJava() { // Lógica para escrever em Java } } class Project { private BackendDeveloper developer; public Project() { this.developer = new BackendDeveloper(); } public void implement() { developer.writeJava(); } }
// Exemplo após aplicar o DIP interface Developer { void develop(); } class BackendDeveloper implements Developer { @Override public void develop() { // Lógica para escrever em Java } } class Project { private Developer developer; public Project(Developer developer) { this.developer = developer; } public void implement() { developer.develop(); } }
تعتمد فئة المشروع الآن على التجريد (المطور) بدلاً من التنفيذ الملموس (BackendDeveloper). يسمح هذا بدمج أنواع مختلفة من المطورين (مثل FrontendDeveloper وMobileDeveloper) بسهولة في فئة Project دون تعديل الكود الخاص بها.
إن اعتماد مبادئ SOLID لا يؤدي فقط إلى رفع جودة التعليمات البرمجية الخاصة بك، بل يعزز أيضًا مهاراتك التقنية، ويزيد من كفاءة عملك، ويعزز مسارك المهني كمطور برامج.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3