Strategy tasarım desenini kullanarak if-else bloklarından kurtulmak

Bu yazımda Java Spring ile yazılım süreçlerini geliştirirken karşımıza çıkan sayıca fazla if else bloklarından Strategy tasarım deseni yardımıyla nasıl kurtuluruz konusunu ele alacağım.

Strategy design pattern, bir nesnenin farklı davranışlarını gerçekleştirmeyi sağlayan bir tasarım desenidir. Bu desen, bir nesnenin davranışını değiştirirken, kodun çok fazla değiştirilmesine gerek kalmamasını sağlar. Strategy deseni, bir sınıfın davranışını değiştirirken, o sınıfın çalışma şeklini değiştirmez. Bunun yerine, sınıfın davranışını değiştirmek için farklı “strateji” sınıfları kullanır. Bu sınıflar, sınıfın çalışma şeklini değiştirmez, ancak sınıfın nasıl davranacağını belirler.

Strategy deseni, bir nesnenin davranışını değiştirmeyi kolaylaştırır ve kodun değiştirilmesine gerek kalmaz. Bu, nesnenin davranışını değiştirmeyi kolaylaştırır ve kodun okunabilirliğini ve anlaşılırlığını arttırır. Bu desen, genellikle farklı algoritmaların bir arada kullanılması gereken senaryolarda kullanılır. Örneğin, bir nesne farklı sıralama algoritmalarını kullanarak verileri sıralayabilir ve kullanıcının seçtiği algoritmayı kullanarak verileri sıralayabilir. Strategy deseni sayesinde, nesnenin davranışı değiştirilebilir ve farklı algoritmalar kolayca kullanılabilir.

Konuyu anlamak adına ilk olarak strategy desenini kullanmadan bir örnek oluşturalım.

@RestController
public class MessageController {
    private MessageService messageService;

    @GetMapping("/messages")
    public void showMessage(@RequestParam String language) {
        messageService.showMessage(language);
    }
}

MessageService inden language parametresine göre mesajı gösteren yukardaki gibi bir rest api oluşturalım.

Daha sonra strategy deseni olmadan if else blokları ile oluşturulmuş servisimizi aşağıdaki gibi hazırlayalım.

public class MessageService {
    public void showMessage(String language) {
        if (language.equals("english")) {
            System.out.println("Hello, how are you?");
        } else if (language.equals("turkish")) {
            System.out.println("Merhaba, nasılsın?");
        } else {
            throw new IllegalArgumentException("Invalid language option: " + language);
        }
    }
}

Bu örnekte görüldüğü üzere yeni eklenecek her dil için if bloğuna yeni şartlar eklememiz gerekecek ve sayısı arttıkça kodumuzun okunabilirliği azalacaktır. Bu durumdan kurtulmak içinde kodumuzu refactor edip strategy desenimizi aşağıdaki gibi uygulayabiliriz.

Daha önceden oluşturduğumuz “MessageService” sınıfına bu sınıfın bir özelliği olan “MessageStrategy” interface ini oluşturup eklemek için hazırda tutalım. Bu özellik, mesajları göstermek için kullanılacak olan “MessageStrategy” sınıfını tutacak.

public interface MessageStrategy {
    String getMessage();
    String getLanguageName();
}

Sonra, farklı dil seçenekleri için farklı “MessageStrategy” sınıfları oluşturalım. Örneğin, “EnglishMessageStrategy” sınıfı İngilizce mesajları “TurkishMessageStrategy” sınıfı Türkçe mesajları döndürecektir.

@Service
public class EnglishMessageStrategy implements MessageStrategy {
    @Override
    public String getMessage() {
        return "Hello, how are you?";
    }
    @Override
    public String getLanguageName(){
        return "english";
    }

}
@Service
public class TurkishMessageStrategy implements MessageStrategy {
    @Override
    public String getMessage() {
        return "Merhaba, nasılsın?";
    }

   @Override
    public String getLanguageName(){
        return "turkish";
    }
}

“MessageService” sınıfını aşağıdaki gibi değiştirelim.

@Service
public class MessageService {
    private final Map<String, MessageStrategy> messageStrategyMap = new HashMap<>();

    public MessageService(List<MessageStrategy> messageStrategies) {
        messageStrategies.forEach(item->messageStrategyMap.put(item.getLanguageName(),item));
    }

    public void showMessage(String language) {
        MessageStrategy messageStrategy = messageStrategyMap.get(language);
        if (messageStrategy == null) {
            throw new IllegalArgumentException("Invalid language option: " + language);
        }
        System.out.println(messageStrategy.getMessage());
    }
}

Bundan sonra eklenecek her yeni bir dil için yeni bir dil strategy sınıfı eklenerek gerekli işlemler yapılmaya devam edilebilir.

Bir sonraki yazıda görüşmek üzere.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir