kazimyilmaz Önce şunu konuşalım; MD5 tek yönlü bir hash algoritması iken base64 ise çift yönlü bir kodlama algoritması. Birinde sadece hash var diğerinde encode ve decode var. Bu durumda ikisini encode adı altında kullanmanız doğru olmaz. Hash algoritmalarına şuradan bakabilirsiniz:
https://www.php.net/manual/en/function.hash-algos.php
https://en.wikipedia.org/wiki/List_of_hash_functions
Kodunuzda enCodeType bir işe yaramıyor. Öyle bir kontrol yapacaksanız $value instanceof EncodeStringInterface
şeklinde kontrol etmelisiniz. O yüzden provider içinde yaptığınız da gereksiz.
Yöntemler Exception dönemez o yüzden public function enCode(Input $input): string|\Exception {
şeklinde bir ifade yanlış. Exception fırlatarak daha o aşamaya gelmeden uygulamayı zaten kırıyorsunuz.
enCode şeklinde bir kelime yok, encode olacak.
Bir şeye encodable diyorsanız bu onun encode edilebilen bir şey olduğunu ifade eder. Sizin orada vermek istediğiniz isim aslında encoder. Encodable burada kodlayacağınız karakter ifade (string), kodlayacak olan ise encoder.
Diyelim ki bu yaptığınız mantıklı bir şey. Şöyle olabilirdi:
interface HashAlgorithmInterface
{
public function make(): string;
}
interface HasherInterface
{
public function make(HashAlgorithmInterface $algo): string;
}
class MD5Algorithm implements HashAlgorithmInterface
{
public function __construct(
public readonly string $data,
public ?array $options = null,
)
{}
public function make(): string
{
return hash('md5', $this->data);
}
}
class SHA256Algorithm implements HashAlgorithmInterface
{
public function __construct(
public readonly string $data,
public ?array $options = null,
)
{}
public function make(): string
{
return hash('sha256', $this->data);
}
}
class Hasher implements HasherInterface
{
public function make(HashAlgorithmInterface $algo): string
{
return $algo->make();
}
}
AppServiceProvider::register()
$this->app
->bind(HasherInterface::class, Hasher::class);
Örnek:
public function index(HasherInterface $hasher)
{
$hash = $hasher->make(
new MD5Algorithm('deneme')
);
}
Single Responsibility Principle
Her bir sınıf sadece üzerine düşen tek bir görevi yapıyor, hashlemek. Alakasız bir işlem yapmıyor.
Open/Close Principle
Yeni bir algoritma ekleyebilirim ve bu ekleme benim mevcut kodumu bozmaz.
Liskov Substitution Principle
Burada extend kullanmadığım için bu devreye girmedi ama kullansaydım, örneğin Hasher sınıfı için bir decorator yazsaydım ve onu kullansaydım, çalışmasını etkilememesi gerekiyordu.
Interface Segregation Principle
Tek bir interface kullandığım için ve her algoritma ve hasher buna ihtiyacı olduğu için bu ilkeden de etkilenmedim. Sınıfa kullanmayacağı bir interface vermemelisiniz.
Dependency Inversion Principle
Hasher sınıfına HashAlgorithmInterface vererek bu ilkeyi gerçekleştirdim, böylece bağımlığı birden fazla algoritma verebilecek şekilde hallettim.
Elbette ben mühendis olmadığım için işin bilimsel kısmında çok bilgim yok, yanlış yapmış olabilirim. Ben kodumu yazarken ilkelere uysun diye yazmıyorum, benim için önemli olan basitlik ve ileri uyumluluk. SOLID tartışmalı bir konu, biraz araştırırsanız her kafadan bir ses çıktığını görürsünüz. Şöyle de bir şey var (bana göre) SOLID prensiplerini en rahat çiğneyenler genelde prensipleri en iyi bilenlerdir.