CodeGym /Java Blog /சீரற்ற /SOLID: ஜாவாவில் வர்க்க வடிவமைப்பின் ஐந்து அடிப்படைக் கோட்...
John Squirrels
நிலை 41
San Francisco

SOLID: ஜாவாவில் வர்க்க வடிவமைப்பின் ஐந்து அடிப்படைக் கோட்பாடுகள்

சீரற்ற குழுவில் வெளியிடப்பட்டது
வகுப்புகள் பயன்பாடுகளின் கட்டுமானத் தொகுதிகள். கட்டிடத்தில் செங்கற்களைப் போல. மோசமாக எழுதப்பட்ட வகுப்புகள் இறுதியில் சிக்கல்களை ஏற்படுத்தும். SOLID: ஜாவாவில் வர்க்க வடிவமைப்பின் ஐந்து அடிப்படைக் கொள்கைகள் - 1ஒரு வகுப்பு சரியாக எழுதப்பட்டுள்ளதா என்பதைப் புரிந்து கொள்ள, அது "தரத் தரங்களுக்கு" எவ்வாறு செல்கிறது என்பதை நீங்கள் சரிபார்க்கலாம். ஜாவாவில், இவை SOLID கொள்கைகள் என்று அழைக்கப்படுகின்றன, நாங்கள் அவற்றைப் பற்றி பேசப் போகிறோம்.

ஜாவாவில் SOLID கொள்கைகள்

SOLID என்பது OOP மற்றும் வகுப்பு வடிவமைப்பின் முதல் ஐந்து கொள்கைகளின் பெரிய எழுத்துக்களில் இருந்து உருவான சுருக்கமாகும். 2000 களின் முற்பகுதியில் ராபர்ட் மார்ட்டின் கொள்கைகளை வெளிப்படுத்தினார், பின்னர் சுருக்கமானது மைக்கேல் ஃபெதர்ஸால் அறிமுகப்படுத்தப்பட்டது. இங்கே SOLID கொள்கைகள் உள்ளன:
  1. ஒற்றைப் பொறுப்புக் கொள்கை
  2. மூடிய கொள்கையைத் திறக்கவும்
  3. லிஸ்கோவ் மாற்றுக் கொள்கை
  4. இடைமுகம் பிரித்தல் கோட்பாடு
  5. சார்பு தலைகீழ் கொள்கை

ஒற்றைப் பொறுப்புக் கொள்கை (SRP)

ஒரு வகுப்பை மாற்றுவதற்கு ஒன்றுக்கு மேற்பட்ட காரணங்கள் இருக்கக்கூடாது என்று இந்தக் கொள்கை கூறுகிறது . ஒவ்வொரு பொருளுக்கும் ஒரு பொறுப்பு உள்ளது, இது வகுப்பில் முழுமையாக இணைக்கப்பட்டுள்ளது. ஒரு வகுப்பின் அனைத்து சேவைகளும் இந்தப் பொறுப்பை ஆதரிப்பதை நோக்கமாகக் கொண்டுள்ளன. தேவைப்பட்டால், அத்தகைய வகுப்புகள் எப்போதுமே மாற்றியமைக்க எளிதாக இருக்கும், ஏனென்றால் வகுப்பு எது மற்றும் பொறுப்பல்ல என்பது தெளிவாக உள்ளது. வேறு வார்த்தைகளில் கூறுவதானால், நாம் மாற்றங்களைச் செய்ய முடியும் மற்றும் விளைவுகளைப் பற்றி பயப்படக்கூடாது, அதாவது பிற பொருட்களின் மீதான தாக்கம். கூடுதலாக, அத்தகைய குறியீட்டைச் சோதிப்பது மிகவும் எளிதானது, ஏனென்றால் உங்கள் சோதனைகள் மற்ற எல்லாவற்றிலிருந்தும் தனிமைப்படுத்தப்பட்ட செயல்பாட்டை உள்ளடக்கியது. ஆர்டர்களைச் செயல்படுத்தும் ஒரு தொகுதியை கற்பனை செய்து பாருங்கள். ஒரு ஆர்டர் சரியாக உருவாக்கப்பட்டால், இந்த தொகுதி அதை ஒரு தரவுத்தளத்தில் சேமித்து, ஆர்டரை உறுதிப்படுத்த மின்னஞ்சலை அனுப்புகிறது:

