Sobes.tech
Middle+
165

Сен SOLID принципі ашықтық-жабықтықты жобалау кезінде қалай қолданасың?

AI-дан жауап

sobes.tech AI

Мен ашықтық/жабықтық қағидатын (Open/Closed Principle - OCP) қолданамын, кеңейтілімділікке назар аудара отырып, бар кодты өзгертуге болмайды.

Негізгі тәсілдер:

  • Абстракциялар (интерфейстер мен абстрактілі сыныптар) қолдану: Менің кодым абстракциялардан тәуелді, нақты жүзеге асырулардан емес. Бұл жаңа жүзеге асыруларды бар кодты өзгертусіз қосуға мүмкіндік береді, ол осы абстракциялардан тәуелді.

    // Контрактты көрсететін интерфейс
    public interface PaymentProcessor {
        void processPayment(BigDecimal amount);
    }
    
    // Нақты жүзеге асыру
    public class CreditCardPaymentProcessor implements PaymentProcessor {
        @Override
        public void processPayment(BigDecimal amount) {
            // Кредиттік карта өңдеу логикасы
            System.out.println("Кредиттік карта төлемін өңдеу: " + amount);
        }
    }
    
    // Басқа жүзеге асыру
    public class PayPalPaymentProcessor implements PaymentProcessor {
        @Override
        public void processPayment(BigDecimal amount) {
            // PayPal өңдеу логикасы
            System.out.println("PayPal төлемін өңдеу: " + amount);
        }
    }
    
    // Абстракцияны қолданатын сынып, өзгертуге жабық, бірақ жаңа PaymentProcessor-лермен кеңейтілуі мүмкін
    public class Order {
        private PaymentProcessor paymentProcessor;
    
        public Order(PaymentProcessor paymentProcessor) {
            this.paymentProcessor = paymentProcessor;
        }
    
        public void finalizeOrder(BigDecimal totalAmount) {
            paymentProcessor.processPayment(totalAmount);
            // Қосымша тапсырыс логикасы
        }
    }
    
  • Стратегия (Strategy Pattern): Бұл жобалау үлгісі OCP-нің нақты көрінісі. Ол алгоритмдердің отбасын анықтауға, әрқайсысын инкапсуляциялауға және оларды алмастыруға мүмкіндік береді.

    // Стратегия интерфейсі
    interface ShippingStrategy {
        BigDecimal calculateCost(BigDecimal weight);
    }
    
    // Нақты стратегия
    class StandardShipping implements ShippingStrategy {
        @Override
        public BigDecimal calculateCost(BigDecimal weight) {
            return weight.multiply(new BigDecimal("2.5"));
        }
    }
    
    // Басқа стратегия
    class ExpressShipping implements ShippingStrategy {
        @Override
        public BigDecimal calculateCost(BigDecimal weight) {
            return weight.multiply(new BigDecimal("5.0")).add(new BigDecimal("10.0"));
        }
    }
    
    // Контекст, стратегияны қолданатын, өзгертуге жабық, бірақ жаңа стратегиялармен кеңейтілуі мүмкін
    class Order {
        private ShippingStrategy shippingStrategy;
    
        public Order(ShippingStrategy shippingStrategy) {
            this.shippingStrategy = shippingStrategy;
        }
    
        public BigDecimal getShippingCost(BigDecimal weight) {
            return shippingStrategy.calculateCost(weight);
        }
    }
    
  • Шаблонды әдіс (Template Method Pattern): Бұл суперкласс ішіндегі алгоритмнің қаңқасын анықтайды, ал жүзеге асыру бөлшектерін подклассқа қалдырады. Бұл алгоритм қадамдарын өзгертуге мүмкіндік береді, оның құрылымын өзгеріссіз.

    // Абстрактілі класс, шаблонды әдіспен
    abstract class DataProcessor {
        // Шаблонды әдіс
        public final void processData() {
            readData();
            transformData();
            writeData();
        }
    
        // Қайталанатын әдістер, подклассқа арналған
        abstract void readData();
        abstract void transformData();
        abstract void writeData();
    }
    
    // Нақты процессор, шаблонды кеңейтеді
    class CSVDataProcessor extends DataProcessor {
        @Override
        void readData() {
            System.out.println("CSV-дан деректерді оқу...");
        }
    
        @Override
        void transformData() {
            System.out.println("CSV деректерін түрлендіру...");
        }
    
        @Override
        void writeData() {
            System.out.println("Деректерді мәліметтер қорына жазу...");
        }
    }
    
  • Фабрика әдістері (Factory Methods): Объектілерді құру үшін интерфейс ұсынады, бірақ нақты объектілердің түрін подкласс анықтайды. Бұл объектілерді құруды икемді етеді, клиенттік кодты өзгерту қажет емес.

    interface Product {
        void use();
    }
    
    class ConcreteProductA implements Product {
        @Override
        public void use() {
            System.out.println("Өнім A-ны пайдалану");
        }
    }
    
    class ConcreteProductB implements Product {
        @Override
        public void use() {
            System.out.println("Өнім B-ны пайдалану");
        }
    }
    
    abstract class Creator {
        public void operation() {
            Product product = factoryMethod();
            product.use();
        }
    
        // Фабрика әдісі
        protected abstract Product factoryMethod();
    }
    
    class ConcreteCreatorA extends Creator {
        @Override
        protected Product factoryMethod() {
            return new ConcreteProductA();
        }
    }
    
    class ConcreteCreatorB extends Creator {
        @Override
        protected Product factoryMethod() {
            return new ConcreteProductB();
        }
    }
    

Осы тәсілдерді қолдана отырып, мен кодты оңай қолдау, кеңейту және тестілеу оңай болатындай етіп жасаймын, жаңа функционал қосқанда қателіктердің ықтималдығын азайтамын.