במאמר זה, תלמדו על העקרונות SOLID. תקבלו הבנה על כל עקרון ביחד עם דוגמאות של קוד בשפת ג' אווה.
עקרונות SOLID הם ערך של חמש עקרונות עיצוב שמשמשים בתכנות המוח האובייקטיבי. המשמעות של העקרונות האלה תעזור לך לפתח תוכנה חזקה. הם יעזרו להפוך את הקוד שלך ליותר יעיל, קריא ומתחזק.
SOLID הוא האות האקרונום של:
- עקרון האחריות היחידה
- עקרון הפתיחה/סגירה
- עקרון ההחלפה של ליסקוב
- עקרון הפריצה של הממשקים
- עקרון ההפך של התלות
עקרון האחריות היחידה
עקרון האחריות היחידה אומר שלכל מושג צריך להיות אחת רק, מרכזית, אחת סיבה לשינוי.
public class Employee{
public String getDesignation(int employeeID){ // }
public void updateSalary(int employeeID){ // }
public void sendMail(){ // }
}
בדוגמא העליונה, המושג Employee
קיבל מספר התנהגויות ספציפיות למושג העובד-אחד כמו getDesignation
ו updateSalary
.
בנוסף, יש לו גם שימוש בשיטה שנקראת sendMail
שנעדרת מהאחריות של המושג Employee
.
ההתנהגויות האלה אינן ספציפיות למושג הזה והקיים אותן פוגע בעקרון האחריות היחידה. כדי להתגבר על זה, ניתן להעביר את שיטת sendMail
למושג נפרד.
כך זה נראה:
public class Employee{
public String getDesignation(int employeeID){ // }
public void updateSalary(int employeeID){ // }
}
public class NotificationService {
public void sendMail() { // }
}
עיקרון פתוח/סגור
לפי עיקרון פתוח/סגור, רכיבים חייבים להיות פתוחים להרחבה אך סגורים לשינויים. כדי להבין את העיקרון הזה, בואו נקח דוגמא למודל של משהו שמחשב את האזור של צורה.
public class AreaCalculator(){
public double area(Shape shape){
double areaOfShape;
if(shape instanceof Square){
// חשב את האזור של הריבוע
} else if(shape instanceof Circle){
// חשב את האזור של העיגול
}
return areaOfShape;
}
הבעיה עם הדוגמה העליונה היא שאם יוצא מובן שיהיה מקבצים חדשים מסוג Shape
עליהם תצטרך לחשב את האזור בעתיד, תצטרך לשנות את המודל העליון על ידי הוספת מודל else-if
נוסף. תהיי צריך לעשות זאת בשביל כל מקבץ חדש של סוג Shape
.
על מנת לפתור את זה, תוכל ליצור ממשק ולהחזיק כל מקבץ Shape
למימוש את הממשק. אז, כל מקבץ יוכל לספק את היישום המקרי שלו לחשב את האזור. זה יגביר את האפשרויות העתידיות בתוכנה שלך.
interface IAreaCalculator(){
double area();
}
class Square implements IAreaCalculator{
@Override
public double area(){
System.out.println("Calculating area for Square");
return 0.0;
}
}
class Circle implements IAreaCalculator{
@Override
public double area(){
System.out.println("Calculating area for Circle");
return 0.0;
}
}
עיקרון ההחלפה של ליסקוב
עיקרון ההחלפה של ליסקוב אומר שאתה צריך להוכיח שניתן להחליף אובייקט של הסוף הגבוה באובייקט של הסוף הנמוך ללא השפעה על ההתנהגות הנכונה של התוכנה.
abstract class Bird{
abstract void fly();
}
class Eagle extends Bird {
@Override
public void fly() { // מבנה מסויים }
}
class Ostrich extends Bird {
@Override
public void fly() { // מבנה מדומה }
}
בדוגמה העליונה, המורה Eagle
ומורה Ostrich
משתרעות אחת מהמורה Bird
ומשתמשים על מתן הפעולה fly()
. אף על פי כן, המורה Ostrich
נאלצה לספק יישום מדומה בגלל שהיא לא יכולה לעוף, ולכן היא לא מתהגה באותה דרך אם נחליף את המורה Bird
בעלתה.
זה נוגד את עיקרון ההחלפה הליסקובי.
abstract class FlyingBird{
abstract void fly();
}
abstract class NonFlyingBird{
abstract void doSomething();
}
class Eagle extends FlyingBird {
@Override
public void fly() { כדי לתת מידה לזה, אנחנו יכולים ליצור מין מקום חדש עבור ציפורים שיכולות לעוף ולהרשים שהמורה Eagle
תהיה סביבה בעלתה, בעוד ציפורים אחרות יכולות להרשים סביבה אחרת, שלא תכלל את ההתנהגות fly
.// מיקום מסויים }
}
class Ostrich extends NonFlyingBird {
@Override
public void doSomething() { // מיקום מסויים }
}
עיקרון הפריצה למערכות ממשקים
לפי עיקרון הפריצה למערכות ממשקים, צריך לבנות מערכות ממשקים קטנות ומ focus שלא מכריעים את הלקוח למימוש התנהגויות שהוא לא צריך.
דוגמה פשוטה לזה תהיה מערך של משק שמנתן להתמודדות באזור וגודל של צורה.
interface IShapeAreaCalculator(){
double calculateArea();
double calculateVolume();
}
class Square implements IShapeAreaCalculator{
double calculateArea(){ // מנתן אזור }
double calculateVolume(){ // יישום מדומה }
}
הבעיה עם זה היא שאם צורה Square
מימשה את המערך הזה, אז היא נאלצה ליישם את הפעולה calculateVolume()
, שהיא לא צריכה.
על הצד השני, מודל Cube
יכול ליישם שניהם. כדי להתגבר על זה, אנחנו יכולים למחלק את הממשק ולקבע שני ממשקים נפרדים: אחד לחישוב השטח ואחד לחישוב החלל. זה יאפשר לצורות המיפוי להחליט מה ליישם.
interface IAreaCalculator {
double calculateArea();
}
interface IVolumeCalculator {
double calculateVolume();
}
class Square implements IAreaCalculator {
@Override
public double calculateArea() { // חישוב השטח }
}
class Cube implements IAreaCalculator, IVolumeCalculator {
@Override
public double calculateArea() { // חישוב השטח }
@Override
public double calculateVolume() {// חישוב החלל }
}
עקרון ההפך מהתלות
בעקרון ההפך מהתלות, מודלים גבוהים צריכים לא לתלות במודלים נמוכים. במילים אחרות, עליך לעקוב אחר ההדמייה ולוודא קישורים חלקיים.
public interface Notification {
void notify();
}
public class EmailNotification implements Notification {
public void notify() {
System.out.println("Sending notification via email");
}
}
public class Employee {
private EmailNotification emailNotification;
public Employee(EmailNotification emailNotification) {
this.emailNotification = emailNotification;
}
public void notifyUser() {
emailNotification.notify();
}
}
בדוגמה הנתנה, המודל Employee
מתלוי ישירות במודל EmailNotification
, שהוא מודל נמוך. זה פוגע בעקרון ההפך מהתלות.
public interface Notification{
public void notify();
}
public class Employee{
private Notification notification;
public Employee(Notification notification){
this.notification = notification;
}
public void notifyUser(){
notification.notify();
}
}
public class EmailNotification implements Notification{
public void notify(){
// ממשק ההודעה באמצעות דוא״ל
}
}
public static void main(String [] args){
Notification notification = new EmailNotification();
Employee employee = new Employee(notification);
employee.notifyUser();
}
בדוגמה העליונה, אנחנו אימצנו קישורים חלקיים. Employee
אינו תלוי ביישום קירבן, אלא רק בהדמייה (ממשק ההודעה).
אם נצטרך לשינוי השיטה להודעה, נוכל ליצור יישום חדש ולעבור אותו ל Employee
.
סיכום
לסיכום, עברנו על המהות של עקרונות SOLID דרך דוגמאות פשוטות במאמר זה.
העקרונות האלה מהבסיסים לפיתוח יישומים הולכים להיות מאוד מתהליכים וניתנים לשימוש מחדש.
בואו ניצור קשר בLinkedIn
Source:
https://www.freecodecamp.org/news/introduction-to-solid-principles/