8 Mart 2021 Pazartesi

Package By Feature

Giriş
Package By Feature kullanım her zaman Package By Layer'a tercih edilmeli.

Package By Layer Neden Zor
Kod katmanlara ayrılsa bile aralarındaki ilişkiyi anlamak gerçekten zor olabiliyor. Bir örnek şöyle. Burada problem katmanlar arasında kodun takip edilememesi.
“ If you try to organize a car on multiple layers, then you have to define at least : a mechanical layer, an electrical layer and a hydraulic layer. The day you have a problem with, let’s say the steering wheel, you are in big trouble, because in order to fix the problem, you need to go and find in each layer the component used by that feature. What you need to do instead, is to organize the car around features (steering, shift, air conditioning ..).”
domain
Bir başka açıklama şöyle
This approach has two main disadvantages:
- From a visibility point-of-view, to use classes outside their package, you need to mark them as public. FirstController uses FirstService, hence the latter must be public. Because of this, any other class can use it, whereas I want it to be used only for "First"-related classes.
- If you want to split the application, you’ll first need to analyze the dependencies to understand the coupling between packages.
Örnek
Elimizde şöyle "Package by layer" kod olsun
ch.frankel
  ├─ controller
  │  ├─ FirstController
  │  └─ SecondController
  ├─ service
  │  ├─ FirstService
  │  └─ SecondService
  └─ dao
     ├─ FirstDao
     └─ SecondDao
Bu kodu Package by feature ile şu hale getiririz
ch.frankel
  ├─ first
  │  ├─ FirstController
  │  ├─ FirstService
  │  └─ FirstDao
  └─  second
     ├─ SecondController
     ├─ SecondService
     └─ SecondDao
Package by Feature ve DCI Architecture anlaşılabilirlik açısından daha iyi özellikler sunuyor. Açıklaması şöyle.
The first system I worked on had layers separated into Maven modules (model, business-logic, webapp). It worked well at first – the structure was simple and easy to explain. The app was successful and as the codebase grew, it became obvious that this approach did not scale.

Back then I read about package-by-feature instead of package-by-layer approach, it made sense, and so we started moving in that direction. First, we’d simply move all classes related to a given feature into its own package, without changing them. This opened the door for further improvements and simplifications (like leveraging package-private visibility, removing some unnecessary mapping between layers, etc.), but I no longer recall which of those materialized while I was with the company.

One thing was clear – dropping packaging by layer undoubtedly improved the system.
Feature'ları Kendi İçinde Bölümlemek
Package By Feature kullanılsa bile paketleri kendi içinde bölümlemek gerekiyor. 

Ortak kullanılabilecek bazı paketler şöyle
config
domain
infrastructure
interfaces
Her bir feature altında da alt feature konuları olabilir.  Örneğin bir cihazı modellecek olayım. Cihazın
- signal detection
- position finder
- target finder
- effect calculator
- dispenser
- foo determiner
- bar receiver
- countermeasure manager

gibi alt özellikleri olsun. Bu karışık bir cihaz. Her bir alt feature da düzgünce paketlenmezse kod çok karışık olacak. 

Alt feature için benim düşündüğüm bir örnek şöyle
processors : Gelen mesajları işler
timers : Timer kullanılıyorsa buradadır
model : Domain nesnelerini saklar
requests : Domain'e gelen istekler
responses : Domain tarafından verilen cevaplar
Örnek
Açıklaması şöyle
In package-by-feature, the package names correspond to important, high-level aspects of the problem domain. For example, a drug prescription application might have these packages:

- com.app.doctor
- com.app.drug
- com.app.patient
- com.app.presription
- com.app.report
- com.app.security
- com.app.webmaster
- com.app.util
- and so on...

Each package usually contains only the items related to that particular feature, and no other feature. For example, the com.app.doctor package might contain these items:
- DoctorAction.java - an action or controller object
- Doctor.java - a Model Object
- DoctorDAO.java - Data Access Object
- database items (SQL statements)
- user interface items (perhaps a JSP, in the case of a web app)
Package-by-layer olarak düşünseydik elimizde şöyle bir yapı olurdu
- config
- controller
- domain
- repository
- service

Hiç yorum yok:

Yorum Gönder