0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6

Gauloran

Global Moderatör
7 Tem 2013
8,127
618
serimizin 6.konusu ile devam ediyoruz. serinin önceki konularını inceleyip yorum yapmayı unutmayalım:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5

şimdi _User diye bir sınıf oluşturalım örnekle devam edelim:

Kod:
class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

ve ana fonksiyonumuzda şöyle devam edelim:

Kod:
final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
tr yazacak yada orada 15 yazabilir.
ekrana bastır

Kod:
final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

Şimdi Bank diye bir sınıf oluşturalım
classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya

Kod:
class Bank {
  final int money;
  Bank(this.money);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }
}

yukarıdaki kodlarda operator + ile başlayan kendi operatörümüzü yazmadığımızı o kısmı eklemediğimizi düşünürsek:

Kod:
//şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50);
  final moneyBank2 = Bank(50);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

devam edelim

Kod:
print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
} //!yazdık artık ve çalışıyor

şimdi kodlarda epey değişikliğe gideceğiz mixin kullanımı with BankMixin yapacağız == operatörünü de yazdık

Kod:
// ignore_for_file: public_member_api_docs, sort_constructors_first
void main(List<String> args) {
  final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

  //kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
  //parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
  // tr yazacak yada orada 15 yazabilir.
  //ekrana bastır

  final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

  //#################################################
  int money1 = 50;
  int money2 = 50;
  if (money1 == money2) {
    print("ok");
  } //şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50, 1);
  final moneyBank2 = Bank(50, 2);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

  /*
  classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
  bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
  bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya
   */

  //müşteri banka sınıfından iki elemanı toplayıp sonucu söyler misin?

  print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
//!yazdık artık ve çalışıyor

  //bankamiza gelen musterilerin idsi ayni olanlar ayni musteri olmalıdır

  print(moneyBank1 == moneyBank2); //false gorunur referans mevzusundan dolayi

  //toString override ettigimiz icin deneyelim
  print(moneyBank1
      .toString()); //ali diye ekledik sonuna override ettik cunku toString metodunu bu sayede varolan bir metodu kendimiz mudahale ettik
  //tekrar çağırıp tekrar yükleme yaptık yani

  print(moneyBank1 == moneyBank2);

  //diğer bankadan bir modül alıp ekleyip müşterinin parasını sorgulamak
}

class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

class Bank with BankMixin {
  final int money;
  final int id;
  Bank(this.money, this.id);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }

  //butun classlar objectten turer bu yuzden toString vardir bu sinif icin toStringi override edelim
  @override
  String toString() {
    return super.toString() + "ali";
  }

  //! generate equality yaptıgımızda bizim icin yapar == operatorunu id icin kontrol etme islemini
  //yani id si aynı olan bu sınıfın nesneleri normalde nesne karşılaştırması olduğunda referans mevzusundan dolayı false çıkan şeyi true çıkartmak için
  @override
  bool operator ==(Object object) {
    return this.id == id;
  }

  @override //şu şu işleri yapacak falan polimorfizm senaryolarında aktif olarak kullanılabilir bir mevzu
  void sayBankHello() {
    // TODO: implement sayBankHello
    calculateMoney(money);
  }
}

//diğer bankadan bir modül alma falan normalde class yapıp diğer bankayı da yapardık ama işini yapıp metodunu yapıp geri döndürecek bir şeyse
//mixin kullanmalıyız, işlerini yapıp geri döndüren metodlardır aslında constructorsız classlar olarak düşünebiliriz mixin leri

mixin BankMixin {
  //bunu yaptık artık Bank sınıfına bu fonksiyonun içerdiği şeyleri kazandırmak için gidip with BankMixin demeliyiz
  void sayBankHello(); //parametre içini doldurmamıza gerek yok
  void calculateMoney(int money) {
    print('money');
  }
}

yanlarda açıklamalı şeyler yazdığım için kodları incelemeniz yeterli olacaktır. şimdi cascade notation diye bir şey var ona bakalım neymiş

Kod:
void updateName(String name) {
    this.name == name;
  }

bunu sınıfımıza ekledik şimdi ana fonksiyona dönelim cascade notation'a bakalım

Kod:
//cascade notation diye bir kullanım var bu da şu mesela herhangi bir nesnede
  moneyBank1
    ..money += 10
    ..updateName(
        "ozgur"); //tek satırda nesnenin birkaç özelliğine müdahale edebiliyoruz cascade notation sayesinde .. koymamız yeterli kullanımı budur

şimdi class singleton kavramına bakalım öncelikle aşağıdaki kodları inceleyelim

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();

}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/

class Product {
  int money = 10;
}

