Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Kaya Gibi Sağlam Yazılım Projelerine İmza Atmanın 5 Prensibi

515 views

Published on

başarısız tasarımın emareleri ve bağımlılık yönetimi konularını içeren sunum. Temmuz 2015 @ PHPKonf

Published in: Technology
  • Be the first to comment

Kaya Gibi Sağlam Yazılım Projelerine İmza Atmanın 5 Prensibi

  1. 1. Kaya Gibi Sağlam Yazılım Projelerine İmza Atmanın 5 Prensibi İbrahim Gündüz Temmuz 2015 @ PHPKonf
  2. 2. İbrahim GündüzYazılım Geliştirici http://tr.linkedin.com/in/ibrahimgunduz https://github.com/ibrahimgunduz34 https://twitter.com/ibrahimgunduz34 ibrahimgunduz34@gmail.com http://www.ibrahimgunduz.net/
  3. 3. "... the design of a software project is documented primarily by its source code." Robert C. Martin
  4. 4. “Biz döküman yazmıyoruz, iş yapıyoruz”
  5. 5. KÖTÜ TASARIM ÇÜRÜR!!!
  6. 6. ÇÜRÜYEN TASARIM KOKAR!!!
  7. 7. Esnemezlik (Rigidity)
  8. 8. Esnemezlik (Rigidity) ● Kaynak kodunda değişikliğe karşı artan zorlaşma eğilimi ● Tek bir değişikliğin bile başka pek çok modülde değişikliğe neden olması ● Geliştirme süresinin gitgide artması
  9. 9. Kırılganlık (Fragility)
  10. 10. Kırılganlık (Fragility) ● En küçük değişiklikle bile uygulamada pek çok noktada kırılabilme eğiliminin artması ● Yapılan değişiklikle doğrudan ilgisi olmayan farklı noktada meydana gelen kırılmalar ● Yapılan her hata giderme işlemi ile birlikte olası beklenmedik hataların oluşması ihtimalinin artması
  11. 11. Taşınamamazlık (Immobility)
  12. 12. Taşınamamazlık (Immobility) ● Modüller arası yüksek bağımlılık ● Taşınamayan, mevcut veya başka bir proje tarafından kullanılamayan kod blokları ● Gereksiz kod tekrarları
  13. 13. Akışkanlık Direnci (Viscosity)
  14. 14. Akışkanlık Direnci (Viscosity) ● Tasarımı koruma yoluna gitmek, gelişi güzel iş yapmaktan daha zor hale geldiğinde akışkanlık direnci yüksektir. ● Geliştirme ortamının yavaş yada elverişsiz olması geliştiricilerin gelişi güzel iş yapma eğilimini arttırır.
  15. 15. Gereksiz Tekrar (Needless Repetition)
  16. 16. Gereksiz Tekrar (Needles Repetition) ● Tasarımın, tek soyutlamanın içinde tekrarlanan yapılar içermesi ● Geliştiricinin kopyala/yapıştır kavramını su istimal etmesi ● Tekrarlanan kodla anlaşılmaz ve bakımı zor hale gelen sistem
  17. 17. Gereksiz Karmaşa (Needless Complexity)
  18. 18. Gereksiz Karmaşa (Needles Complexity) ● Proje, anlaşılması güç ve hiçbir zaman kullanılmayan yapılarla doludur. ● Kullanışsız kod blokları karmaşa hissi uyandırır.
  19. 19. “Any fool can write code that a computer can understand. Good programmers can write code that humans can understand.” Martin Fowler
  20. 20. S.O.L.I.D. Prensipleri
  21. 21. SOLID Prensipleri Nedir ? Robert Martin sunumu ile ortaya çıkan bağımlılık yönetimi biçiminin baş harfleridir. Ne Sağlar ? ● Gevşek bağlara sahip ● Yeniden Kullanılabilir ● Kolaylıkla test edilebilir ● Gerektiğinde rahatlıkla bakım yapılabilir ● Yüksek uyumluğa sahip
  22. 22. “S” Single Responsibility Tekil Sorumluluk
  23. 23. Single Responsbility Her sınıfın ve metodun tek bir sorumluluğu olmalı.
  24. 24. class UserManager { public function register($email, $fullname, $password) { //validasyon if( !$email || !$this->isEmail($email)) {, throw new ValidationError('Email must be valid email address.'); } if(!$fullname || len($fullname) < 20 || len(split(' ', $email)) < 2) { throw new ValidationError('Fullname must be valid name.'); } if(len($password) < 6 || len($password) > 30) { throw new ValidationError('Password length must be greater than six character and less than thirty character.'); } //veritabaninda kullanici kaydi olusturuluyor try { $user = new User(); $user->setName($fullname); $user->setEmail($email); $user->generatePassword($password); $user->persist(); $user->flush(); $mailer = new Mailer(); $mailer->send($user->getEmail(), 'Registration is completed successfuly.', 'bla..bla...' ); } catch(DatabaseError $error) { Logger::exception($error); throw new SystemError('User registration is failed.'); } } }
  25. 25. class UserManager { private function createUser($email, $fullname, password) { $user = new User(); $user->setName($fullname); $user->setEmail($email); $user->generatePassword($password); $user->persist(); $user->flush(); return $user; } public function register($email, $fullname, $password) { //validasyon $validator = new UserRegistrationValidator($email, $fullname, $password); $validator->validate(); //veritabaninda kullanici kaydi olusturuluyor try { $user = $this->createUser($email, $fullname, $password); $eventDispatcher->dispatch('user.registred', new UserRegisterEvent($user)); return true; } catch(DatabaseError $exc) { Logger::exception($exc); throw new SystemError('User registration is failed.'); } } }
  26. 26. “O” Open-Closed Açık / Kapalı
  27. 27. Open - Closed Kaynak kodu genişlemeye açık, değişime kapalı olmalıdır.
  28. 28. class SaleRules { public function calculateDiscount($customerGroup, $totalAmount) { if($customerGroup == CustomerGroup::STANDARD) { $discount = $totalAmount * 0.95 + 3 / 2 } elseif ($customerGroup == CustomerGroup::SILVER) { $discount = ... } elseif($customerGroup == CustomerGroup::PLATIN) { $discount = ... } elseif($customerGroup == CustomerGroup::GOLD) { $discount = ... } return $discount } }
  29. 29. interface CustomerGroupRuleInterface { public function calculateDiscount($totalAmount); } class StandardGroupRule implements CustomerGroupRuleInterface { public function calculateDiscount($totalAmount) { return $totalAmount * 0.95 + 3 / 2 } } class SilverGroupRule implements CustomerGroupRuleInterface { public function calculateDiscount($totalAmount) { return $totalAmount * 0.95 + 3 / 2 } } class SaleRules { public function calculateDiscount($rule, $totalAmount) { return $rule->calculateDiscount($totalAmount); } }
  30. 30. “L” Liskov Substitution Liskov’un Yerine Geçme
  31. 31. Liskov Substitution Alt sınıflardan oluşturulan nesneler, üst sınıflardan oluşturulan nesnelerle yer değiştirdiklerinde aynı davranışı sergilemek zorundadırlar.
  32. 32. class Employee { protected $baseSalary = 2000; public function getSalary() { throw new EmployeException('This employee salary is not defined yet.'); } } class Engineer extends Employee { public function getSalary() { return $this->baseSalary * 3 } } class Manager extends Employee { public function getSalary() { return $this->baseSalary * 5; } } class Intern extends Employee {}
  33. 33. class SalaryCalculator { public function getTotalSalary() { $total = 0; foreach(getEmployeers() as $employee) { if($employee instanceof Intern) { $total += 0; } else { $total += $employee->getSalary(); } } return $total; } }
  34. 34. class SalaryCalculator { public function getTotalSalary() { $total = 0; foreach(getEmployeers() as $employee) { $total += $employee->getSalary(); } return $total; } }
  35. 35. “I” Interface Segregation Arayüz Ayırma
  36. 36. Interface Segregation Birbiriyle ilişkili olmayan pek çok metodu ihtiva eden arayüzler yerine birbiriyle ilişkili metodlardan oluşan çok sayıda arayüz kullanılmalı.
  37. 37. interface PosInterface { public function preAuthorization(PreAuthorizationRequest $request); public function postAuthorization(PostAuthorizationRequest $request); public function sale(SaleRequest $request); public function refund(RefundRequest $request); public function cancel(CancelRequest $request); public function processProviderResponse(ProviderResponse $providerResponse); public function finalize(Finalize3dRequest $request); } class SynchPayA implements PosInterface { /... } class SynchPayB implements PosInterface { /... }
  38. 38. interface PosInterface { public function sale(SaleRequest $request); public function refund(RefundRequest $request); public function cancel(CancelRequest $request); } interface ThreeDSecureAware { public function processProviderResponse(ProviderResponse $providerResponse); public function finalize(Finalize3dRequest $request); } interface PreAuthorizationWare { public function preAuthorization(PreAuthorizationRequest $request); public function postAuthorization(PostAuthorizationRequest $request); } class SynchPayA implements PosInterface, PreAuthorizationWare { /... } class SynchPayB implements PosInterface, PreAuthorizationWare, ThreeDSecureAware { /... }
  39. 39. “D” Dependency Inversion Bağımlılıkların Tersine Çevirilmesi
  40. 40. Dependency Inversion Somut sınıflarla olan bağımlılıklar arayüzler ve soyut sınıflar kullanılarak kaldırılmalı.
  41. 41. interface CustomerGroupRuleInterface { public function calculateDiscount($totalAmount); } class StandardGroupRule implements CustomerGroupRuleInterface { public function calculateDiscount($totalAmount) { return $totalAmount * 0.95 + 3 / 2 } } class SilverGroupRule implements CustomerGroupRuleInterface { public function calculateDiscount($totalAmount) { return $totalAmount * 0.95 + 3 / 2 } } class SaleRules { public function calculateDiscount($rule, $totalAmount) { if($rule instanceof StandardGroupRule) { /... $discount $rule->calculateDiscount } elseif($rule instanceof SilverGroupRule) { /... $discount $rule->calculateDiscount } return $discount } }
  42. 42. interface CustomerGroupRuleInterface { public function calculateDiscount($totalAmount); } class StandardGroupRule implements CustomerGroupRuleInterface { public function calculateDiscount($totalAmount) { return $totalAmount * 0.95 + 3 / 2 } } class SilverGroupRule implements CustomerGroupRuleInterface { public function calculateDiscount($totalAmount) { return $totalAmount * 0.95 + 3 / 2 } } class SaleRules { public function calculateDiscount(CustomerGroupRuleInterface $rule, $totalAmount) { return $rule->calculateDiscount($totalAmount); } }
  43. 43. http://tr.linkedin.com/in/ibrahimgunduz https://github.com/ibrahimgunduz34 https://twitter.com/ibrahimgunduz34 ibrahimgunduz34@gmail.com http://www.ibrahimgunduz.net/ Teşekkürler

×