Strateji Tasarım Modeli

Dec 01 2022
değişenleri özetlemek
Diyelim ki müşterilerin bir ürün satın almak veya bir hizmet almak için ödeme yapmasına olanak tanıyan bir uygulamamız var. Uygulamanın birden fazla ödeme şekli var, müşteri nakit, visa kartı veya cüzdan kullanabilir, bunu şöyle yapabiliriz: Aslında hayır, Üç ödeme şeklimiz var ve her durumda farklı bir uygulama var, bu yüzden tek bir davranışımız var. Farklı yollarla “ödeme”, yani değişenleri alıp ayrı sınıflara koyarsak ve ortak davranış için ortak bir arayüz kullanırsak ne olabilir?

Diyelim ki müşterilerin bir ürün satın almak veya bir hizmet almak için ödeme yapmasına olanak tanıyan bir uygulamamız var.

Uygulamanın birden fazla ödeme şekli var, müşteri nakit, visa kartı veya cüzdan kullanabilir, bunu şu şekilde yapabiliriz:

public class Customer {

  public void pay(String paymentType) {
    if (StringUtils.isEmpty(paymentType)) {
      throw new RuntimeException("please add payment method");
    }
      // pay according to payment type
    if (paymentType.equalsIgnoreCase("cash")) {
      // pay in cash steps ( Algorithm )
    } else if (paymentType.equalsIgnoreCase("visa")) {
      // use the visa for payment steps ( Algorithm )
    } else if (paymentType.equalsIgnoreCase("wallet")) {
      // use the wallet for payment steps ( Algorithm )
    } else {
      throw new RuntimeException(paymentType + "payment type is not available");
    }
  }
}

public class Client {
    public static void main(String[] args) {
        Customer customer = new Customer();
        customer.pay("cash");
    }
}

Aslında hayır,

  1. Yeni bir ödeme yöntemi eklemek istiyorsanız, bu sınıfı değiştirmeniz gerekir ve bu, tasarımınızı herhangi bir yeni değişiklik için esnek hale getirmez, bu uygulama ile SOLID tasarım ilkelerinden birini ihlal etmiş oluruz: "yazılım varlıkları açık olmalıdır. " uzatma için ancak değişiklik için kapalı
  2. Ödeme türü müşteri tarafından seçildikten sonra sınıftaki mantığın çoğu kullanılmaz, bu nedenle müşteri nakit ödeme yapmak isterse vize ve cüzdanı işleyen kod kullanılmayacaktır.
  3. Bu tasarım biçiminde gördüğünüz gibi, NULL ödeme türü veya boş ödeme türü olarak mantıklı gelmese bile olası her ödeme türü girişini halletmeniz gerekir ve müşteriyi yalnızca geçerli ödeme türlerini seçmesi için kolayca kısıtlayabilirsiniz. , bir strateji modeli kullanarak.

Üç ödeme tipimiz var ve her durumda farklı bir uygulama var , bu nedenle farklı yollarla "ödeme" yapan bir davranışımız var, yani değişenleri alıp ayrı sınıflara koyarsak ve ortak davranış için ortak bir arayüz kullanırsak ne olabilir? .

Payment adında bir interface oluşturalım . Soyut bir yöntemi olacak ve her bir ödeme yönteminin, Ödeme arayüzünü uygulayan kendi somut sınıfı olacaktır. Müşteri , ödeme arayüzünü bir "kompozisyon kullan" değişkeni olarak alacak ve tür yöntemine müşterinin tercihine göre karar verilecektir.

public interface Payment {
    void pay();
}
public class CashPayment implements Payment {
    @Override
    public void pay() {
        // pay in cash steps ( Algorithm )
    }
}
public class VisaPayment implements Payment {
    @Override
    public void pay() {
        // use the visa for payment steps ( Algorithm )
    }
}
public class WalletPayment implements Payment {
    @Override
    public void pay() {
        // use the wallet for payment steps ( Algorithm )
    }
}

public class Customer {
    private Payment payment;

    public Customer(Payment payment) {
        this.payment = payment;
    }

    public void setPaymentType(Payment payment) {
        this.payment = payment;
    }

    public void pay() {
        payment.pay();
    }
}

public class Client {
    public static void main(String[] args) {
        Customer customer = new Customer(new VisaPayment());
        customer.pay();
        // you can change the payment type at runtime
        customer.setPaymentType(new CashPayment());
        customer.pay();
    }
}

Müşteri ödeme örneği için UML diyagramı

Tasarım ilkeleri

önceki tartışmadan dört tasarım ilkesi sonucuna varabiliriz:

  1. Uygulama için değil arayüz için tasarım
  2. Değişenleri kapsülleyin
  3. Yazılım varlıkları genişleme için açık, değişiklik için kapalı olmalıdır.
  4. Kalıtım yerine kompozisyon kullanın

Strateji modeli için kitap tanımı şöyledir: Bir algoritma ailesi tanımlayın, her birini içine alın ve birbirinin yerine kullanılabilir hale getirin. Strateji, algoritmanın onu kullanan müşterilerden bağımsız olarak değişmesine izin verir.

Örneğimizde, algoritma ailesi ödeme yöntemleriydi ve bunların her birini somut alt sınıfta kapsıyoruz ve çalışma zamanında bile herhangi bir ödeme türünü seçebilen müşteri tarafından değiştirilebilirler, algoritma Müşteri ve İstemciden ayrılmıştır. …. ve bu strateji modelidir .