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:
ve ana fonksiyonumuzda şöyle devam edelim:
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
Ş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
yukarıdaki kodlarda operator + ile başlayan kendi operatörümüzü yazmadığımızı o kısmı eklemediğimizi düşünürsek:
devam edelim
şimdi kodlarda epey değişikliğe gideceğiz mixin kullanımı with BankMixin yapacağız == operatörünü de yazdık
yanlarda açıklamalı şeyler yazdığım için kodları incelemeniz yeterli olacaktır. şimdi cascade notation diye bir şey var ona bakalım neymiş
bunu sınıfımıza ekledik şimdi ana fonksiyona dönelim cascade notation'a bakalım
şimdi class singleton kavramına bakalım öncelikle aşağıdaki kodları inceleyelim
şimdi devamına bakalım:
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
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ş
epey bir açıklamalı kod yazdım burada mevzular dönüyor ama karışık değil. şimdi biraz karışabilir mesela adam gidiyor
ana fonksiyonda da
şimdi sınıfı şöyle güncellersek
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
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
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