şimdi devamına bakalım:

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if (Product.money > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

class Product {
  static int money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static void incrementMoney(int newMoney) {
    money += newMoney;
  }
}

static bizim için çok önemli bunu da anladık.
bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz
 
}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

kavramların içerisinde kaybolmayalım şimdi bunların hepsini bilmek önemli ama kullanmamız gerekiyor yazarken. şimdi factory kullanımına bakalım tekrar constructor da constructor ne constructormış arkadaş

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }

//user sınıfını kullanarak product yapmak istiyoruz
  final user1 = User("ozgur", "aa");
  final newProduct2 = Product(user1.product);
  //!bu kullanım birazcık sıkıntılı bir kullanım niye bakalım factory metod diye bir kavram var sinifimiza gidip bakalim
  //! constructorına bak Product ın orada bir açıklama yaptık zaten yorum satırında

  Product
      .mehmet(); //ozel constructırımızı kullandık direkt mehmet i uretiyor yani vermezsek git bak mehmet isimli constructora

  final newProduct3 = Product.fromUser(user1); //bu sekilde yapilabilir factory kullanımını da gormus olduk
 
}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  //Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz
}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz
  String name;
  Product(
      this.name) {} //! constructorımız der ki class ilk yüklendiğinde ilk sınıfın harekete geçtiği yer constructırdır burası çalışır

  Product.mehmet([this.name = "mehmet"]);

//! simdi ozel bir constructor olusturduk mesela fromUser diye User sınıfından bir nesne aliyor ve o nesnenin name ozelligini kullaniyor Product sinifindan nesne olusturuyor
//! constructor geriye bir şey döndürmez geriye değer döndürmesini istediğimiz bir constructor varsa işte burada mevzuya factory giriyor başa factory yazıyoruz
  factory Product.fromUser(User user) {
    return Product(user.name);
  }

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

class User {
  final String name;
  final String product;
  User(this.name, this.product);
}

epey bir açıklamalı kod yazdım burada mevzular dönüyor ama karışık değil. şimdi biraz karışabilir mesela adam gidiyor

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz
  ProductConfig(this.apiKey);
  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig("a");
}

ana fonksiyonda da

Kod:
 ProductConfig.instance.apiKey; //!böyle eriştik ama başka birisi de erişebilir
  ProductConfig("asd").apiKey; //! adam gidiyo asd yazıyor apiKey bana farklı geliyor diyor misal

şimdi sınıfı şöyle güncellersek

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

artık dışarıdan eleman nesne üretemez hale geliyor. eager singletondı aslında bu ve zaten iki tip gibi düşünelim lazysingleton ve eager singleton ikisine de bakacaksak şu şekilde

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(
      this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

//singleton kullanımları iki tane bir tanesi yukarıdaki gibi diğeri de lazy kullanım oluyor. yukarıdaki ise eager kullanımı diyebiliriz

class ProductLazySingleton {
  static ProductLazySingleton? _instance;
  static ProductLazySingleton get instance {
    if (_instance == null) _instance = ProductLazySingleton._init();
    return _instance!;
  }

  ProductLazySingleton._init();
}

Birçok projede hayatımızı kurtaracak bir şey. Bu sayede biz işlemlerimizi yaparken sonuç olarak static bir instance yaparak tek bir classtan bir instance ile yönetimi sağlayabiliyoruz. Bir sonraki konuyla serimize devam edelim Dart'a devam ediyoruz bu konu biraz karmaşık gelmiş olabilir yola devam.

<3 Gauloran

 

hoaydar

Yazılım Ekibi
18 Ocak 2023
489
412
/system32
serimizin 6.konusu ile devam ediyoruz. serinin önceki konularını inceleyip yorum yapmayı unutmayalım:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5

şimdi _User diye bir sınıf oluşturalım örnekle devam edelim:

Kod:
class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

ve ana fonksiyonumuzda şöyle devam edelim:

Kod:
final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
tr yazacak yada orada 15 yazabilir.
ekrana bastır

Kod:
final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

Şimdi Bank diye bir sınıf oluşturalım
classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya

Kod:
class Bank {
  final int money;
  Bank(this.money);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }
}

yukarıdaki kodlarda operator + ile başlayan kendi operatörümüzü yazmadığımızı o kısmı eklemediğimizi düşünürsek:

Kod:
//şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50);
  final moneyBank2 = Bank(50);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

devam edelim

Kod:
print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
} //!yazdık artık ve çalışıyor

şimdi kodlarda epey değişikliğe gideceğiz mixin kullanımı with BankMixin yapacağız == operatörünü de yazdık