public class OrderProcessor {

    public void process(Order order){
        if (order.isValid() && save(order)) {
            sendConfirmationEmail(order);
        }
    }

    private boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }

    private void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }
}
இந்த தொகுதி மூன்று காரணங்களுக்காக மாறலாம். முதலில், ஆர்டர்களை செயலாக்குவதற்கான தர்க்கம் மாறலாம். இரண்டாவதாக, ஆர்டர்கள் சேமிக்கப்படும் விதம் (தரவுத்தள வகை) மாறலாம். மூன்றாவதாக, உறுதிப்படுத்தல் அனுப்பப்படும் விதம் மாறலாம் (உதாரணமாக, மின்னஞ்சலுக்கு பதிலாக ஒரு குறுஞ்செய்தியை அனுப்ப வேண்டும் என்று வைத்துக்கொள்வோம்). இந்த பிரச்சனையின் மூன்று அம்சங்களும் உண்மையில் மூன்று வெவ்வேறு பொறுப்புகள் என்பதை ஒற்றை பொறுப்புக் கொள்கை குறிக்கிறது. அதாவது அவை வெவ்வேறு வகுப்புகள் அல்லது தொகுதிகளில் இருக்க வேண்டும். வெவ்வேறு நேரங்களில் மற்றும் வெவ்வேறு காரணங்களுக்காக மாறக்கூடிய பல நிறுவனங்களை இணைப்பது மோசமான வடிவமைப்பு முடிவாகக் கருதப்படுகிறது. ஒரு தொகுதியை மூன்று தனித்தனி தொகுதிகளாகப் பிரிப்பது மிகவும் சிறந்தது, ஒவ்வொன்றும் ஒரு செயல்பாட்டைச் செய்கிறது:

public class MySQLOrderRepository {
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }
}

public class ConfirmationEmailSender {
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }
}

public class OrderProcessor {
    public void process(Order order){

        MySQLOrderRepository repository = new MySQLOrderRepository();
        ConfirmationEmailSender mailSender = new ConfirmationEmailSender();

        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }

}

திறந்த மூடிய கொள்கை (OCP)

இந்த கொள்கை பின்வருமாறு விவரிக்கப்பட்டுள்ளது: மென்பொருள் நிறுவனங்கள் (வகுப்புகள், தொகுதிகள், செயல்பாடுகள் போன்றவை) நீட்டிப்புக்காக திறந்திருக்க வேண்டும், ஆனால் மாற்றத்திற்காக மூடப்பட்டிருக்க வேண்டும் . வகுப்பின் தற்போதைய குறியீட்டில் மாற்றங்களைச் செய்யாமல் ஒரு வகுப்பின் வெளிப்புற நடத்தையை மாற்ற முடியும் என்பதே இதன் பொருள். இந்தக் கொள்கையின்படி, வகுப்புகள் வடிவமைக்கப்பட்டுள்ளன, இதனால் குறிப்பிட்ட நிபந்தனைகளுக்கு ஏற்றவாறு ஒரு வகுப்பை மாற்றியமைக்க, அதை நீட்டிக்கவும் சில செயல்பாடுகளை மேலெழுதவும் வேண்டும். இதன் பொருள், கணினி நெகிழ்வானதாக இருக்க வேண்டும், மூலக் குறியீட்டை மாற்றாமல் மாறும் நிலைமைகளில் வேலை செய்ய முடியும். ஆர்டர் செயலாக்கத்தை உள்ளடக்கிய எங்கள் உதாரணத்தைத் தொடர்கிறோம், ஒரு ஆர்டரைச் செயலாக்குவதற்கு முன்பும், உறுதிப்படுத்தல் மின்னஞ்சல் அனுப்பப்பட்ட பிறகும் சில செயல்களைச் செய்ய வேண்டும் என்று வைத்துக்கொள்வோம். மாற்றுவதற்கு பதிலாகOrderProcessorவகுப்பிலேயே, திறந்த மூடிய கொள்கையை மீறாமல் எங்கள் நோக்கத்தை நிறைவேற்ற அதை விரிவுபடுத்துவோம்:

public class OrderProcessorWithPreAndPostProcessing extends OrderProcessor {

