Розділ[19]: Перегляд об’єктно-орієнтованого проектування: Комплексна платіжна система на Java

pic

Зображення від freepik

Ми знову повернемося до деяких ключових концепцій об'єктно-орієнтованого проектування (ООП), реалізуючи платіжну систему (яку ми вже частково створили), що використовує різні методи, такі як UPI, кредитні картки, дебетові картки та PayPal. Наприкінці цього процесу ви будете мати міцне розуміння того, як впроваджувати ці основні принципи таким чином, щоб це було і практично, і легко для розуміння.

Давайте розберемо кожну концепцію — Наслідування, Поліморфізм, Абстракція, Інкапсуляція та Композиція (останній раз) — і як ми можемо застосувати їх для створення надійної платіжної системи.

1. Наслідування: Створення на основі основ

У нашому випадку є базовий клас PaymentProcessor, який міститиме загальну логіку для обробки платежів. Потім ми розширюємо цей базовий клас, створюючи спеціалізовані типи платежів, такі як UPI, дебетова картка, кредитна картка та PayPal.

Ось як це працює: ми визначаємо загальний метод для обробки платежів у класі PaymentProcessor, а потім кожен з підкласів — UpiPayments, DebitCardPayments тощо — перевизначає цей метод для впровадження власної специфічної логіки.

2. Поліморфізм: Залишаємо це гнучким

Наприклад, чи ми обробляємо платіж через UPI, чи через PayPal, метод для обробки платежу залишається тим самим. Однак реалізація змінюється залежно від типу платежу, завдяки поліморфізму. Тому коли ми викликаємо processPayment(), фактичний метод, що виконується, залежить від того, чи працюємо ми з екземпляром UPI, дебетової картки, кредитної картки чи PayPal.

3. Абстракція: Приховування складності

У нашому проектуванні клас PaymentProcessor є абстрактним. Це означає, що нам не потрібно знати, як кожен метод оплати обробляється, коли ми його викликаємо; ми просто знаємо, що він буде оброблений, і залишаємо подробиці підкласам.

Абстрактний клас визначає метод processPayment(), але саме підкласи (такі як UpiPayments, DebitCardPayments тощо) відповідають за заповнення деталей того, як платіж насправді відбувається. Це дозволяє зробити наш код чистішим і зручнішим для керування.

4. Інкапсуляція: Захист даних

Цей принцип особливо корисний у нашому класі UserProfile, де ми зберігаємо чутливі дані користувача, такі як імена та електронні адреси. Замість того, щоб надавати прямий доступ до цих полів, ми використовуємо методи отримання та встановлення значень.

Наприклад, замість того, щоб безпосередньо отримувати ім'я користувача, ми викликаємо userProfile.getName(). Таким чином, ми можемо контролювати, як дані доступаються і оновлюються, додаючи рівень безпеки і запобігаючи несподіваним змінам.

5. Композиція: Створення через взаємозв'язки

Наслідування добре підходить для створення відносин "is-a" (наприклад, DebitCardPayment — це PaymentProcessor), але композиція допомагає створювати відносини "has-a". У нашій системі клас PaymentService "має" PaymentProcessor.

Це означає, що замість того, щоб розширювати кілька класів, PaymentService може утримувати екземпляр PaymentProcessor і делегувати відповідальність за обробку платежу відповідному класу оплати. Композиція дозволяє нам легко змінювати методи оплати без зміни структури самого сервісу.

Підсумок

Давайте подивимося, як все це вписується в нашу повну Java-рішення. Ми створимо клас для UserProfile, щоб зберігати дані користувача, клас PaymentProcessor, щоб визначити загальну логіку оплати, і спеціалізовані класи, такі як UpiPayments, DebitCardPayments, CreditCardPayments та PayPalPayments, для обробки конкретних методів оплати.

Нарешті, клас PaymentService з'єднує все це разом, використовуючи композицію для вибору та виконання правильного методу оплати залежно від вибору користувача.

1.

1. Клас профілю користувача (Інкапсуляція)

Цей клас зберігає інформацію про користувача, таку як ім'я, електронна пошта тощо, і надає доступ до цих даних через методи отримання та встановлення значень.

public class UserProfile {  
 private String name;  
 private String email;  
public UserProfile(String name, String email) {  
 this.name = name;  
 this.email = email;  
 }  
 public String getName() {  
 return name;  
 }  
 public String getEmail() {  
 return email;  
 }  
 public void setName(String name) {  
 this.name = name;  
 }  
 public void setEmail(String email) {  
 this.email = email;  
 }  
}