Kod:
// ignore_for_file: public_member_api_docs, sort_constructors_first
void main(List<String> args) {
  final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

  //kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
  //parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
  // tr yazacak yada orada 15 yazabilir.
  //ekrana bastır

  final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

  //#################################################
  int money1 = 50;
  int money2 = 50;
  if (money1 == money2) {
    print("ok");
  } //şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50, 1);
  final moneyBank2 = Bank(50, 2);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

  /*
  classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
  bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
  bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya
   */

  //müşteri banka sınıfından iki elemanı toplayıp sonucu söyler misin?

  print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
//!yazdık artık ve çalışıyor

  //bankamiza gelen musterilerin idsi ayni olanlar ayni musteri olmalıdır

  print(moneyBank1 == moneyBank2); //false gorunur referans mevzusundan dolayi

  //toString override ettigimiz icin deneyelim
  print(moneyBank1
      .toString()); //ali diye ekledik sonuna override ettik cunku toString metodunu bu sayede varolan bir metodu kendimiz mudahale ettik
  //tekrar çağırıp tekrar yükleme yaptık yani

  print(moneyBank1 == moneyBank2);

  //diğer bankadan bir modül alıp ekleyip müşterinin parasını sorgulamak
}

class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

class Bank with BankMixin {
  final int money;
  final int id;
  Bank(this.money, this.id);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }

  //butun classlar objectten turer bu yuzden toString vardir bu sinif icin toStringi override edelim
  @override
  String toString() {
    return super.toString() + "ali";
  }

  //! generate equality yaptıgımızda bizim icin yapar == operatorunu id icin kontrol etme islemini
  //yani id si aynı olan bu sınıfın nesneleri normalde nesne karşılaştırması olduğunda referans mevzusundan dolayı false çıkan şeyi true çıkartmak için
  @override
  bool operator ==(Object object) {
    return this.id == id;
  }

  @override //şu şu işleri yapacak falan polimorfizm senaryolarında aktif olarak kullanılabilir bir mevzu
  void sayBankHello() {
    // TODO: implement sayBankHello
    calculateMoney(money);
  }
}

//diğer bankadan bir modül alma falan normalde class yapıp diğer bankayı da yapardık ama işini yapıp metodunu yapıp geri döndürecek bir şeyse
//mixin kullanmalıyız, işlerini yapıp geri döndüren metodlardır aslında constructorsız classlar olarak düşünebiliriz mixin leri

mixin BankMixin {
  //bunu yaptık artık Bank sınıfına bu fonksiyonun içerdiği şeyleri kazandırmak için gidip with BankMixin demeliyiz
  void sayBankHello(); //parametre içini doldurmamıza gerek yok
  void calculateMoney(int money) {
    print('money');
  }
}

yanlarda açıklamalı şeyler yazdığım için kodları incelemeniz yeterli olacaktır. şimdi cascade notation diye bir şey var ona bakalım neymiş

Kod:
void updateName(String name) {
    this.name == name;
  }

bunu sınıfımıza ekledik şimdi ana fonksiyona dönelim cascade notation'a bakalım

Kod:
//cascade notation diye bir kullanım var bu da şu mesela herhangi bir nesnede
  moneyBank1
    ..money += 10
    ..updateName(
        "ozgur"); //tek satırda nesnenin birkaç özelliğine müdahale edebiliyoruz cascade notation sayesinde .. koymamız yeterli kullanımı budur

şimdi class singleton kavramına bakalım öncelikle aşağıdaki kodları inceleyelim

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();

}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/

class Product {
  int money = 10;
}

şimdi devamına bakalım:

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if (Product.money > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

class Product {
  static int money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static void incrementMoney(int newMoney) {
    money += newMoney;
  }
}

static bizim için çok önemli bunu da anladık.
bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz

}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

kavramların içerisinde kaybolmayalım şimdi bunların hepsini bilmek önemli ama kullanmamız gerekiyor yazarken. şimdi factory kullanımına bakalım tekrar constructor da constructor ne constructormış arkadaş

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }

//user sınıfını kullanarak product yapmak istiyoruz
  final user1 = User("ozgur", "aa");
  final newProduct2 = Product(user1.product);
  //!bu kullanım birazcık sıkıntılı bir kullanım niye bakalım factory metod diye bir kavram var sinifimiza gidip bakalim
  //! constructorına bak Product ın orada bir açıklama yaptık zaten yorum satırında

  Product
      .mehmet(); //ozel constructırımızı kullandık direkt mehmet i uretiyor yani vermezsek git bak mehmet isimli constructora

  final newProduct3 = Product.fromUser(user1); //bu sekilde yapilabilir factory kullanımını da gormus olduk

}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  //Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz
}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz
  String name;
  Product(
      this.name) {} //! constructorımız der ki class ilk yüklendiğinde ilk sınıfın harekete geçtiği yer constructırdır burası çalışır

  Product.mehmet([this.name = "mehmet"]);