    @Override
    public void process(Order order) {
        beforeProcessing();
        super.process(order);
        afterProcessing();
    }
    
    private void beforeProcessing() {
        // Take some action before processing the order
    }
    
    private void afterProcessing() {
        // Take some action after processing the order
    }
}

லிஸ்கோவ் மாற்றுக் கொள்கை (LSP)

இது நாம் முன்பு குறிப்பிட்ட திறந்த மூடிய கொள்கையின் மாறுபாடு. இது பின்வருமாறு வரையறுக்கப்படலாம்: நிரலின் பண்புகளை மாற்றாமல் பொருள்களை துணைப்பிரிவுகளின் பொருள்களால் மாற்றலாம். இதன் பொருள், ஒரு அடிப்படை வகுப்பை விரிவுபடுத்துவதன் மூலம் உருவாக்கப்பட்ட ஒரு வகுப்பு அதன் முறைகளை மீற வேண்டும், இதனால் கிளையன்ட் பார்வையில் இருந்து செயல்பாடு சமரசம் செய்யப்படாது. அதாவது, ஒரு டெவலப்பர் உங்கள் வகுப்பை விரிவுபடுத்தி, அதை ஒரு பயன்பாட்டில் பயன்படுத்தினால், அவர் அல்லது அவள் எந்த மேலெழுதப்பட்ட முறைகளின் எதிர்பார்க்கப்படும் நடத்தையை மாற்றக்கூடாது. கிளையண்டின் பார்வையில் இருந்து செயல்பாடு உடைக்கப்படாமல் இருக்க, துணைப்பிரிவுகள் அடிப்படை வகுப்பின் முறைகளை மீற வேண்டும். பின்வரும் எடுத்துக்காட்டில் இதை விரிவாக ஆராயலாம். ஒரு ஆர்டரைச் சரிபார்ப்பதற்கும், ஆர்டரில் உள்ள அனைத்துப் பொருட்களும் கையிருப்பில் உள்ளதா என்பதைச் சரிபார்க்கும் பொறுப்பு எங்களிடம் உள்ளது என்று வைத்துக்கொள்வோம்.isValid()உண்மை அல்லது பொய்யை வழங்கும் முறை :

public class OrderStockValidator {

    public boolean isValid(Order order) {
        for (Item item : order.getItems()) {
            if (!item.isInStock()) {
                return false;
            }
        }

        return true;
    }
}
சில ஆர்டர்கள் வேறுவிதமாக சரிபார்க்கப்பட வேண்டும் என்று வைத்துக்கொள்வோம், எ.கா. சில ஆர்டர்களுக்கு ஆர்டரில் உள்ள அனைத்து பொருட்களும் கையிருப்பில் உள்ளதா மற்றும் அனைத்து பொருட்களும் நிரம்பியுள்ளனவா என்பதை சரிபார்க்க வேண்டும். OrderStockValidatorஇதைச் செய்ய, வகுப்பை உருவாக்குவதன் மூலம் வகுப்பை விரிவுபடுத்துகிறோம் OrderStockAndPackValidator:

public class OrderStockAndPackValidator extends OrderStockValidator {

    @Override
    public boolean isValid(Order order) {
        for (Item item : order.getItems()) {
            if ( !item.isInStock() || !item.isPacked() ){
                throw new IllegalStateException(
                     String.format("Order %d is not valid!", order.getId())
                );
            }
        }

        return true;
    }
}
ஆனால் இங்கே நாங்கள் Liskov மாற்றுக் கொள்கையை மீறியுள்ளோம், ஏனெனில் ஆர்டர் சரிபார்ப்பில் தோல்வியுற்றால் தவறானதாகத் திரும்புவதற்குப் பதிலாக , எங்கள் முறை ஒரு IllegalStateException. இந்தக் குறியீட்டைப் பயன்படுத்தும் வாடிக்கையாளர்கள் இதை எதிர்பார்க்க மாட்டார்கள்: அவர்கள் உண்மை அல்லது தவறான மதிப்பை எதிர்பார்க்கிறார்கள் . இது இயக்க நேர பிழைகளுக்கு வழிவகுக்கும்.

இடைமுகம் பிரித்தல் கோட்பாடு (ISP)

