capodecina
capodecina bu verdiğiniz örnek üzerine arada ki ProductService ihtiyaç var mı?
Bir uygulama temel olarak ikiye ayrılır; iş (business) ve uygulama (application). Burada servis, iş katmanına ait işlemleri gerçekleştirmeniz için; repository ise sizin uygulama katmanında veritabanı üzerinde ve/veya modelin üstüne inşa edilmiş bir yapı. Repository ürün oluşturmaz, çünkü o katmana girdiğinizde artık ürün diye bir şey yoktur, o katmanda o yapı bir girdidir (entry). Ona, işinize uygun anlamı yüklediğiniz yer servistir. Elbette uygulama katmanında da servisler olur ama genellikle Manager, Finder vs gibi isimlendirilir.
capodecina Repositoryi doğrudan controller da kullanmamızda ki sakınca nedir.
Bir sakınca yok ama portatif kod yazmamış olursunuz. ProductServis'i her yerde kullanabilirsiniz, gördüğünüz gibi kesin bir bağlılığı yok. Ürünü bir controller ile gelen bir istek de oluşturabilir, kuyruktaki bir Job da oluşturabilir, konsolda çalışan bir Command da oluşturabilir. Bu durumda ya ortak kullanmanız gereken bir servis olacak ya da Action Pattern kullanıp yapılan işleri tek bir iş yapan ama her yerde çağırabileceğiniz küçük sınıflara böleceksiniz, CreateProduct::handle($data, $user)
gibi ama burada da Poltergeist (ya da Gipsy Wagon) dediğimiz anti-pattern'ın oluşma durumu olabilir. Nested ve/veya gereksiz obje kullanımından kaçınmanız gerekecek.
capodecina Ayrıca ProductService şuan repository üzerinde işlemler yapabilmeyi sağlıyor. DB üzerinden çekilen dataları manüpüle
edebilir belirli bir duruma bağlı olarak, peki bir API isteği gerçekleştirmem gereken durumlarda veya uygulamamın business logiclerinin işletilmesini yine bu ProductService de mi gerçekleştirmeliyim?
Servis bu iş için iyi bir yer. Burada şöyle bir durum daha var, genellike direkt servis değil onu gerçeklediği interface enjekte edilir, örneğin ProductServiceInterface. Böylece Laravel'in service container özelliğe ile Inversion of Control ilkesi sağlanmış olur ve tek bir noktadan altını (gerçek sınıfı) değiştirebileceğiniz bir yapı elde edersiniz. Şu konuda bir şeyler anlatmışım: https://laravel.gen.tr/d/5835-crud-islemleri
capodecina Product Insert işleminde; API üzerinden bir yere istek attığım, dönen sonuca göre Repositoryden belirli id li ürünleri çektiğim sonrasında da bunlarla kendi uygulama logiclerimi işlettiğim durumda ProductService God Class diye tabir edilen bir yapıya dönmeyecek midir?
Servisleri daha küçük servislere bölerek servisler üzerindeki yükü azaltabilirsiniz, sürekli kullanılmayan yerleri direkt repository'den çıkıp gerekirse ileride servise alabilirsiniz ama servisler arası veri aktarımında kullandığınız yapı Poltergeist oluşmasına da sebep olabilir dikkatli olmanız lazım.
capodecina Özetle bir Service sınıfının kapsamı tam olarak ne olmalı nerede duracak bu Service sınıfının gelişmesi gibi sorularım var.
Sınıfın kapsamı bağlamıdır. ProductService isimli bir sınıfınız varsa bu sınıfın demek ki bağlamı üründür ve ürün ile ilgili temel görevleri yapacak demektir. Eğer bağlamın dışına çıkarsa God olur; bağlamın temel tüm gereksinimlerini sağlamazsa yetersiz olur, çok fazla sınıfla objeler kullanarak haberleşirse Poltergeist oluşur. Her 10 işlemde 1 kere kullanılan bir işi o servise koymazsınız; her ürün oluşturmanızda gerekli olan bir işi servise alırsınız vs...
Eğer her şeyi iki parağrafta anlatabilseydik felsefeye gerek olmazdı. Bu soruların kesin kabul görmüş cevapları yok, herkes farklı görüşte ve kod yazılırken savunulan yapının bile dışına çıkılan zamanlar olur. Her uygulamanın kaosa dönüştüğü yerleri olur, mükemmel bir uygulama ütopiktir, o yüzden versiyonlama diye bir kavram vardır. Benim tavsiyem Ockham'ın usturası prensibinden hareket ederek basitliğin peşinden koşmanız ki bazen basit olan anti-pattern de olabilir; sadece çok belirgin yanlışlardan uzak durun.