//! simdi ozel bir constructor olusturduk mesela fromUser diye User sınıfından bir nesne aliyor ve o nesnenin name ozelligini kullaniyor Product sinifindan nesne olusturuyor
//! constructor geriye bir şey döndürmez geriye değer döndürmesini istediğimiz bir constructor varsa işte burada mevzuya factory giriyor başa factory yazıyoruz
  factory Product.fromUser(User user) {
    return Product(user.name);
  }

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

class User {
  final String name;
  final String product;
  User(this.name, this.product);
}

epey bir açıklamalı kod yazdım burada mevzular dönüyor ama karışık değil. şimdi biraz karışabilir mesela adam gidiyor

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz
  ProductConfig(this.apiKey);
  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig("a");
}

ana fonksiyonda da

Kod:
 ProductConfig.instance.apiKey; //!böyle eriştik ama başka birisi de erişebilir
  ProductConfig("asd").apiKey; //! adam gidiyo asd yazıyor apiKey bana farklı geliyor diyor misal

şimdi sınıfı şöyle güncellersek

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

artık dışarıdan eleman nesne üretemez hale geliyor. eager singletondı aslında bu ve zaten iki tip gibi düşünelim lazysingleton ve eager singleton ikisine de bakacaksak şu şekilde

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(
      this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

//singleton kullanımları iki tane bir tanesi yukarıdaki gibi diğeri de lazy kullanım oluyor. yukarıdaki ise eager kullanımı diyebiliriz

class ProductLazySingleton {
  static ProductLazySingleton? _instance;
  static ProductLazySingleton get instance {
    if (_instance == null) _instance = ProductLazySingleton._init();
    return _instance!;
  }

  ProductLazySingleton._init();
}

Birçok projede hayatımızı kurtaracak bir şey. Bu sayede biz işlemlerimizi yaparken sonuç olarak static bir instance yaparak tek bir classtan bir instance ile yönetimi sağlayabiliyoruz. Bir sonraki konuyla serimize devam edelim Dart'a devam ediyoruz bu konu biraz karmaşık gelmiş olabilir yola devam.

<3 Gauloran

Dostum ellerine sağlık gerçekten uğraşılmış bir gönderi olmuş
 

bozzturkk

Üye
25 Nis 2023
126
41
serimizin 6.konusu ile devam ediyoruz. serinin önceki konularını inceleyip yorum yapmayı unutmayalım:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5

şimdi _User diye bir sınıf oluşturalım örnekle devam edelim:

Kod:
class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

ve ana fonksiyonumuzda şöyle devam edelim:

Kod:
final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
tr yazacak yada orada 15 yazabilir.
ekrana bastır

Kod:
final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

Şimdi Bank diye bir sınıf oluşturalım
classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya

Kod:
class Bank {
  final int money;
  Bank(this.money);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }
}

yukarıdaki kodlarda operator + ile başlayan kendi operatörümüzü yazmadığımızı o kısmı eklemediğimizi düşünürsek:

Kod:
//şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50);
  final moneyBank2 = Bank(50);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

devam edelim

Kod:
print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
} //!yazdık artık ve çalışıyor

şimdi kodlarda epey değişikliğe gideceğiz mixin kullanımı with BankMixin yapacağız == operatörünü de yazdık

Kod:
// ignore_for_file: public_member_api_docs, sort_constructors_first
void main(List<String> args) {
  final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

  //kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
  //parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
  // tr yazacak yada orada 15 yazabilir.
  //ekrana bastır

  final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

  //#################################################
  int money1 = 50;
  int money2 = 50;
  if (money1 == money2) {
    print("ok");
  } //şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50, 1);
  final moneyBank2 = Bank(50, 2);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

  /*
  classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
  bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
  bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya
   */

  //müşteri banka sınıfından iki elemanı toplayıp sonucu söyler misin?

  print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
//!yazdık artık ve çalışıyor

  //bankamiza gelen musterilerin idsi ayni olanlar ayni musteri olmalıdır

  print(moneyBank1 == moneyBank2); //false gorunur referans mevzusundan dolayi

  //toString override ettigimiz icin deneyelim
  print(moneyBank1
      .toString()); //ali diye ekledik sonuna override ettik cunku toString metodunu bu sayede varolan bir metodu kendimiz mudahale ettik
  //tekrar çağırıp tekrar yükleme yaptık yani

  print(moneyBank1 == moneyBank2);

  //diğer bankadan bir modül alıp ekleyip müşterinin parasını sorgulamak
}

class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