இது பின்வரும் அறிக்கையால் வகைப்படுத்தப்படுகிறது: கிளையன்ட் அவர்கள் பயன்படுத்தாத முறைகளைச் செயல்படுத்த கட்டாயப்படுத்தக்கூடாது . இடைமுகப் பிரிப்புக் கொள்கை என்பது மிகவும் "தடிமனாக" இருக்கும் இடைமுகங்கள் சிறிய, குறிப்பிட்டதாகப் பிரிக்கப்பட வேண்டும் என்பதாகும், இதனால் சிறிய இடைமுகங்களைப் பயன்படுத்தும் வாடிக்கையாளர்கள் தங்கள் பணிக்குத் தேவையான முறைகளைப் பற்றி மட்டுமே அறிந்து கொள்வார்கள். இதன் விளைவாக, ஒரு இடைமுக முறை மாறும்போது, ​​அந்த முறையைப் பயன்படுத்தாத எந்த கிளையண்டும் மாறக்கூடாது. இந்த உதாரணத்தைக் கவனியுங்கள்: அலெக்ஸ், ஒரு டெவலப்பர், ஒரு "அறிக்கை" இடைமுகத்தை உருவாக்கி இரண்டு முறைகளைச் சேர்த்துள்ளார்: generateExcel()மற்றும்generatedPdf(). இப்போது ஒரு கிளையன்ட் இந்த இடைமுகத்தைப் பயன்படுத்த விரும்புகிறார், ஆனால் அறிக்கைகளை PDF வடிவத்தில் மட்டுமே பயன்படுத்த விரும்புகிறார், எக்செல் இல் அல்ல. இந்த செயல்பாடு இந்த வாடிக்கையாளரை திருப்திப்படுத்துமா? இல்லை. கிளையன்ட் இரண்டு முறைகளை செயல்படுத்த வேண்டும், அவற்றில் ஒன்று பெரும்பாலும் தேவையில்லை மற்றும் மென்பொருளை வடிவமைத்த அலெக்ஸுக்கு மட்டுமே நன்றி. கிளையன்ட் வேறு இடைமுகத்தைப் பயன்படுத்துவார் அல்லது எக்செல் அறிக்கைகளுக்கான முறையுடன் எதுவும் செய்யமாட்டார். அப்படியானால் என்ன தீர்வு? தற்போதுள்ள இடைமுகத்தை இரண்டு சிறியதாகப் பிரிப்பதாகும். ஒன்று PDF அறிக்கைகளுக்கு, மற்றொன்று எக்செல் அறிக்கைகளுக்கு. இது வாடிக்கையாளர்களுக்குத் தேவையான செயல்பாட்டை மட்டுமே பயன்படுத்த அனுமதிக்கிறது.

சார்பு தலைகீழ் கோட்பாடு (டிஐபி)

ஜாவாவில், இந்த SOLID கொள்கை பின்வருமாறு விவரிக்கப்படுகிறது: கணினியில் உள்ள சார்புகள் சுருக்கங்களின் அடிப்படையில் கட்டமைக்கப்படுகின்றன. உயர்-நிலை தொகுதிகள் கீழ்-நிலை தொகுதிகள் சார்ந்து இல்லை. சுருக்கங்கள் விவரங்களைச் சார்ந்து இருக்கக்கூடாது. விவரங்கள் சுருக்கத்தைப் பொறுத்தது. பல்வேறு தொகுதிக்கூறுகள் சுயமாக மற்றும் சுருக்கம் மூலம் ஒன்றோடொன்று இணைக்கப்படும் வகையில் மென்பொருள் வடிவமைக்கப்பட வேண்டும். இந்த கொள்கையின் உன்னதமான பயன்பாடு வசந்த கட்டமைப்பாகும். ஸ்பிரிங் கட்டமைப்பில், அனைத்து தொகுதிக்கூறுகளும் ஒன்றாக வேலை செய்யக்கூடிய தனித்தனி கூறுகளாக செயல்படுத்தப்படுகின்றன. அவை மிகவும் தன்னாட்சி பெற்றவை, அவை ஸ்பிரிங் கட்டமைப்பைத் தவிர மற்ற நிரல் தொகுதிகளில் எளிதாகப் பயன்படுத்தப்படலாம். மூடிய மற்றும் திறந்த கொள்கைகளின் சார்பு காரணமாக இது அடையப்படுகிறது. அனைத்து தொகுதிகளும் சுருக்கத்திற்கு மட்டுமே அணுகலை வழங்குகின்றன, இது மற்றொரு தொகுதியில் பயன்படுத்தப்படலாம். ஒரு உதாரணத்தைப் பயன்படுத்தி இதை விளக்க முயற்சிப்போம். ஒற்றை பொறுப்புக் கொள்கையைப் பற்றி பேசுகையில், நாங்கள் கருதினோம்OrderProcessorவர்க்கம். இந்த வகுப்பின் குறியீட்டை மீண்டும் பார்ப்போம்:

public class OrderProcessor {
    public void process(Order order){

        MySQLOrderRepository repository = new MySQLOrderRepository();
        ConfirmationEmailSender mailSender = new ConfirmationEmailSender();

        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }

}
இந்த எடுத்துக்காட்டில், எங்கள் OrderProcessorவகுப்பு இரண்டு குறிப்பிட்ட வகுப்புகளைச் சார்ந்துள்ளது: MySQLOrderRepositoryமற்றும் ConfirmationEmailSender. இந்த வகுப்புகளின் குறியீட்டையும் நாங்கள் வழங்குவோம்:

public class MySQLOrderRepository {
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }
}

public class ConfirmationEmailSender {
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }
}
இந்த வகுப்புகள் நாம் சுருக்கங்கள் என்று அழைப்பதில் இருந்து வெகு தொலைவில் உள்ளன. சார்பு தலைகீழ் கொள்கையின் பார்வையில், குறிப்பிட்ட செயலாக்கங்களை விட, எதிர்காலத்தில் நாம் வேலை செய்யக்கூடிய சில சுருக்கங்களை உருவாக்குவதன் மூலம் தொடங்குவது நல்லது. இரண்டு இடைமுகங்களை உருவாக்குவோம்: MailSenderமற்றும் OrderRepository). இவை எங்கள் சுருக்கங்களாக இருக்கும்:

public interface MailSender {
    void sendConfirmationEmail(Order order);
}

public interface OrderRepository {
    boolean save(Order order);
}
இதற்காக ஏற்கனவே தயாரிக்கப்பட்ட வகுப்புகளில் இந்த இடைமுகங்களை இப்போது செயல்படுத்துகிறோம்:

public class ConfirmationEmailSender implements MailSender {

    @Override
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }

}

public class MySQLOrderRepository implements OrderRepository {

    @Override
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }
}
நாங்கள் ஆயத்த வேலைகளைச் செய்தோம், அதனால் எங்கள் OrderProcessorவகுப்பு உறுதியான விவரங்களில் அல்ல, ஆனால் சுருக்கங்களைச் சார்ந்தது. எங்கள் சார்புகளை கிளாஸ் கன்ஸ்ட்ரக்டரில் சேர்ப்பதன் மூலம் அதை மாற்றுவோம்:

public class OrderProcessor {

    private MailSender mailSender;
    private OrderRepository repository;

    public OrderProcessor(MailSender mailSender, OrderRepository repository) {
        this.mailSender = mailSender;
        this.repository = repository;
    }

    public void process(Order order){
        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }
}
இப்போது எங்கள் வகுப்பு சுருக்கங்களைச் சார்ந்தது, குறிப்பிட்ட செயலாக்கங்கள் அல்ல. OrderProcessorஒரு பொருளை உருவாக்கும் நேரத்தில் விரும்பிய சார்புநிலையைச் சேர்ப்பதன் மூலம் அதன் நடத்தையை நாம் எளிதாக மாற்றலாம் . ஜாவாவில் உள்ள SOLID வடிவமைப்பு கொள்கைகளை ஆய்வு செய்துள்ளோம். நீங்கள் பொதுவாக OOP மற்றும் ஜாவா புரோகிராமிங்கின் அடிப்படைகள் பற்றி மேலும் அறிந்து கொள்வீர்கள் - சலிப்பு எதுவும் இல்லை மற்றும் நூற்றுக்கணக்கான மணிநேர பயிற்சி - CodeGym பாடத்திட்டத்தில். சில பணிகளை தீர்க்க நேரம் :)
கருத்துக்கள்
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION