1. Önsöz

Bu yazıda, hexagonal architecture, diğer adıyla ports and adaptors hakkında bilgiler öğrenip javada uygulayacağız.

2. Hexagonal Architecture Nedir

Hexagonal Architecture uygulamanın temel işlevini onu çağıran servislerden ayrıştıran çok katmanlı bir yapıdır. Hexagonal yani altıgen denilmesinin mantıksal hiçbir anlamı yoktur, iç içe katmanlar olarak gözüktüğü için tercih edilmiştir.

Hexagonal Architecture, 3 katmandan oluşur

  • Framework Layer
  • Application Layer
  • Domain Layer

 

Bu katmanları daha detaylı incelemeden önce, katmanların kendi aralarında ports and adapters ile iletişim kurduğunu bilmelisiniz. Basitçe, portlar istek ile geleceklerin kullandığı interfaceler, adaptörler ise bu interface’leri implement eden sınıflardır.

2.1. Framework Layer

Framework layer, 3. parti uygulamalardan (hexagonun dışında kalan herşeyi 3. parti olarak görüyoruz) gelen istekleri karşılayan ve onlara cevap veren katmandır.

2.2. Application Layer

Körpü katmanı olarak görülen Application Layer, Framework Layer’dan gelen istekleri karşılamakla görevlidir. Gelen isteğin gereğine göre kendi cevaplar, gerekirse Domain Layer’a iletir.

Bir diğer sorumluluğu ise, uygulamanın esas işi dışında kalan işlemleri üstlenmektir. Örneğin bir e-ticaret sitesinin checkout işlemi domaini ise, notification işlemi Application Layer’ındır.

2.3. Domain Layer

Son olarak, Domain Layer uygulamanın temel katmanıdır. Uygulamanın yapması gereken esas işi yapar. Aynı zamanda Application Layer ile iletişim sağlar.

3. Hexagonal Mimari Nasıl Kullanılır

Baeldung’un spring crud eğitimindeki spring-boot-crud branchinde bulunan UserControlller class’ını ele alalım. updateUser methodu post isteklerini alıyor:

 

public String updateUser(@PathVariable("id") long id, @Valid User user, BindingResult result, Model model) {
    if(result.hasErrors()) {
        user.setId(id);
        return "update-user";
    }
        
    userRepository.save(user);
    model.addAttribute("users", userRepository.findAll());
    return "index";
}

Bu method üzerine hexagonal architecture uygulamayı deneyelim.

3.1. Portlar

First of all, let’s create our ports upon return values.
Herşeyden önce, view değerlerine uygun portları ayarlayalım.

public interface UserUpdatePort {
    void returnIndexPage();
    void showErrors();
}

3.2. Adaptörler

Şimdi, yarattığımız portları kullanan adaptörleri yazalım.

public class UserUpdatePortAdapter implements UserUpdatePort {
    private String pageName;

    @Override
    public void returnIndexPage() {
        pageName = "update-user";
    }

    @Override
    public void showErrors() {
        pageName = "index";
    }

    public String getPageName() {
        return pageName;
    }
}

Ve son olarak, yazdığımız bu controller değerlerini kabul edip geri dönen bir servis yazmamız gerekiyor.

3.3. Apply To Service

public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void updateUser(Long id, User user, BindingResult result, UserUpdatePort userUpdatePort, Model model) {
        if(result.hasErrors()) {
            user.setId(id);
            userUpdatePort.showErrors();
        }

        userRepository.save(user);
        model.addAttribute("users", userRepository.findAll());
        userUpdatePort.returnIndexPage();
    }
}

3.4. Controller’ı Güncelleyelim

Son olarak, controller’ımızı değiştirip hexagonal architecture‘a uygun bir hale getiriyoruz.

@PostMapping("/update/{id}")
public String updateUser(@PathVariable("id") long id, @Valid User user, BindingResult result, Model model) {
    UserUpdatePortAdapter userUpdatePortAdapter = new UserUpdatePortAdapter();
    userService.updateUser(id, user, result, userUpdatePortAdapter, model);
    return userUpdatePortAdapter.getPageName();
}

Ports and adapters tekniğini controller methoduna uygulayarak, servis sınıfımızı hegzagonal mimariye uygun tasarlamış olduk. Artık, controller hiçbir servis aksiyonu hakkında bilgili değil ve bunun yanında, hiçbir if-else yapısına sahip değil.

4. Sonuc

Bu alıştırmada, hexagonal architecture‘ın javada nasıl uygulanacağını kısaca görmüş olduk.

Bu yazı farklı sebeplerle ingilizce yazılmış olup, Türkçe kaynak bulunması açısından türkçeleştirilmiştir.

Yazı içerisinde kullanılan bütün kod örneklerini baeldung’un github hesabında bulabilirsiniz.

Categories: JavaSpring

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.