class Bank with BankMixin {
  final int money;
  final int id;
  Bank(this.money, this.id);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }

  //butun classlar objectten turer bu yuzden toString vardir bu sinif icin toStringi override edelim
  @override
  String toString() {
    return super.toString() + "ali";
  }

  //! generate equality yaptıgımızda bizim icin yapar == operatorunu id icin kontrol etme islemini
  //yani id si aynı olan bu sınıfın nesneleri normalde nesne karşılaştırması olduğunda referans mevzusundan dolayı false çıkan şeyi true çıkartmak için
  @override
  bool operator ==(Object object) {
    return this.id == id;
  }

  @override //şu şu işleri yapacak falan polimorfizm senaryolarında aktif olarak kullanılabilir bir mevzu
  void sayBankHello() {
    // TODO: implement sayBankHello
    calculateMoney(money);
  }
}

//diğer bankadan bir modül alma falan normalde class yapıp diğer bankayı da yapardık ama işini yapıp metodunu yapıp geri döndürecek bir şeyse
//mixin kullanmalıyız, işlerini yapıp geri döndüren metodlardır aslında constructorsız classlar olarak düşünebiliriz mixin leri

mixin BankMixin {
  //bunu yaptık artık Bank sınıfına bu fonksiyonun içerdiği şeyleri kazandırmak için gidip with BankMixin demeliyiz
  void sayBankHello(); //parametre içini doldurmamıza gerek yok
  void calculateMoney(int money) {
    print('money');
  }
}

yanlarda açıklamalı şeyler yazdığım için kodları incelemeniz yeterli olacaktır. şimdi cascade notation diye bir şey var ona bakalım neymiş

Kod:
void updateName(String name) {
    this.name == name;
  }

bunu sınıfımıza ekledik şimdi ana fonksiyona dönelim cascade notation'a bakalım

Kod:
//cascade notation diye bir kullanım var bu da şu mesela herhangi bir nesnede
  moneyBank1
    ..money += 10
    ..updateName(
        "ozgur"); //tek satırda nesnenin birkaç özelliğine müdahale edebiliyoruz cascade notation sayesinde .. koymamız yeterli kullanımı budur

şimdi class singleton kavramına bakalım öncelikle aşağıdaki kodları inceleyelim

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();

}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/

class Product {
  int money = 10;
}

şimdi devamına bakalım:

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if (Product.money > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

class Product {
  static int money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static void incrementMoney(int newMoney) {
    money += newMoney;
  }
}

static bizim için çok önemli bunu da anladık.
bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz

}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

kavramların içerisinde kaybolmayalım şimdi bunların hepsini bilmek önemli ama kullanmamız gerekiyor yazarken. şimdi factory kullanımına bakalım tekrar constructor da constructor ne constructormış arkadaş

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }

//user sınıfını kullanarak product yapmak istiyoruz
  final user1 = User("ozgur", "aa");
  final newProduct2 = Product(user1.product);
  //!bu kullanım birazcık sıkıntılı bir kullanım niye bakalım factory metod diye bir kavram var sinifimiza gidip bakalim
  //! constructorına bak Product ın orada bir açıklama yaptık zaten yorum satırında

  Product
      .mehmet(); //ozel constructırımızı kullandık direkt mehmet i uretiyor yani vermezsek git bak mehmet isimli constructora

  final newProduct3 = Product.fromUser(user1); //bu sekilde yapilabilir factory kullanımını da gormus olduk

}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  //Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz
}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz
  String name;
  Product(
      this.name) {} //! constructorımız der ki class ilk yüklendiğinde ilk sınıfın harekete geçtiği yer constructırdır burası çalışır

  Product.mehmet([this.name = "mehmet"]);

//! simdi ozel bir constructor olusturduk mesela fromUser diye User sınıfından bir nesne aliyor ve o nesnenin name ozelligini kullaniyor Product sinifindan nesne olusturuyor
//! constructor geriye bir şey döndürmez geriye değer döndürmesini istediğimiz bir constructor varsa işte burada mevzuya factory giriyor başa factory yazıyoruz
  factory Product.fromUser(User user) {
    return Product(user.name);
  }

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

class User {
  final String name;
  final String product;
  User(this.name, this.product);
}

epey bir açıklamalı kod yazdım burada mevzular dönüyor ama karışık değil. şimdi biraz karışabilir mesela adam gidiyor

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz
  ProductConfig(this.apiKey);
  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig("a");
}

ana fonksiyonda da

Kod:
 ProductConfig.instance.apiKey; //!böyle eriştik ama başka birisi de erişebilir
  ProductConfig("asd").apiKey; //! adam gidiyo asd yazıyor apiKey bana farklı geliyor diyor misal

