SOLID Prensibine Uygun Bir Proje Yapalım

Proje Tanımı

Bu proje, bir restoranın sipariş alımı ve hesap işlemlerini gerçekleştirmek için tasarlanmış bir uygulamadır. Uygulama, müşterilerin siparişlerini oluşturmasına, siparişleri onaylamasına ve hesaplarını ödemesine olanak tanıyacak şekilde tasarlanmıştır.

SOLID Prensipleri

Projenin SOLID prensiplerine uygun şekilde tasarlanması için şu adımlar atılabilir:

  • Tek Sorumluluk Prensibi (SRP):

    Her sınıfın yalnızca bir sorumluluğu olmalıdır. Bu prensibi uygulamak için, her sınıfın tek bir amaç için tasarlanmış olduğundan emin olmak gerekir.

  • Açık/Kapalı Prensibi (OCP):

    Yazılım modülleri, değişime kapalı ancak genişletilebilir olmalıdır. Bu prensibi uygulamak için, kodunuzun gelecekteki değişikliklere açık olduğundan emin olmanız gerekir. Kodunuzu değiştirmeden yeni özellikler ekleyebilmelisiniz.

  • Liskov Yerine Koyma Prensibi (LSP):

    Alt sınıflar, üst sınıfların yerine kullanılabilir olmalıdır. Bu prensibi uygulamak için, alt sınıfların üst sınıfların yerine kullanılabileceğinden emin olmanız gerekir.

  • Arayüz Ayrımı Prensibi (ISP):

    İstemciler, kullanmayacakları arayüzleri implemente etmek zorunda olmamalıdır. Bu prensibi uygulamak için, her sınıfın sadece kendi ihtiyaçları için gerekli olan arayüzleri uygulamasına izin vermeniz gerekir.

  • Bağımlılıkların Tersine Çevirme Prensibi (DIP):

    Alt seviyeli modüller, üst seviyeli modüllere bağımlı olmamalıdır. Bu prensibi uygulamak için, bağımlılıkları mümkün olduğunca soyutlama üzerinden oluşturmalısınız.

Sınıf Yapısı

Bu projede, aşağıdaki sınıflar yer alacaktır:

  • Musteri: Bu sınıf, müşterilerin bilgilerini ve siparişlerini temsil eder.
  • Urun: Bu sınıf, restoranın menüsünde bulunan ürünleri temsil eder.
  • Siparis: Bu sınıf, müşterilerin oluşturdukları siparişleri temsil eder.
  • Hesap: Bu sınıf, müşterilerin hesaplarını temsil eder ve hesap işlemlerini gerçekleştirir.
  • SiparisYoneticisi: Bu sınıf, sipariş oluşturma ve onaylama işlemlerini gerçekleştirir.
  • OdemeYoneticisi: Bu sınıf, ödeme işlemlerini gerçekleştirir.
  • SiparisOnaylayici: Bu arayüz, sipariş onaylama işlemini gerçekleştiren sınıflar için bir şablon görevi görür.
  • OdemeYontemi: Bu arayüz, ödeme işlemini gerçekleştiren sınıflar için bir şablon görevi görür.

Sınıf Detayları

  1. Musteri sınıfı:
public class Musteri {
    private String isim;
    private String soyisim;
    private String adres;
    private List<Siparis> siparisListesi;

    public Musteri(String isim, String soyisim, String adres) {
        this.isim = isim;
        this.soyisim = soyisim;
        this.adres = adres;
        this.siparisListesi = new ArrayList<>();
    }

    public void siparisEkle(Siparis siparis) {
        siparisListesi.add(siparis);
    }

    public List<Siparis> getSiparisListesi() {
        return siparisListesi;
    }

    // getters and setters
}

Bu sınıf, müşterilerin bilgilerini ve siparişlerini temsil eder. Her müşterinin bir isim, soyisim ve adres bilgisi vardır. Ayrıca, müşterinin siparişleri bir List içinde saklanır. Sipariş ekleme ve sipariş listesi alma gibi temel işlevleri vardır.

  1. Urun sınıfı:
public class Urun {
    private String ad;
    private double fiyat;

    public Urun(String ad, double fiyat) {
        this.ad = ad;
        this.fiyat = fiyat;
    }

    // getters and setters
}

Bu sınıf, restoranın menüsünde yer alan ürünleri temsil eder. Her ürünün bir adı ve bir fiyatı vardır.

  1. Siparis sınıfı:
public class Siparis {
    private Musteri musteri;
    private List<Urun> urunListesi;
    private double toplamFiyat;
    private boolean onaylandi;

    public Siparis(Musteri musteri) {
        this.musteri = musteri;
        this.urunListesi = new ArrayList<>();
        this.toplamFiyat = 0;
        this.onaylandi = false;
    }

    public void urunEkle(Urun urun) {
        urunListesi.add(urun);
        toplamFiyat += urun.getFiyat();
    }

    // getters and setters
}

Bu sınıf, müşterilerin oluşturdukları siparişleri temsil eder. Her siparişin bir müşterisi ve bir ürün listesi vardır. Ayrıca, siparişin toplam fiyatı ve onay durumu da saklanır. Siparişe ürün ekleme gibi temel işlevleri vardır.

  1. Hesap sınıfı:
public class Hesap {
    private Musteri musteri;
    private double bakiye;

    public Hesap(Musteri musteri) {
        this.musteri = musteri;
        this.bakiye = 0;
    }

    public void paraYatir(double miktar) {
        bakiye += miktar;
    }

    public void paraCek(double miktar) {
        if (bakiye < miktar) {
            throw new RuntimeException("Yetersiz bakiye");
        }
        bakiye -= miktar;
    }

    public double getBakiye() {
        return bakiye;
    }

    // getters and setters
}

Bu sınıf, müşterilerin hesaplarını temsil eder ve hesap işlemlerini gerçekleştirir. Her hesabın bir müşterisi ve bir bakiyesi vardır. Hesaba para yatırma ve para çekme gibi temel işlevleri vardır.

  1. SiparisYoneticisi sınıfı:
public class SiparisYoneticisi {
    private List<Siparis> siparisListesi;
    private SiparisOnaylayici siparisOnaylayici;

    public SiparisYoneticisi() {
        this.siparisListesi = new ArrayList<>();
    }

    public void siparisEkle(Siparis siparis) {
        siparisListesi.add(siparis);
    }

    public void siparisOnayla(Siparis siparis) {
        siparisOnaylayici.onayla(siparis);
        siparis.setOnaylandi(true);
    }

    public void setSiparisOnaylayici(SiparisOnaylayici siparisOnaylayici) {
        this.siparisOnaylayici = siparisOnaylayici;
    }

    // getters and setters
}

Bu sınıf, sipariş oluşturma ve onaylama işlemlerini gerçekleştirir. Her sipariş yöneticisinin bir sipariş listesi ve bir sipariş onaylayıcısı vardır. Sipariş ekleme, sipariş onaylama ve sipariş onaylayıcı ayarlama gibi temel işlevleri vardır.

  1. OdemeYoneticisi sınıfı
public class OdemeYoneticisi {
    private OdemeYontemi odemeYontemi;

    public void odemeYap(Siparis siparis) {
        double toplamFiyat = siparis.getToplamFiyat();
        odemeYontemi.odemeYap(toplamFiyat);
    }

    public void setOdemeYontemi(OdemeYontemi odemeYontemi) {
        this.odemeYontemi = odemeYontemi;
    }
}

Bu sınıf, ödeme işlemlerini gerçekleştirir. Her ödeme yöneticisinin bir ödeme yöntemi vardır. Ödeme yapma ve ödeme yöntemi ayarlama gibi temel işlevleri vardır.

  1. SiparisOnaylayici arayüzü:
public interface SiparisOnaylayici {
    void onayla(Siparis siparis);
}

Bu arayüz, sipariş onaylama işlemini gerçekleştiren sınıfların uyması gereken standartları belirler. SiparisYoneticisi, SatisElemani ve Mudur sınıfları bu arayüzü uygular.

  1. KrediKartiOdeme sınıfı:
public class KrediKartiOdeme implements OdemeYontemi {
    private String kartNumarasi;
    private String sonKullanmaTarihi;
    private String guvenlikKodu;

    public KrediKartiOdeme(String kartNumarasi, String sonKullanmaTarihi, String guvenlikKodu) {
        this.kartNumarasi = kartNumarasi;
        this.sonKullanmaTarihi = sonKullanmaTarihi;
        this.guvenlikKodu = guvenlikKodu;
    }

    @Override
    public void odemeYap(double miktar) {
        // kredi kartı ile ödeme yapma işlemleri
    }

    // getters and setters
}

Bu sınıf, kredi kartı ile ödeme yapma işlemlerini gerçekleştirir. Her kredi kartı ödeme yönteminin bir kart numarası, son kullanma tarihi ve güvenlik kodu vardır. OdemeYontemi arayüzünü uygular.

  1. NakitOdeme sınıfı:
public class NakitOdeme implements OdemeYontemi {
    @Override
    public void odemeYap(double miktar) {
        // nakit ödeme yapma işlemleri
    }
}

Bu sınıf, nakit ödeme yapma işlemlerini gerçekleştirir. OdemeYontemi arayüzünü uygular. Bu proje, SOLID prensiplerine uyan bir yapıda tasarlanmıştır. Her sınıfın tek bir sorumluluğu vardır ve birbirleriyle bağımlılıkları minimize edilmiştir. Örneğin, SiparisYoneticisi sınıfı sadece siparişleri yönetir ve sipariş onaylama işlemini SiparisOnaylayici arayüzüne göre gerçekleştirir. Bu sayede, sistemde değişiklik yapmak istendiğinde sadece ilgili sınıflarda değişiklik yapmak yeterlidir.

Ayrıca, sınıflar arasındaki bağımlılıklar, arayüzler ve bağımlılık enjeksiyonu kullanılarak yönetilir. OdemeYontemi arayüzü, farklı ödeme yöntemlerinin uyguladığı standartları belirler ve herhangi bir ödeme yöntemi, bu arayüzü uygulayarak sistem içinde yer alabilir.

SOLID prensipleri, kodun daha okunaklı, sürdürülebilir ve ölçeklenebilir olmasını sağlar.