- Software Architecture
Composition Pattern Nedir? React'te Esnek Component Mimarisi
React uygulamalarında Composition Pattern kullanımı, component tasarımı ve sürdürülebilir UI architecture yaklaşımı
Zeynep Baş6 dk okuma
Composition Pattern Nedir?
Component'leri birleştirerek esnek yapılar oluşturmak
Composition Pattern, büyük ve karmaşık yapılar oluşturmak yerine küçük ve bağımsız component'leri bir araya getirerek daha esnek ve yeniden kullanılabilir yapılar oluşturmayı amaçlayan bir tasarım yaklaşımıdır. React'te component composition, component'lerin birbirlerinden miras alması yerine birlikte kullanılmasına dayanır.
Component'leri birleştirme
Reusable components
Küçük ve bağımsız component'ler
Low coupling
Maintainability
Composition yaklaşımında bir component'in bütün davranışları kendi içerisinde tanımlanmak zorunda değildir. Component, kendisine verilen diğer component'leri veya içerikleri kullanarak farklı ihtiyaçlara göre şekillendirilebilir.
Esnek component yapısı
Sorumlulukların ayrıştırılması
Farklı içerik kombinasyonları
Kod tekrarını azaltma
Controlled abstraction
Composition Neden Önemlidir?
Büyüyen component'lerde karmaşıklığı kontrol etmek
Uygulamalar büyüdükçe component'ler farklı kullanım senaryolarını desteklemek zorunda kalabilir. Bu durum zaman içerisinde çok fazla prop, boolean değer ve koşullu render yapısının oluşmasına neden olabilir. Composition bu karmaşıklığın component parçalarına ayrılmasına yardımcı olabilir.
Props karmaşasını azaltır
Boolean prop sayısını azaltabilir
Component sorumluluklarını ayırır
Farklı kullanım senaryolarını destekler
Composition kullanılmadığında tek bir component zaman içerisinde çok fazla sorumluluk üstlenebilir. Component hem veriyi yönetir, hem görünümü kontrol eder hem de farklı kullanım senaryolarını çok sayıda prop üzerinden yönetmeye başlayabilir.
Büyük component'ler
Props explosion
Koşullu render karmaşası
Artan bakım maliyeti
Düşük okunabilirlik
React'te Children Kullanımı
Component içeriğini consumer'a bırakmak
React'te Composition Pattern'in en temel kullanım şekillerinden biri children prop'udur. Parent component, içerisinde hangi içeriğin gösterileceğini tamamen kendisi belirlemek yerine bu içeriği dışarıdan alabilir.
children prop
Parent component
Consumer component
Esnek içerik
Reusable UI
Örneğin genel amaçlı bir Card component'i yalnızca belirli bir başlığı veya açıklamayı göstermek zorunda değildir. Card içerisine farklı component'ler gönderilerek aynı yapı farklı ekranlarda farklı amaçlarla kullanılabilir.
Card component
Dinamik içerik
Farklı kullanım senaryoları
Component composition
Kod tekrarını azaltma
Compound Components
Birlikte çalışan component ailesi oluşturmak
Compound Components, Composition Pattern'in React'teki güçlü kullanım alanlarından biridir. Bir parent component ortak davranışı yönetirken alt component'ler kendi sorumluluklarını üstlenir ve birlikte tek bir component API'si gibi çalışır.
Compound Components
Parent component
Child components
Ortak state
Component API
Tabs, Modal, Dropdown ve Accordion gibi UI yapılarında bu yaklaşım oldukça kullanışlıdır. Örneğin Tabs component'i aktif tab bilgisini yönetirken Tabs.List, Tabs.Tab ve Tabs.Panel gibi alt component'ler kendi görevlerini yerine getirebilir.
Tabs
Modal
Dropdown
Accordion
Menu
Props Karmaşası ve Composition
Çok sayıda prop yerine component'leri birleştirmek
Bir component farklı kullanım senaryolarını desteklemeye başladığında boolean prop'ların ve seçeneklerin sayısı hızla artabilir. Örneğin showHeader, showFooter, showImage veya showActions gibi prop'lar zamanla component API'sini karmaşık hale getirebilir.
Boolean prop
Props explosion
Conditional rendering
Karmaşık component API
Bakım maliyeti
Composition yaklaşımında bu davranışları tek bir component'in içerisinde kontrol etmek yerine bağımsız component'ler halinde birleştirmek mümkündür. Böylece consumer yalnızca ihtiyaç duyduğu parçaları kullanabilir.
Bağımsız component'ler
İhtiyaca göre composition
Daha sade API
Esnek kullanım
Daha az koşullu yapı
Card Örneği
Composition ile esnek bir UI component'i oluşturmak
Basit bir Card component'i başlangıçta title ve description gibi birkaç prop ile yönetilebilir. Ancak component farklı sayfalarda kullanılmaya başladığında image, badge, actions, footer veya farklı içerik türleri için yeni prop'lar eklenebilir.
title
description
image
badge
actions
Composition yaklaşımıyla Card'ın parçaları birbirinden ayrılabilir. Böylece ihtiyaç duyulan yapı consumer tarafından oluşturulur ve Card component'i hangi içeriğin kullanılacağını önceden bilmek zorunda kalmaz.
Card.Header
Card.Content
Card.Footer
Card.Image
Card.Actions
Inheritance ve Composition
Kalıtım yerine birleştirme yaklaşımı
Composition ve inheritance farklı component tasarım yaklaşımlarıdır. Inheritance bir yapının başka bir yapıdan özellik veya davranış almasına dayanırken composition mevcut parçaların bir araya getirilmesine dayanır.
Inheritance
Composition
Reusable behavior
Component relationships
Abstraction
React component mimarisinde composition çoğu durumda daha esnek bir yapı sağlayabilir. Çünkü component'ler arasında katı bir kalıtım ilişkisi oluşturmak yerine ihtiyaç duyulan parçalar farklı kombinasyonlarla bir araya getirilebilir.
Esnek component mimarisi
Farklı kombinasyonlar
Daha az coupling
Reusable components
Kolay değiştirilebilir yapı
Composition Ne Zaman Kullanılmalı?
Pattern'in gerçekten değer ürettiği durumları belirlemek
Composition özellikle bir component'in farklı ekranlarda farklı içeriklerle kullanılacağı durumlarda oldukça faydalıdır. Component'in bazı bölümleri değişiyor ancak ana yapı korunuyorsa composition iyi bir abstraction sağlayabilir.
Farklı kullanım senaryoları
Değişebilir component parçaları
Reusable UI
Farklı içerik kombinasyonları
Component API
Props sayısı sürekli artıyorsa, boolean prop'lar çoğalıyorsa veya component içerisinde çok fazla koşullu render bulunuyorsa composition değerlendirilmelidir.
Artan props sayısı
Boolean prop karmaşası
Conditional rendering
Büyük component
Tekrarlayan UI yapıları
Composition Ne Zaman Kullanılmamalı?
Her component'i parçalamak doğru değildir
Composition Pattern her durumda kullanılmamalıdır. Çok basit bir component için yalnızca pattern kullanmak amacıyla birçok alt component oluşturmak gereksiz abstraction ve complexity oluşturabilir.
Gereksiz abstraction
Component complexity
Fazla dosya
Okunabilirlik kaybı
Overengineering
Eğer bir component yalnızca birkaç basit prop ile anlaşılır ve sürdürülebilir şekilde kullanılabiliyorsa composition yapısına geçmek yerine mevcut basit yapıyı korumak daha doğru olabilir.
Basit component
Az sayıda prop
Düşük domain complexity
YAGNI
Basitliği koruma
Gerçek Bir React Senaryosu
Ürün kartı üzerinden Composition yaklaşımı
Bir e-ticaret uygulamasında ProductCard başlangıçta ürün adı, fiyatı ve görselini gösterebilir. Uygulama büyüdükçe aynı kartın admin panelinde, ürün listesinde ve kampanya sayfasında farklı içerikler göstermesi gerekebilir.
ProductCard
Ürün listesi
Admin panel
Kampanya sayfası
Farklı UI ihtiyaçları
Her senaryo için yeni prop eklemek yerine ProductCard içerisindeki bölümler composition ile ayrılabilir. Böylece her ekran ihtiyacına göre Image, Info, Discount veya Actions gibi parçalar bir araya getirilebilir.
ProductCard.Image
ProductCard.Info
ProductCard.Discount
ProductCard.Actions
Farklı component kombinasyonları
Composition ve Design System
Reusable UI component'lerinde composition kullanımı
Design System içerisinde tekrar kullanılabilir component'ler oluşturulurken Composition Pattern güçlü bir yaklaşım sunabilir. Component'lerin tek bir kullanım senaryosuna bağımlı olması yerine farklı ekranlarda birleştirilebilir olması UI sisteminin esnekliğini artırabilir.
Design System
Reusable components
Component API
UI consistency
Scalability
Özellikle Button, Modal, Dropdown, Table, Form ve Card gibi component'lerde composition yaklaşımı farklı kullanım ihtiyaçlarını desteklerken ortak tasarım dilinin korunmasına yardımcı olabilir.
Button
Modal
Dropdown
Table
Form
Senior Developer Bakış Açısı
Component'i küçültmek değil, değişimi doğru yerlere ayırmak
Senior seviyede Composition Pattern kullanmanın amacı her component'i mümkün olduğunca küçük parçalara bölmek değildir. Asıl amaç, değişmesi beklenen sorumlulukları birbirinden ayırarak component'lerin farklı senaryolarda yeniden kullanılabilmesini sağlamaktır.
Separation of concerns
Reusability
Low coupling
High cohesion
Controlled abstraction
Composition kullanırken component API'sinin anlaşılır olması, component'lerin sorumluluklarının net olması ve abstraction seviyesinin gereğinden fazla yükselmemesi gerekir. İyi bir composition yapısı kodu daha karmaşık değil, daha yönetilebilir hale getirmelidir.
Readable API
Single responsibility
Maintainability
Cognitive load
Abstraction seviyesini kontrol etme
Composition Pattern Kullanırken Sorulması Gereken Sorular
Pattern uygulamadan önce problemi doğru tanımla
Composition kullanmadan önce component'in gerçekten farklı içerik kombinasyonlarına ihtiyaç duyup duymadığı değerlendirilmelidir. Pattern yalnızca modern veya profesyonel göründüğü için uygulanmamalıdır.
Component farklı yerlerde kullanılacak mı?
İçerik yapısı değişiyor mu?
Props sayısı artıyor mu?
Boolean prop'lar çoğalıyor mu?
Component sorumluluğu büyüyor mu?
Ayrıca composition yapısının getireceği abstraction maliyeti de değerlendirilmelidir. Eğer composition mevcut component'i daha karmaşık hale getiriyor ancak anlamlı bir esneklik sağlamıyorsa basit çözümü korumak daha doğru olabilir.
Complexity
Cognitive load
Maintenance cost
Team understanding
Future changes
Sonuç
Composition ile esnek ve sürdürülebilir component mimarisi
Composition Pattern, React uygulamalarında component'leri daha esnek, yeniden kullanılabilir ve sürdürülebilir hale getirmek için kullanılan güçlü bir yaklaşımdır. Özellikle büyüyen component'lerde props karmaşasını azaltmak ve farklı kullanım senaryolarını desteklemek için faydalı olabilir.
Reusable components
Flexible architecture
Low coupling
Maintainability
Scalability
Ancak Composition Pattern de diğer Design Pattern'ler gibi bir amaç değil, araçtır. Her component'i parçalamak veya her projede Compound Components kullanmak doğru değildir. Önemli olan mevcut problemi anlamak ve ihtiyaç duyulan abstraction seviyesini belirlemektir.
Pattern bir araçtır
Problem önce gelir
Basitlik değerlidir
Overengineering'den kaçınılmalıdır
Doğru abstraction seçilmelidir
Kısacası iyi bir Composition yaklaşımı, component'i yalnızca küçültmez; değişmesi beklenen parçaları birbirinden ayırır ve aynı yapının farklı senaryolarda yeniden kullanılmasını sağlar. Senior yaklaşım ise 'Composition kullanmalı mıyım?' sorusundan önce 'Bu component'teki gerçek değişim ve tekrar problemi ne?' sorusunu sormaktır.
Önce problemi tanımla
Değişebilir parçaları belirle
Gerekirse composition uygula
Abstraction seviyesini kontrol et
Gerekmiyorsa basit bırak