şimdi sınıfı şöyle güncellersek

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

artık dışarıdan eleman nesne üretemez hale geliyor. eager singletondı aslında bu ve zaten iki tip gibi düşünelim lazysingleton ve eager singleton ikisine de bakacaksak şu şekilde

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(
      this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

//singleton kullanımları iki tane bir tanesi yukarıdaki gibi diğeri de lazy kullanım oluyor. yukarıdaki ise eager kullanımı diyebiliriz

class ProductLazySingleton {
  static ProductLazySingleton? _instance;
  static ProductLazySingleton get instance {
    if (_instance == null) _instance = ProductLazySingleton._init();
    return _instance!;
  }

  ProductLazySingleton._init();
}

Birçok projede hayatımızı kurtaracak bir şey. Bu sayede biz işlemlerimizi yaparken sonuç olarak static bir instance yaparak tek bir classtan bir instance ile yönetimi sağlayabiliyoruz. Bir sonraki konuyla serimize devam edelim Dart'a devam ediyoruz bu konu biraz karmaşık gelmiş olabilir yola devam.

<3 Gauloran
Elinize sağlık faydalı bir gönderi olmuş
 

ashpelia

Üye
26 Nis 2023
65
20
serimizin 6.konusu ile devam ediyoruz. serinin önceki konularını inceleyip yorum yapmayı unutmayalım:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5

şimdi _User diye bir sınıf oluşturalım örnekle devam edelim:

Kod:
class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

ve ana fonksiyonumuzda şöyle devam edelim:

Kod:
final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
tr yazacak yada orada 15 yazabilir.
ekrana bastır

Kod:
final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

Şimdi Bank diye bir sınıf oluşturalım
classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya

Kod:
class Bank {
  final int money;
  Bank(this.money);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }
}

yukarıdaki kodlarda operator + ile başlayan kendi operatörümüzü yazmadığımızı o kısmı eklemediğimizi düşünürsek:

Kod:
//şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50);
  final moneyBank2 = Bank(50);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

devam edelim

Kod:
print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
} //!yazdık artık ve çalışıyor

şimdi kodlarda epey değişikliğe gideceğiz mixin kullanımı with BankMixin yapacağız == operatörünü de yazdık

Kod:
// ignore_for_file: public_member_api_docs, sort_constructors_first
void main(List<String> args) {
  final user = _User('ali', age: 9);

  /* if(user.age ?? 0<18){

  } */

  if (user.age is int) {
    // is! demek int değil dimi demektir örneğin değer 9 ise is! kullandığımızda int değil dimi nin cevabı yok int olur yani false.
    //! age int mi? evetse true hayırsa false olur şartın içi
    if (user.age! < 18) {
      //! ! koyarak evet ben null olmadigini biliyorum bunun kesin diyoruz
      print('evet küçük 18 den');
      user.updateMoneyWithString("TR");
    } else {
      user.updateMoneyWithNumber(15);
    }
  }

  //kullanicilarimizin parasi var ama paranin tipi degisken olabilir misal.
  //parasi olan adamin o parametresi bir isim de olabilir veya deger olabilir
  // tr yazacak yada orada 15 yazabilir.
  //ekrana bastır

  final _newType = user.moneyType is String ? (user.moneyType as String) : "";
  //! user.moneyType Stringse String olarak kabul et değilse "" yap ki String olsun dedim

  print((_newType) + "A");

  //#################################################
  int money1 = 50;
  int money2 = 50;
  if (money1 == money2) {
    print("ok");
  } //şimdi bu aynı işlemi Bank sınıfıyla yapalım

  final moneyBank1 = Bank(50, 1);
  final moneyBank2 = Bank(50, 2);
  if (moneyBank1 == moneyBank2) {
    print("eşittir");
  } else {
    print("eşit değildir");
  }

  /*
  classlar birer referans tipidir referans tipi de kendi içlerinde yer tutarlar
  bundan dolayı öncelikle value leri karşılaştırmak yerine referanslar aynı mı diye kontrol edilir
  bu işlemin sonucunda eşittir sonucunu almak istiyorsak operatörlerde bitiyor iş. geldik kendi custom operatörlerimizi yazmaya
   */

  //müşteri banka sınıfından iki elemanı toplayıp sonucu söyler misin?

  print(moneyBank1 +
      moneyBank2); // e + da çalışmıyor neden?? çünkü ilgili sınıfta yani Bank sınıfında o operatörü yazmamız gerekir istediğimiz sonuç için
//!yazdık artık ve çalışıyor

  //bankamiza gelen musterilerin idsi ayni olanlar ayni musteri olmalıdır

  print(moneyBank1 == moneyBank2); //false gorunur referans mevzusundan dolayi

  //toString override ettigimiz icin deneyelim
  print(moneyBank1
      .toString()); //ali diye ekledik sonuna override ettik cunku toString metodunu bu sayede varolan bir metodu kendimiz mudahale ettik
  //tekrar çağırıp tekrar yükleme yaptık yani

  print(moneyBank1 == moneyBank2);

  //diğer bankadan bir modül alıp ekleyip müşterinin parasını sorgulamak
}