2. Клас процесора платежів (Абстракція)

Це буде абстрактний клас, який визначає загальні методи для різних методів оплати.

public abstract class PaymentProcessor {  
 protected UserProfile userProfile;  
 public PaymentProcessor(UserProfile userProfile) {  
 this.userProfile = userProfile;  
 }  
 public abstract void processPayment(double amount);  
}

3. Клас платежів через UPI (Наслідування та Поліморфізм)

Цей клас розширює PaymentProcessor і реалізує метод processPayment.

public class UpiPayments extends PaymentProcessor {  
 public UpiPayments(UserProfile userProfile) {  
 super(userProfile);  
 }  
@Override  
 public void processPayment(double amount) {  
 System.out.println("Processing UPI payment of " + amount + " for " + userProfile.getName());  
 }  
}

4. Клас платежів через дебетову картку (Наслідування та Поліморфізм)

Цей клас розширює PaymentProcessor і реалізує метод processPayment.

public class DebitCardPayments extends PaymentProcessor {  
 public DebitCardPayments(UserProfile userProfile) {  
 super(userProfile);  
 }  
@Override  
 public void processPayment(double amount) {  
 System.out.println("Processing Debit Card payment of " + amount + " for " + userProfile.getName());  
 }  
}

5. Клас платежів через кредитну картку (Наслідування та Поліморфізм)

Цей клас розширює PaymentProcessor і реалізує метод processPayment.

public class CreditCardPayments extends PaymentProcessor {  
 public CreditCardPayments(UserProfile userProfile) {  
 super(userProfile);  
 }  

@Override  
 public void processPayment(double amount) {  
 System.out.println("Processing Credit Card payment of " + amount + " for " + userProfile.getName());  
 }  
}

6. Клас платежів через PayPal (Наслідування та Поліморфізм)

Цей клас розширює PaymentProcessor і реалізує метод processPayment.

public class PayPalPayments extends PaymentProcessor {  
 public PayPalPayments(UserProfile userProfile) {  
 super(userProfile);  
 }  
@Override  
 public void processPayment(double amount) {  
 System.out.println("Processing PayPal payment of " + amount + " for " + userProfile.getName());  
 }  
}

7. Клас платіжного сервісу (Композиція)

Цей клас використовує композицію для керування різними методами оплати. Він дозволяє обробляти платежі через будь-який з класів оплати (UPI, дебетова картка тощо).

public class PaymentService {  
 private PaymentProcessor paymentProcessor;  

public void setPaymentProcessor(PaymentProcessor paymentProcessor) {  
 this.paymentProcessor = paymentProcessor;  
 }  
 public void processPayment(double amount) {  
 paymentProcessor.processPayment(amount);  
 }  
}

8.

Головний клас (для запуску всього)

Цей клас створить профіль користувача та класи для платіжних методів і оброблятиме платежі, використовуючи різні способи оплати.

public class Main {  
 public static void main(String[] args) {  

 UserProfile user = new UserProfile("John Doe", "[email protected]");  

 PaymentService paymentService = new PaymentService();  

 // Обробка платежу через UPI  
 PaymentProcessor upiPayment = new UpiPayments(user);  
 paymentService.setPaymentProcessor(upiPayment);  
 paymentService.processPayment(1000.50);  

 // Обробка платежу через дебетову картку  
 PaymentProcessor debitCardPayment = new DebitCardPayments(user);  
 paymentService.setPaymentProcessor(debitCardPayment);  
 paymentService.processPayment(2000.75);  

 // Обробка платежу через кредитну картку  
 PaymentProcessor creditCardPayment = new CreditCardPayments(user);  
 paymentService.setPaymentProcessor(creditCardPayment);  
 paymentService.processPayment(1500.30);  

 // Обробка платежу через PayPal  
 PaymentProcessor paypalPayment = new PayPalPayments(user);  
 paymentService.setPaymentProcessor(paypalPayment);  
 paymentService.processPayment(500.90);  
 }  
}

Ключові концепції, що використовуються:

  1. Наслідування: Класи, такі як UpiPayments, DebitCardPayments тощо, успадковують клас PaymentProcessor.
  2. Поліморфізм: Метод processPayment перевизначається в кожному класі платіжного методу.
  3. Абстракція: Клас PaymentProcessor визначає абстрактний метод processPayment, залишаючи реалізацію для підкласів.
  4. Інкапсуляція: Клас UserProfile інкапсулює дані користувача, з методами доступу та зміни значень.
  5. Композиція: Клас PaymentService використовує композицію для включення об'єкта PaymentProcessor для обробки різних методів оплати.