class _User {
  //!sınıfları da file private yapabiliyoruz
  final String name;
  int? age; //!nullable age
  dynamic moneyType;

  _User(this.name, {this.age}); //! constructor

  void updateMoneyWithString(String data) {
    moneyType = data;
  }

  void updateMoneyWithNumber(int number) {
    moneyType = number;
  }
}

class Bank with BankMixin {
  final int money;
  final int id;
  Bank(this.money, this.id);

  operator +(Bank newBank) {
    //kendi operatorumuzu olusturuyoruz + operatoru bir Bank sınıfından nesne alir ve
    return this.money +
        newBank
            .money; //! this.money yani o ilgili sinifin nesnesi ve + operatorunden sonra gelen şey newBank parametresi olarak gelip buraya eklenir
  }

  //butun classlar objectten turer bu yuzden toString vardir bu sinif icin toStringi override edelim
  @override
  String toString() {
    return super.toString() + "ali";
  }

  //! generate equality yaptıgımızda bizim icin yapar == operatorunu id icin kontrol etme islemini
  //yani id si aynı olan bu sınıfın nesneleri normalde nesne karşılaştırması olduğunda referans mevzusundan dolayı false çıkan şeyi true çıkartmak için
  @override
  bool operator ==(Object object) {
    return this.id == id;
  }

  @override //şu şu işleri yapacak falan polimorfizm senaryolarında aktif olarak kullanılabilir bir mevzu
  void sayBankHello() {
    // TODO: implement sayBankHello
    calculateMoney(money);
  }
}

//diğer bankadan bir modül alma falan normalde class yapıp diğer bankayı da yapardık ama işini yapıp metodunu yapıp geri döndürecek bir şeyse
//mixin kullanmalıyız, işlerini yapıp geri döndüren metodlardır aslında constructorsız classlar olarak düşünebiliriz mixin leri

mixin BankMixin {
  //bunu yaptık artık Bank sınıfına bu fonksiyonun içerdiği şeyleri kazandırmak için gidip with BankMixin demeliyiz
  void sayBankHello(); //parametre içini doldurmamıza gerek yok
  void calculateMoney(int money) {
    print('money');
  }
}

yanlarda açıklamalı şeyler yazdığım için kodları incelemeniz yeterli olacaktır. şimdi cascade notation diye bir şey var ona bakalım neymiş

Kod:
void updateName(String name) {
    this.name == name;
  }

bunu sınıfımıza ekledik şimdi ana fonksiyona dönelim cascade notation'a bakalım

Kod:
//cascade notation diye bir kullanım var bu da şu mesela herhangi bir nesnede
  moneyBank1
    ..money += 10
    ..updateName(
        "ozgur"); //tek satırda nesnenin birkaç özelliğine müdahale edebiliyoruz cascade notation sayesinde .. koymamız yeterli kullanımı budur

şimdi class singleton kavramına bakalım öncelikle aşağıdaki kodları inceleyelim

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();

}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/

class Product {
  int money = 10;
}

şimdi devamına bakalım:

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if (Product.money > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

class Product {
  static int money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static void incrementMoney(int newMoney) {
    money += newMoney;
  }
}

static bizim için çok önemli bunu da anladık.
bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }
}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz

}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

kavramların içerisinde kaybolmayalım şimdi bunların hepsini bilmek önemli ama kullanmamız gerekiyor yazarken. şimdi factory kullanımına bakalım tekrar constructor da constructor ne constructormış arkadaş

Kod:
void main(List<String> args) {
  //şimdi Product sınıfına erişmek için ondan nesne oluşturalım
  final newProduct = Product();
}

/*
bazı sınıflar ortak kullanılabilir bu gibi durumlarda müşteri bizden ekranlarda hep aynı şeyi kullanarak
her yerde bir class yapıp çağırmak yerine singleton mevzusuna gelmiş oluyoruz
*/
void calculateMoney() {
  if ((Product.money ?? 0) > 5) {
    print("5 tl daha eklendi");
    Product.incrementMoney(5);
    print(Product.money);
  }

//user sınıfını kullanarak product yapmak istiyoruz
  final user1 = User("ozgur", "aa");
  final newProduct2 = Product(user1.product);
  //!bu kullanım birazcık sıkıntılı bir kullanım niye bakalım factory metod diye bir kavram var sinifimiza gidip bakalim
  //! constructorına bak Product ın orada bir açıklama yaptık zaten yorum satırında

  Product
      .mehmet(); //ozel constructırımızı kullandık direkt mehmet i uretiyor yani vermezsek git bak mehmet isimli constructora

  final newProduct3 = Product.fromUser(user1); //bu sekilde yapilabilir factory kullanımını da gormus olduk

}

void productNameChange() {
  Product.money =
      null; //sonra null checklemeyi falan unuttuk falan ya da calculateMoney'i çağırdık falan hop metod çalışmıyor
  //yani static kullanımında dikkat etmek lazım
  //! static kullanıyorsak dikkat etmeliyiz
  //Product.companyName = ""; //hop bunu yapamaz çünkü const tanımladık bu şekilde yapılabilir tabi kendimizi önlemek adına
  //! bir ton yazılı olmayan kural var aslında bunları ilerde göreceğiz beraber öğreneceğiz
}

class Product {
  static int? money =
      10; //bu sınıftan artık herkes yeni bir nesne oluşturmadan money'i çağırabilecek!
  //static proje boyunca ayakta durur proje ölene kadar bu instance hayatı boyunca bizim belleğimizde yerini tutar biz öldürmediğimiz sürece bellekten çıkmaz
  String name;
  Product(
      this.name) {} //! constructorımız der ki class ilk yüklendiğinde ilk sınıfın harekete geçtiği yer constructırdır burası çalışır

  Product.mehmet([this.name = "mehmet"]);

//! simdi ozel bir constructor olusturduk mesela fromUser diye User sınıfından bir nesne aliyor ve o nesnenin name ozelligini kullaniyor Product sinifindan nesne olusturuyor
//! constructor geriye bir şey döndürmez geriye değer döndürmesini istediğimiz bir constructor varsa işte burada mevzuya factory giriyor başa factory yazıyoruz
  factory Product.fromUser(User user) {
    return Product(user.name);
  }

  static const companyName = "DENEME BANK";

  static void incrementMoney(int newMoney) {
    if (money != null) {
      money = money! + newMoney;
    }
  }
}

//! bu static kullanımı aslında tehlikelidir çünkü bu kullanımdan dolayı herkesin buna erişip dokunmasına izin veriyoruz
//! bunların çok manipüle edilip çok fazla crash gelme ihtimalini doğurur

class User {
  final String name;
  final String product;
  User(this.name, this.product);
}

epey bir açıklamalı kod yazdım burada mevzular dönüyor ama karışık değil. şimdi biraz karışabilir mesela adam gidiyor

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz
  ProductConfig(this.apiKey);
  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig("a");
}

ana fonksiyonda da

Kod:
 ProductConfig.instance.apiKey; //!böyle eriştik ama başka birisi de erişebilir
  ProductConfig("asd").apiKey; //! adam gidiyo asd yazıyor apiKey bana farklı geliyor diyor misal

şimdi sınıfı şöyle güncellersek

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

artık dışarıdan eleman nesne üretemez hale geliyor. eager singletondı aslında bu ve zaten iki tip gibi düşünelim lazysingleton ve eager singleton ikisine de bakacaksak şu şekilde

Kod:
class ProductConfig {
  final String
      apiKey; //!buna böyle herkes erişebilir bunun böyle erişilmesini istememeliyiz

  ProductConfig._(
      this.apiKey); //sadece bu fileda olanlar görebilir olur dışarıdan birisi nesne üretemez artık

  //! productconfigten sadece bir tane productconfig olsun kimse productconfig oluşturamasın istiyorsak singleton bir sınıf yapmak istiyoruz peki ne yapacağız
  //! piyasada kullanılan yöntem şu :)
  static final ProductConfig instance = ProductConfig._("a");
}

//singleton kullanımları iki tane bir tanesi yukarıdaki gibi diğeri de lazy kullanım oluyor. yukarıdaki ise eager kullanımı diyebiliriz

class ProductLazySingleton {
  static ProductLazySingleton? _instance;
  static ProductLazySingleton get instance {
    if (_instance == null) _instance = ProductLazySingleton._init();
    return _instance!;
  }

  ProductLazySingleton._init();
}

Birçok projede hayatımızı kurtaracak bir şey. Bu sayede biz işlemlerimizi yaparken sonuç olarak static bir instance yaparak tek bir classtan bir instance ile yönetimi sağlayabiliyoruz. Bir sonraki konuyla serimize devam edelim Dart'a devam ediyoruz bu konu biraz karmaşık gelmiş olabilir yola devam.

<3 Gauloran

eline sağlık
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.