Ключові концепції об'єктно-орієнтованого програмування, що використовуються в коді:

  1. Інкапсуляція:
  • Клас UserProfile інкапсулює дані користувача, такі як name та email. Ці поля є приватними, а доступ до них здійснюється через публічні методи отримання та встановлення значень.
  1. Діаграма (Інкапсуляція):
+-----------------------+  
| UserProfile |  
+-----------------------+  
| - name: String | <-- Приватне поле  
| - email: String | <-- Приватне поле  
+-----------------------+  
| + getName(): String | <-- Публічний метод доступу  
| + getEmail(): String | <-- Публічний метод доступу  
| + setName(String) | <-- Публічний метод встановлення  
| + setEmail(String) | <-- Публічний метод встановлення  
+-----------------------+
  1. Наслідування:
  • Класи, такі як UpiPayments, DebitCardPayments, CreditCardPayments та PayPalPayments, успадковують абстрактний клас PaymentProcessor, що дозволяє їм ділити спільну поведінку та реалізовувати специфічну логіку оплати.
  1. Діаграма (Наслідування):
+-------------------+ +-------------------------+  
| PaymentProcessor |<-----| UpiPayments |  
+-------------------+ +-------------------------+  
| + processPayment() | | + processPayment() | <-- Перевизначений метод  
+-------------------+ +-------------------------+  
 ^  
 |  
+-------------------+ +-------------------------+  
| DebitCardPayments | | CreditCardPayments |  
+-------------------+ +-------------------------+
  1. Поліморфізм:
  • Метод processPayment є поліморфним, що означає, що він працює по-різному в залежності від методу оплати. Кожен підклас (наприклад, UpiPayments, DebitCardPayments тощо) надає свою реалізацію методу processPayment.
  1. Діаграма (Поліморфізм):
+-------------------+ +-------------------------+  
| PaymentProcessor |<-----| UpiPayments |  
+-------------------+ +-------------------------+  
| + processPayment() | | + processPayment() | <-- Різна реалізація  
+-------------------+ +-------------------------+  
 ^  
 |  
+-------------------+ +-------------------------+  
| DebitCardPayments | | CreditCardPayments |  
+-------------------+ +-------------------------+

## **Абстракція**:

- Клас `PaymentProcessor` абстрагує метод `processPayment`, дозволяючи підкласам визначати свою власну реалізацію. Сам метод оголошено, але не реалізовано в абстрактному класі.

1. **Діаграма (Абстракція)**:

+------------------------------+
| <> PaymentProcessor |
+------------------------------+
| - userProfile: UserProfile | <-- Композиція
+------------------------------+
| + processPayment(amount) | <-- Абстрактний метод
+------------------------------+
^
|
+-------------------+ +-------------------------+
| UpiPayments | | DebitCardPayments |
+-------------------+ +-------------------------+
| + processPayment()| | + processPayment() |
+-------------------+ +-------------------------+
```

Композиція:

  • Клас PaymentService демонструє композицію, утримуючи посилання на об'єкт PaymentProcessor. Це дозволяє класу PaymentService працювати з різними типами оплат (UPI, дебетова картка тощо) динамічно.
  1. Діаграма (Композиція):
+---------------------------+  
| PaymentService |  
+--------------------------------------+  
| - paymentProcessor: PaymentProcessor |  
+--------------------------------------+  
| + setPaymentProcessor() |  
| + processPayment() |  
+---------------------------+  
 |  
 v  
+---------------------------+  
| PaymentProcessor |  
+---------------------------+

Висновок

Комбінуючи Інкапсуляцію, Наслідування, Поліморфізм, Абстракцію та Композицію, ми створили модульну та гнучку платіжну систему, яку легко розширювати новими методами оплати в майбутньому. Ця структура забезпечує чітке розділення відповідальностей, роблячи код простішим для підтримки та масштабування.

Ви можете знайти та завантажити код тут.

.

.

.

Успішного кодування!

Перекладено з: Chapter[19]: Revisiting Object-Oriented Design: A Comprehensive Payment System in Java

Leave a Reply

Your email address will not be published. Required fields are marked *