{"id":31358,"date":"2025-10-09T02:01:41","date_gmt":"2025-10-08T23:01:41","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/"},"modified":"2025-10-09T02:01:41","modified_gmt":"2025-10-08T23:01:41","slug":"dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/","title":{"rendered":"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)"},"content":{"rendered":"<p><body><\/p>\n<p>Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak s\u0131f\u0131rdan bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeye ne dersiniz? Bu rehber, Dart\u2019\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffederken, finansal takibinizi kolayla\u015ft\u0131racak pratik bir uygulama olu\u015fturman\u0131za yard\u0131mc\u0131 olacak. Ad\u0131m ad\u0131m ilerleyecek, temel OOP kavramlar\u0131ndan ba\u015flay\u0131p ileri seviye veri y\u00f6netimine kadar pek \u00e7ok konuya de\u011finece\u011fiz.<\/p>\n<p>Modern ya\u015fam\u0131n karma\u015f\u0131kl\u0131\u011f\u0131 i\u00e7inde, finansal durumumuzu kontrol alt\u0131nda tutmak hi\u00e7 bu kadar \u00f6nemli olmam\u0131\u015ft\u0131. Her ge\u00e7en g\u00fcn artan harcamalar, sabit kalan gelirler ve hayat pahal\u0131l\u0131\u011f\u0131, bireyleri ve aileleri b\u00fct\u00e7elerini daha dikkatli y\u00f6netmeye itiyor. Ancak, hangi harcamalar\u0131n ger\u00e7ekten gerekli oldu\u011funu, nereye ne kadar para harcad\u0131\u011f\u0131m\u0131z\u0131 net bir \u015fekilde g\u00f6rmek genellikle zordur. \u0130\u015fte tam da bu noktada bir gider y\u00f6neticisi uygulamas\u0131 devreye girer. Bir gider y\u00f6neticisi, finansal al\u0131\u015fkanl\u0131klar\u0131m\u0131z\u0131 \u015feffaf hale getirerek, para ak\u0131\u015f\u0131m\u0131z\u0131 anlamam\u0131za, gereksiz harcamalar\u0131 tespit etmemize ve uzun vadeli finansal hedeflerimize ula\u015fmam\u0131za yard\u0131mc\u0131 olan paha bi\u00e7ilmez bir ara\u00e7t\u0131r.<\/p>\n<p>Peki, b\u00f6yle bir uygulamay\u0131 Dart Nesne Y\u00f6nelimli Programlama (OOP) prensipleriyle geli\u015ftirmek neden bu kadar mant\u0131kl\u0131? Dart, \u00f6zellikle Flutter ile mobil ve web uygulamalar\u0131 geli\u015ftirmek i\u00e7in pop\u00fcler bir dil olmas\u0131na ra\u011fmen, temiz, okunabilir ve bak\u0131m\u0131 kolay kod yazmak i\u00e7in g\u00fc\u00e7l\u00fc OOP yetenekleri sunar. Bu, karma\u015f\u0131k finansal verileri d\u00fczenli s\u0131n\u0131flar ve nesneler halinde modellememize olanak tan\u0131r. \u00d6rne\u011fin, her bir gideri bir nesne olarak d\u00fc\u015f\u00fcnebiliriz; bu nesnenin bir miktar\u0131, bir tarihi, bir a\u00e7\u0131klamas\u0131 ve bir kategorisi olabilir. Bu sayede, finansal verileriniz sadece bir say\u0131 y\u0131\u011f\u0131n\u0131 olmaktan \u00e7\u0131kar, anlaml\u0131 ve y\u00f6netilebilir bilgi par\u00e7ac\u0131klar\u0131na d\u00f6n\u00fc\u015f\u00fcr. Uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e veya yeni \u00f6zellikler eklemek istedi\u011finizde (\u00f6rne\u011fin, b\u00fct\u00e7eleme, raporlama, farkl\u0131 para birimleri deste\u011fi), OOP&#8217;nin sa\u011flad\u0131\u011f\u0131 mod\u00fcler yap\u0131 sayesinde kodunuzu kolayca geni\u015fletebilir ve s\u00fcrd\u00fcrebilirsiniz. Bu ders serisinin dokuzuncu b\u00f6l\u00fcm\u00fc olarak, \u00f6nceki bilgilerinizin \u00fczerine in\u015fa ederek, daha sofistike ve kullan\u0131c\u0131 dostu bir gider y\u00f6neticisi olu\u015fturma yolunda \u00f6nemli ad\u0131mlar ataca\u011f\u0131z. Bu b\u00f6l\u00fcmde, uygulaman\u0131n temel mimarisini ve veri modellerini Dart OOP&#8217;nin g\u00fcc\u00fcn\u00fc kullanarak nas\u0131l olu\u015fturaca\u011f\u0131m\u0131z\u0131 derinlemesine inceleyece\u011fiz. Finansal \u00f6zerkli\u011finize giden yolda kodlaman\u0131n tad\u0131n\u0131 \u00e7\u0131kar\u0131n!<\/p>\n<h2>Dart&#8217;ta Nesne Y\u00f6nelimli Programlamaya H\u0131zl\u0131 Bir Bak\u0131\u015f: Temel \u0130lkeler Nelerdir?<\/h2>\n<p>Nesne Y\u00f6nelimli Programlama (OOP), yaz\u0131l\u0131m geli\u015ftirmede kullan\u0131lan g\u00fc\u00e7l\u00fc bir paradigmad\u0131r. Ger\u00e7ek d\u00fcnyadaki varl\u0131klar\u0131 yaz\u0131l\u0131m nesneleri olarak modellememizi sa\u011flar, b\u00f6ylece kodumuzu daha anla\u015f\u0131l\u0131r, esnek ve bak\u0131m\u0131 kolay hale getiririz. Dart da g\u00fc\u00e7l\u00fc bir OOP dilidir ve bu paradigman\u0131n temel ilkelerini tamamen destekler. Bir gider y\u00f6neticisi gibi finansal bir uygulamay\u0131 geli\u015ftirirken, bu ilkeler bize b\u00fcy\u00fck avantajlar sa\u011flar. Her bir harcaman\u0131n veya gelirin bir nesne olarak d\u00fc\u015f\u00fcn\u00fcld\u00fc\u011f\u00fc, kategorilere ayr\u0131ld\u0131\u011f\u0131 ve \u00fczerinde i\u015flemler yap\u0131ld\u0131\u011f\u0131 bir sistem hayal edin. \u0130\u015fte tam bu noktada OOP\u2019nin g\u00fcc\u00fc ortaya \u00e7\u0131kar.<\/p>\n<h3>S\u0131n\u0131flar ve Nesneler: Ger\u00e7ek D\u00fcnyay\u0131 Kodlamak Nas\u0131l M\u00fcmk\u00fcn?<\/h3>\n<p>OOP&#8217;nin temel yap\u0131 ta\u015flar\u0131 s\u0131n\u0131flar ve nesnelerdir. Bir <strong>s\u0131n\u0131f (Class)<\/strong>, belirli bir t\u00fcrdeki nesnelerin \u00f6zelliklerini (nitelikler\/alanlar) ve davran\u0131\u015flar\u0131n\u0131 (metotlar\/fonksiyonlar) tan\u0131mlayan bir taslak veya \u015fablondur. \u00d6rne\u011fin, bir &#8220;Gider&#8221; s\u0131n\u0131f\u0131, her giderin sahip olmas\u0131 gereken \u00f6zellikleri (miktar, a\u00e7\u0131klama, tarih, kategori) ve yapabilece\u011fi eylemleri (kaydetme, d\u00fczenleme, silme) tan\u0131mlayabilir. Bir <strong>nesne (Object)<\/strong> ise bu s\u0131n\u0131f\u0131n somut bir \u00f6rne\u011fidir. Yani, &#8220;Gider&#8221; s\u0131n\u0131f\u0131ndan t\u00fcretilmi\u015f bir nesne, belirli bir harcamay\u0131 (\u00f6rne\u011fin, &#8220;Market al\u0131\u015fveri\u015fi, 200 TL, 15 Mart 2023, G\u0131da&#8221; gibi) temsil eder. Bu ayr\u0131m, kodunuzu d\u00fczenli ve mod\u00fcler tutman\u0131n anahtar\u0131d\u0131r. Her nesne, kendi i\u00e7 durumunu korur ve bu durum \u00fczerinde tan\u0131mlanm\u0131\u015f metotlar arac\u0131l\u0131\u011f\u0131yla i\u015flem yapar.<\/p>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: S\u0131n\u0131f isimlerini her zaman b\u00fcy\u00fck harfle ba\u015flat\u0131n (PascalCase), nesne isimlerini ise k\u00fc\u00e7\u00fck harfle (camelCase). Bu, kod okunabilirli\u011fini art\u0131r\u0131r ve Dart toplulu\u011funun genel bir kabul\u00fcd\u00fcr.\n  <\/div>\n<p><strong>Kaps\u00fclleme (Encapsulation)<\/strong>, bir s\u0131n\u0131f\u0131n i\u00e7 detaylar\u0131n\u0131 d\u0131\u015f d\u00fcnyadan gizleme prensibidir. Bir nesnenin verilerine (alanlar\u0131na) do\u011frudan eri\u015fimi k\u0131s\u0131tlar ve bu verilere sadece o nesnenin kendi metotlar\u0131 arac\u0131l\u0131\u011f\u0131yla eri\u015filmesini sa\u011flar. Bu, veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc korur ve kodun beklenmedik \u015fekillerde de\u011fi\u015ftirilmesini \u00f6nler. Dart&#8217;ta bu, genellikle \u00f6zel (private) alanlar tan\u0131mlayarak ve bu alanlara eri\u015fim i\u00e7in getter\/setter metotlar\u0131 veya uygun aray\u00fczler sa\u011flayarak yap\u0131l\u0131r. Bir giderin miktar\u0131n\u0131 direkt olarak de\u011fi\u015ftirmek yerine, bir <code>gider.miktarGuncelle(yeniMiktar)<\/code> metodu kullanmak, hem verinin ge\u00e7erlili\u011fini kontrol etmenizi sa\u011flar hem de gelecekteki de\u011fi\u015fiklikleri kolayla\u015ft\u0131r\u0131r.<\/p>\n<h3>Kal\u0131t\u0131m ve Aray\u00fczler: Kod Tekrar\u0131n\u0131 Azaltman\u0131n Yollar\u0131 Nelerdir?<\/h3>\n<p><strong>Kal\u0131t\u0131m (Inheritance)<\/strong>, bir s\u0131n\u0131f\u0131n (alt s\u0131n\u0131f\/t\u00fcretilmi\u015f s\u0131n\u0131f) ba\u015fka bir s\u0131n\u0131f\u0131n (\u00fcst s\u0131n\u0131f\/temel s\u0131n\u0131f) \u00f6zelliklerini ve davran\u0131\u015flar\u0131n\u0131 miras almas\u0131n\u0131 sa\u011flayan bir OOP ilkesidir. Bu, kod tekrar\u0131n\u0131 azalt\u0131r ve hiyerar\u015fik bir yap\u0131 olu\u015fturarak kodun yeniden kullan\u0131labilirli\u011fini art\u0131r\u0131r. \u00d6rne\u011fin, bir genel &#8220;\u0130\u015flem&#8221; (Transaction) s\u0131n\u0131f\u0131n\u0131z olabilir ve hem &#8220;Gider&#8221; hem de &#8220;Gelir&#8221; s\u0131n\u0131flar\u0131 bu &#8220;\u0130\u015flem&#8221; s\u0131n\u0131f\u0131ndan miras alabilir. Bu sayede, tarih veya miktar gibi ortak \u00f6zellikleri her iki s\u0131n\u0131fta da tekrar tekrar tan\u0131mlamak yerine bir kez tan\u0131mlam\u0131\u015f olursunuz. Dart&#8217;ta kal\u0131t\u0131m <code>extends<\/code> anahtar kelimesiyle sa\u011flan\u0131r. B\u00f6ylece, ortak i\u015flevsellik tek bir yerde y\u00f6netilir ve t\u00fcm alt s\u0131n\u0131flar otomatik olarak bu i\u015flevsellikten faydalan\u0131r.<\/p>\n<p><strong>\u00c7ok Bi\u00e7imlilik (Polymorphism)<\/strong>, farkl\u0131 s\u0131n\u0131flara ait nesnelerin ayn\u0131 aray\u00fcz \u00fczerinden i\u015flenebilmesi yetene\u011fidir. Yani, bir temel s\u0131n\u0131f t\u00fcr\u00fcnden bir referans, o temel s\u0131n\u0131ftan t\u00fcretilmi\u015f farkl\u0131 alt s\u0131n\u0131f nesnelerini i\u015faret edebilir. Bu, esnek ve geni\u015fletilebilir kod yazman\u0131za olanak tan\u0131r. Gider y\u00f6neticisi \u00f6rne\u011finde, bir <code>List<Islem><\/code> i\u00e7inde hem <code>Gider<\/code> hem de <code>Gelir<\/code> nesnelerini tutabilir ve her birini ayn\u0131 \u015fekilde i\u015fleyebilirsiniz.<\/p>\n<p><strong>Soyutlama (Abstraction)<\/strong>, sadece gerekli bilgileri g\u00f6sterip, gereksiz detaylar\u0131 gizleme prensibidir. Dart&#8217;ta soyut s\u0131n\u0131flar (<code>abstract class<\/code>) ve aray\u00fczler (<code>implements<\/code> anahtar kelimesiyle belirtilen normal s\u0131n\u0131flar veya <code>abstract class<\/code>&#8216;lar) kullan\u0131larak uygulan\u0131r. Bir soyut s\u0131n\u0131f, di\u011fer s\u0131n\u0131flar\u0131n miras alabilece\u011fi ve belirli metotlar\u0131 uygulamak zorunda kalaca\u011f\u0131 bir \u015fablon sunar. Bu, farkl\u0131 veri depolama mekanizmalar\u0131n\u0131 (\u00f6rne\u011fin, yerel depolama, bulut depolama) tek bir <code>VeriDepolayici<\/code> aray\u00fcz\u00fc alt\u0131nda toplayarak kodunuzu daha esnek hale getirebilir. Her bir depolama t\u00fcr\u00fc, bu aray\u00fcz\u00fc uygulayarak kendi kaydetme ve y\u00fckleme mant\u0131\u011f\u0131n\u0131 i\u00e7erebilir. Bu sayede, uygulaman\u0131z\u0131n temel veri y\u00f6netimi mant\u0131\u011f\u0131n\u0131 de\u011fi\u015ftirmeden farkl\u0131 depolama \u00e7\u00f6z\u00fcmleri aras\u0131nda ge\u00e7i\u015f yapabilirsiniz. Bu OOP prensipleri, gider y\u00f6neticisi uygulamam\u0131z\u0131n sa\u011flam ve s\u00fcrd\u00fcr\u00fclebilir bir temele sahip olmas\u0131n\u0131 sa\u011flayacakt\u0131r.<\/p>\n<h2>Gider Y\u00f6neticisi Uygulamas\u0131nda Temel Modelleri Olu\u015fturmak: Hangi S\u0131n\u0131flara \u0130htiyac\u0131m\u0131z Var?<\/h2>\n<p>Bir gider y\u00f6neticisi uygulamas\u0131n\u0131n kalbi, harcamalar\u0131 ve ilgili verileri nas\u0131l modeledi\u011fimizdir. Dart&#8217;\u0131n Nesne Y\u00f6nelimli Programlama (OOP) yetenekleri sayesinde, ger\u00e7ek d\u00fcnyadaki kavramlar\u0131 (giderler, kategoriler vb.) kodumuzda anlaml\u0131 s\u0131n\u0131flara d\u00f6n\u00fc\u015ft\u00fcrebiliriz. Bu, hem kodun okunabilirli\u011fini art\u0131r\u0131r hem de gelecekteki de\u011fi\u015fiklikleri ve geni\u015fletmeleri \u00e7ok daha kolay hale getirir. Uygulamam\u0131z i\u00e7in ilk olarak temel veri modellerini tasarlamam\u0131z gerekiyor. Genellikle, bir giderin kendisi ve ait oldu\u011fu kategori gibi ana bile\u015fenler \u00f6ne \u00e7\u0131kar.<\/p>\n<h3><code>Gider<\/code> S\u0131n\u0131f\u0131 Tasar\u0131m\u0131: Bir Gideri Neler Tan\u0131mlar?<\/h3>\n<p>Her bir gideri temsil edecek bir <code>Gider<\/code> s\u0131n\u0131f\u0131, uygulamam\u0131z\u0131n en merkezi par\u00e7alar\u0131ndan biridir. Bir gideri benzersiz k\u0131lan ve anlaml\u0131 k\u0131lan \u00f6zellikleri d\u00fc\u015f\u00fcnelim: miktar\u0131, ne zaman yap\u0131ld\u0131\u011f\u0131, ne i\u00e7in yap\u0131ld\u0131\u011f\u0131 (a\u00e7\u0131klama) ve hangi kategoriye ait oldu\u011fu. Bu \u00f6zellikler, <code>Gider<\/code> s\u0131n\u0131f\u0131m\u0131z\u0131n alanlar\u0131n\u0131 (properties) olu\u015fturacakt\u0131r.<\/p>\n<p>\u0130\u015fte <code>Gider<\/code> s\u0131n\u0131f\u0131n\u0131n Dart&#8217;taki temel yap\u0131s\u0131:<\/p>\n<pre><code>\n    import 'package:uuid\/uuid.dart'; \/\/ Benzersiz ID'ler i\u00e7in\n    import 'package:intl\/intl.dart'; \/\/ Tarih formatlama i\u00e7in\n\n    class Gider {\n      final String id;\n      final double miktar;\n      final String aciklama;\n      final DateTime tarih;\n      final String kategori; \/\/ \u015eimdilik basit bir string olarak tutal\u0131m\n\n      Gider({\n        String? id,\n        required this.miktar,\n        required this.aciklama,\n        required this.tarih,\n        required this.kategori,\n      }) : id = id ?? const Uuid().v4(); \/\/ E\u011fer ID verilmezse yeni bir ID olu\u015ftur.\n\n      \/\/ Gider nesnesini kolayca yazd\u0131rmak i\u00e7in toString metodu\n      @override\n      String toString() {\n        final dateFormat = DateFormat('dd\/MM\/yyyy');\n        return 'ID: $id, Miktar: ${miktar.toStringAsFixed(2)} TL, A\u00e7\u0131klama: $aciklama, Tarih: ${dateFormat.format(tarih)}, Kategori: $kategori';\n      }\n\n      \/\/ Gider nesnesini JSON format\u0131na d\u00f6n\u00fc\u015ft\u00fcrme\n      Map<String, dynamic> toJson() {\n        return {\n          'id': id,\n          'miktar': miktar,\n          'aciklama': aciklama,\n          'tarih': tarih.toIso8601String(), \/\/ ISO 8601 format\u0131nda tarih saklama\n          'kategori': kategori,\n        };\n      }\n\n      \/\/ JSON'dan Gider nesnesi olu\u015fturma\n      factory Gider.fromJson(Map<String, dynamic> json) {\n        return Gider(\n          id: json['id'] as String,\n          miktar: json['miktar'] as double,\n          aciklama: json['aciklama'] as String,\n          tarih: DateTime.parse(json['tarih'] as String),\n          kategori: json['kategori'] as String,\n        );\n      }\n    }\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu <code>Gider<\/code> s\u0131n\u0131f\u0131nda \u015funlar\u0131 g\u00f6r\u00fcyoruz:<\/p>\n<ul>\n<li><code>id<\/code>: Her gideri benzersiz \u015fekilde tan\u0131mlamak i\u00e7in bir ID kullan\u0131yoruz. Bu, daha sonra bir gideri kolayca bulmam\u0131z\u0131, g\u00fcncellememizi veya silmemizi sa\u011flar. <code>uuid<\/code> paketi, bu t\u00fcr benzersiz ID'leri \u00fcretmek i\u00e7in kullan\u0131\u015fl\u0131d\u0131r.<\/li>\n<li><code>miktar<\/code>: Giderin say\u0131sal de\u011ferini temsil eder (\u00f6rne\u011fin, <code>double<\/code>).<\/li>\n<li><code>aciklama<\/code>: Giderin ne ile ilgili oldu\u011funu anlatan k\u0131sa bir metin (\u00f6rne\u011fin, <code>String<\/code>).<\/li>\n<li><code>tarih<\/code>: Giderin ne zaman yap\u0131ld\u0131\u011f\u0131n\u0131 belirten bir <code>DateTime<\/code> nesnesi.<\/li>\n<li><code>kategori<\/code>: Giderin hangi kategoriye ait oldu\u011funu g\u00f6steren bir <code>String<\/code>. \u0130lerleyen b\u00f6l\u00fcmlerde bunu daha sofistike bir <code>Kategori<\/code> nesnesine d\u00f6n\u00fc\u015ft\u00fcrebiliriz.<\/li>\n<\/ul>\n<p>Ayr\u0131ca, nesneleri daha okunabilir hale getirmek i\u00e7in bir <code>toString()<\/code> metodu ve verileri depolamak i\u00e7in gerekli olan <code>toJson()<\/code> ve <code>fromJson()<\/code> metotlar\u0131n\u0131 ekledik. Bu metotlar, <code>Gider<\/code> nesnelerini JSON format\u0131na d\u00f6n\u00fc\u015ft\u00fcrmeyi ve JSON'dan yeniden olu\u015fturmay\u0131 sa\u011flayarak, verilerimizi kal\u0131c\u0131 hale getirmemizde kilit rol oynayacaklard\u0131r.<\/p>\n<h3><code>Kategori<\/code> S\u0131n\u0131f\u0131 ve \u0130li\u015fkisel Yap\u0131lar: Giderleri Gruplamak Neden \u00d6nemli?<\/h3>\n<p>Giderleri sadece miktar\u0131 ve a\u00e7\u0131klamas\u0131yla takip etmek yeterli de\u011fildir. Genellikle, harcamalar\u0131m\u0131z\u0131 belirli gruplara ay\u0131rarak b\u00fct\u00e7e takibi ve analiz yapmak isteriz. \u00d6rne\u011fin, \"Yiyecek\", \"Ula\u015f\u0131m\", \"E\u011flence\", \"Fatura\" gibi kategoriler, finansal al\u0131\u015fkanl\u0131klar\u0131m\u0131z\u0131 daha iyi anlamam\u0131z\u0131 sa\u011flar. Bu nedenle, bir <code>Kategori<\/code> s\u0131n\u0131f\u0131 tan\u0131mlamak da uygulamam\u0131z i\u00e7in olduk\u00e7a \u00f6nemlidir.<\/p>\n<p><code>Kategori<\/code> s\u0131n\u0131f\u0131n\u0131n temel yap\u0131s\u0131 \u015fu \u015fekilde olabilir:<\/p>\n<pre><code>\n    import 'package:uuid\/uuid.dart';\n\n    class Kategori {\n      final String id;\n      final String ad;\n      final double? butceLimiti; \/\/ Her kategoriye \u00f6zel bir b\u00fct\u00e7e limiti olabilir\n\n      Kategori({\n        String? id,\n        required this.ad,\n        this.butceLimiti,\n      }) : id = id ?? const Uuid().v4();\n\n      @override\n      String toString() {\n        return 'ID: $id, Ad: $ad, B\u00fct\u00e7e Limiti: ${butceLimiti != null ? butceLimiti.toStringAsFixed(2) + ' TL' : 'Yok'}';\n      }\n\n      \/\/ Kategori nesnesini JSON format\u0131na d\u00f6n\u00fc\u015ft\u00fcrme\n      Map<String, dynamic> toJson() {\n        return {\n          'id': id,\n          'ad': ad,\n          'butceLimiti': butceLimiti,\n        };\n      }\n\n      \/\/ JSON'dan Kategori nesnesi olu\u015fturma\n      factory Kategori.fromJson(Map<String, dynamic> json) {\n        return Kategori(\n          id: json['id'] as String,\n          ad: json['ad'] as String,\n          butceLimiti: json['butceLimiti'] as double?,\n        );\n      }\n    }\n  <\/pre>\n<p><\/code><\/p>\n<p>Burada <code>Kategori<\/code> s\u0131n\u0131f\u0131 \u015funlar\u0131 i\u00e7erir:<\/p>\n<ul>\n<li><code>id<\/code>: Her kategoriyi benzersiz \u015fekilde tan\u0131mlamak i\u00e7in.<\/li>\n<li><code>ad<\/code>: Kategorinin ad\u0131 (\u00f6rne\u011fin, \"G\u0131da\", \"Ula\u015f\u0131m\").<\/li>\n<li><code>butceLimiti<\/code>: Bu kategori i\u00e7in belirlenen opsiyonel bir b\u00fct\u00e7e limiti. Bu, kullan\u0131c\u0131lar\u0131n belirli harcama alanlar\u0131nda kendilerini s\u0131n\u0131rlamalar\u0131na yard\u0131mc\u0131 olabilir.<\/li>\n<\/ul>\n<p>\u015eu anda <code>Gider<\/code> s\u0131n\u0131f\u0131ndaki <code>kategori<\/code> alan\u0131n\u0131 basit bir <code>String<\/code> olarak tuttuk. Ancak, ger\u00e7ek bir uygulamada, <code>Gider<\/code> s\u0131n\u0131f\u0131n\u0131n <code>Kategori<\/code> s\u0131n\u0131f\u0131ndan bir nesneye referans vermesi daha iyi bir ili\u015fkisel modelleme olacakt\u0131r. Bu, kategorilerin y\u00f6netilmesini (ekleme, d\u00fczenleme, silme) ve giderlerle tutarl\u0131 bir \u015fekilde ili\u015fkilendirilmesini kolayla\u015ft\u0131r\u0131r. \u00d6rne\u011fin:<\/p>\n<pre><code>\n    \/\/ Gider s\u0131n\u0131f\u0131n\u0131 g\u00fcncelleyelim\n    \/\/ import 'package:uuid\/uuid.dart';\n    \/\/ import 'package:intl\/intl.dart';\n\n    \/\/ class Gider {\n    \/\/   final String id;\n    \/\/   final double miktar;\n    \/\/   final String aciklama;\n    \/\/   final DateTime tarih;\n    \/\/   final Kategori kategori; \/\/ Kategori nesnesine referans\n\n    \/\/   Gider({\n    \/\/     String? id,\n    \/\/     required this.miktar,\n    \/\/     required this.aciklama,\n    \/\/     required this.tarih,\n    \/\/     required this.kategori,\n    \/\/   }) : id = id ?? const Uuid().v4();\n\n    \/\/   @override\n    \/\/   String toString() {\n    \/\/     final dateFormat = DateFormat('dd\/MM\/yyyy');\n    \/\/     return 'ID: $id, Miktar: ${miktar.toStringAsFixed(2)} TL, A\u00e7\u0131klama: $aciklama, Tarih: ${dateFormat.format(tarih)}, Kategori: ${kategori.ad}';\n    \/\/   }\n\n    \/\/   \/\/ toJson ve fromJson metodlar\u0131 da Kategori nesnesini i\u00e7erecek \u015fekilde g\u00fcncellenmeli\n    \/\/   Map<String, dynamic> toJson() {\n    \/\/     return {\n    \/\/       'id': id,\n    \/\/       'miktar': miktar,\n    \/\/       'aciklama': aciklama,\n    \/\/       'tarih': tarih.toIso8601String(),\n    \/\/       'kategori': kategori.toJson(), \/\/ Kategori nesnesini de JSON'a d\u00f6n\u00fc\u015ft\u00fcr\n    \/\/     };\n    \/\/   }\n\n    \/\/   factory Gider.fromJson(Map<String, dynamic> json) {\n    \/\/     return Gider(\n    \/\/       id: json['id'] as String,\n    \/\/       miktar: json['miktar'] as double,\n    \/\/       aciklama: json['aciklama'] as String,\n    \/\/       tarih: DateTime.parse(json['tarih'] as String),\n    \/\/       kategori: Kategori.fromJson(json['kategori'] as Map<String, dynamic>), \/\/ JSON'dan Kategori olu\u015ftur\n    \/\/     );\n    \/\/   }\n    \/\/ }\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu \u015fekilde, <code>Gider<\/code> ve <code>Kategori<\/code> s\u0131n\u0131flar\u0131 aras\u0131nda daha g\u00fc\u00e7l\u00fc ve anlaml\u0131 bir ili\u015fki kurmu\u015f oluruz. Bu yap\u0131, hem veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc sa\u011flar hem de uygulama i\u00e7inde verilerle \u00e7al\u0131\u015fmay\u0131 \u00e7ok daha tutarl\u0131 hale getirir. \u00d6rne\u011fin, bir kategorinin ad\u0131n\u0131 de\u011fi\u015ftirdi\u011finizde, o kategoriye ait t\u00fcm giderlerin de otomatik olarak yeni kategori ad\u0131na sahip olmas\u0131n\u0131 sa\u011flamak daha kolayla\u015f\u0131r. Bu modelleme, uygulamam\u0131z\u0131n temelini olu\u015fturacak ve Dart OOP'nin g\u00fcc\u00fcn\u00fc en iyi \u015fekilde kullanmam\u0131z\u0131 sa\u011flayacakt\u0131r.<\/p>\n<h2>Veri Y\u00f6netimi ve Kal\u0131c\u0131l\u0131k: Gider Bilgilerini Nas\u0131l Saklar\u0131z?<\/h2>\n<p>Uygulamam\u0131z\u0131n en kritik ihtiya\u00e7lar\u0131ndan biri, kullan\u0131c\u0131lar\u0131n girdi\u011fi gider bilgilerini kal\u0131c\u0131 olarak saklayabilmektir. Kullan\u0131c\u0131 uygulamay\u0131 kapatt\u0131\u011f\u0131nda t\u00fcm verilerin kaybolmas\u0131, bir gider y\u00f6neticisi i\u00e7in kabul edilemez bir durumdur. Bu nedenle, verilerimizi bir dosyaya (veya daha geli\u015fmi\u015f sistemlerde bir veritaban\u0131na) yazma ve oradan okuma mekanizmalar\u0131 olu\u015fturmam\u0131z gerekir. Bu b\u00f6l\u00fcmde, Dart'\u0131n dosya okuma\/yazma yeteneklerini ve nesnelerimizi veri format\u0131na d\u00f6n\u00fc\u015ft\u00fcrmek i\u00e7in JSON'\u0131 nas\u0131l kullanaca\u011f\u0131m\u0131z\u0131 inceleyece\u011fiz. Bu sayede, uygulaman\u0131z her a\u00e7\u0131ld\u0131\u011f\u0131nda kald\u0131\u011f\u0131n\u0131z yerden devam edebilecek, t\u00fcm giderleriniz ve kategorileriniz g\u00fcvenle saklanabilecektir.<\/p>\n<h3>Giderleri JSON Format\u0131nda Saklamak: Neden ve Nas\u0131l?<\/h3>\n<p>JSON (JavaScript Object Notation), hafif, okunabilir ve veri al\u0131\u015fveri\u015fi i\u00e7in yayg\u0131n olarak kullan\u0131lan bir formatt\u0131r. Nesne y\u00f6nelimli programlamadaki nesneleri temsil etmek i\u00e7in do\u011fal bir yap\u0131s\u0131 vard\u0131r ve Dart'ta nesneleri JSON'a d\u00f6n\u00fc\u015ft\u00fcrmek (serile\u015ftirme) ve JSON'dan nesneye d\u00f6n\u00fc\u015ft\u00fcrmek (deserile\u015ftirme) olduk\u00e7a kolayd\u0131r. JSON kullanmak, verilerinizi insanlar taraf\u0131ndan okunabilir bir formatta saklaman\u0131z\u0131 sa\u011flar ve gelecekte farkl\u0131 platformlarla (web aray\u00fczleri, di\u011fer uygulamalar, API'ler) veri al\u0131\u015fveri\u015fi yapman\u0131z gerekti\u011finde b\u00fcy\u00fck esneklik sunar. Dart'\u0131n <code>dart:convert<\/code> k\u00fct\u00fcphanesi, bu i\u015flemleri yapmak i\u00e7in g\u00fc\u00e7l\u00fc ara\u00e7lar sa\u011flar.<\/p>\n<p>\u00d6ncelikle, t\u00fcm giderlerimizi ve kategorilerimizi y\u00f6neten bir s\u0131n\u0131f olu\u015ftural\u0131m. Bu s\u0131n\u0131f, verileri bellekte tutacak ve bunlar\u0131 diske kaydetme\/y\u00fckleme i\u015flemlerini y\u00f6netecek. A\u015fa\u011f\u0131daki \u00f6rnekte, temel bir <code>GiderYonetici<\/code> s\u0131n\u0131f\u0131 ve dosya i\u015flemlerini g\u00f6receksiniz:<\/p>\n<pre><code>\n    import 'dart:convert'; \/\/ JSON i\u015flemleri i\u00e7in\n    import 'dart:io';    \/\/ Dosya i\u015flemleri i\u00e7in\n    import 'package:path_provider\/path_provider.dart'; \/\/ Uygulama dizini i\u00e7in (Flutter\/mobil)\n    import 'package:uuid\/uuid.dart';\n    import 'package:intl\/intl.dart';\n\n    \/\/ Yukar\u0131daki Gider ve Kategori s\u0131n\u0131flar\u0131n\u0131 buraya ekledi\u011finizi varsayal\u0131m\n\n    class GiderYonetici {\n      List<Gider> _giderler = [];\n      List<Kategori> _kategoriler = [];\n      static const String _giderDosyasi = 'giderler.json';\n      static const String _kategoriDosyasi = 'kategoriler.json';\n\n      \/\/ Getter'lar\n      List<Gider> get giderler => [..._giderler]; \/\/ De\u011fi\u015ftirilemez bir kopya d\u00f6nd\u00fcr\n      List<Kategori> get kategoriler => [..._kategoriler];\n\n      GiderYonetici() {\n        _kategoriler = [ \/\/ Varsay\u0131lan kategoriler\n          Kategori(ad: 'G\u0131da'),\n          Kategori(ad: 'Ula\u015f\u0131m'),\n          Kategori(ad: 'E\u011flence'),\n          Kategori(ad: 'Fatura'),\n          Kategori(ad: 'Giyim'),\n        ];\n      }\n\n      \/\/ Dosya yolunu bulma (uygulaman\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131 ortama g\u00f6re de\u011fi\u015febilir)\n      Future<String> _getLocalPath() async {\n        \/\/ Bu \u00f6rnek bir Flutter uygulamas\u0131 i\u00e7in path_provider kullan\u0131r.\n        \/\/ Konsol uygulamas\u0131 i\u00e7in '.\/' veya spesifik bir dizin kullanabilirsiniz.\n        final directory = await getApplicationDocumentsDirectory();\n        return directory.path;\n      }\n\n      \/\/ Verileri dosyaya kaydetme\n      Future<void> verileriKaydet() async {\n        try {\n          final path = await _getLocalPath();\n          final giderDosyasi = File('$path\/$_giderDosyasi');\n          final kategoriDosyasi = File('$path\/$_kategoriDosyasi');\n\n          \/\/ Giderleri JSON format\u0131na d\u00f6n\u00fc\u015ft\u00fcr ve kaydet\n          final giderlerJson = jsonEncode(_giderler.map((g) => g.toJson()).toList());\n          await giderDosyasi.writeAsString(giderlerJson);\n\n          \/\/ Kategorileri JSON format\u0131na d\u00f6n\u00fc\u015ft\u00fcr ve kaydet\n          final kategorilerJson = jsonEncode(_kategoriler.map((k) => k.toJson()).toList());\n          await kategoriDosyasi.writeAsString(kategorilerJson);\n          print('Veriler ba\u015far\u0131yla kaydedildi.');\n        } catch (e) {\n          print('Verileri kaydederken hata olu\u015ftu: $e');\n        }\n      }\n\n      \/\/ Verileri dosyadan y\u00fckleme\n      Future<void> verileriYukle() async {\n        try {\n          final path = await _getLocalPath();\n          final giderDosyasi = File('$path\/$_giderDosyasi');\n          final kategoriDosyasi = File('$path\/$_kategoriDosyasi');\n\n          \/\/ Giderleri y\u00fckle\n          if (await giderDosyasi.exists()) {\n            final giderlerString = await giderDosyasi.readAsString();\n            final List<dynamic> decodedGiderler = jsonDecode(giderlerString);\n            _giderler = decodedGiderler.map((json) => Gider.fromJson(json as Map<String, dynamic>)).toList();\n          }\n\n          \/\/ Kategorileri y\u00fckle\n          if (await kategoriDosyasi.exists()) {\n            final kategorilerString = await kategoriDosyasi.readAsString();\n            final List<dynamic> decodedKategoriler = jsonDecode(kategorilerString);\n            _kategoriler = decodedKategoriler.map((json) => Kategori.fromJson(json as Map<String, dynamic>)).toList();\n          }\n          print('Veriler ba\u015far\u0131yla y\u00fcklendi.');\n        } catch (e) {\n          print('Verileri y\u00fcklerken hata olu\u015ftu: $e');\n        }\n      }\n\n      \/\/ Gider ekleme\n      void giderEkle(Gider gider) {\n        _giderler.add(gider);\n        print('Gider eklendi: $gider');\n      }\n\n      \/\/ Kategori ekleme\n      void kategoriEkle(Kategori kategori) {\n        if (!_kategoriler.any((k) => k.ad.toLowerCase() == kategori.ad.toLowerCase())) {\n          _kategoriler.add(kategori);\n          print('Kategori eklendi: $kategori');\n        } else {\n          print('Bu kategori zaten mevcut.');\n        }\n      }\n\n      \/\/ Belirli bir kategoriye ait giderleri filtreleme\n      List<Gider> giderleriFiltrele(String kategoriAdi) {\n        return _giderler.where((g) => g.kategori.toLowerCase() == kategoriAdi.toLowerCase()).toList();\n      }\n\n      \/\/ Gider silme (ID ile)\n      bool giderSil(String id) {\n        final initialLength = _giderler.length;\n        _giderler.removeWhere((g) => g.id == id);\n        return _giderler.length < initialLength;\n      }\n    }\n  <\/pre>\n<p><\/code><\/p>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: <code>path_provider<\/code> paketi genellikle Flutter uygulamalar\u0131nda dosya yollar\u0131n\u0131 y\u00f6netmek i\u00e7in kullan\u0131l\u0131r. Konsol tabanl\u0131 bir Dart uygulamas\u0131 i\u00e7in, <code>Directory.current.path<\/code> kullanarak uygulaman\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131 dizine eri\u015febilirsiniz. Bu, uygulamalar\u0131n farkl\u0131 ortamlarda sorunsuz \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flamak i\u00e7in \u00f6nemlidir.\n  <\/div>\n<p>Yukar\u0131daki kodda:<\/p>\n<ul>\n<li><code>_getLocalPath()<\/code>: Verileri saklayaca\u011f\u0131m\u0131z dizinin yolunu belirler. Mobil uygulamalar i\u00e7in <code>path_provider<\/code> paketi kullan\u0131l\u0131rken, masa\u00fcst\u00fc veya konsol uygulamalar\u0131 i\u00e7in farkl\u0131 yakla\u015f\u0131mlar gerekebilir.<\/li>\n<li><code>verileriKaydet()<\/code>: <code>_giderler<\/code> ve <code>_kategoriler<\/code> listelerindeki her bir nesneyi <code>toJson()<\/code> metoduyla JSON'a d\u00f6n\u00fc\u015ft\u00fcr\u00fcr, ard\u0131ndan t\u00fcm bu JSON nesnelerini bir listeye al\u0131p <code>jsonEncode<\/code> ile tek bir JSON string'ine \u00e7evirir ve bir dosyaya yazar.<\/li>\n<li><code>verileriYukle()<\/code>: Dosyadan JSON string'ini okur, <code>jsonDecode<\/code> ile Dart nesnelerine (<code>List<dynamic><\/code>) \u00e7evirir ve her birini <code>Gider.fromJson()<\/code> veya <code>Kategori.fromJson()<\/code> metotlar\u0131 ile kendi s\u0131n\u0131f nesnelerine d\u00f6n\u00fc\u015ft\u00fcrerek listelere ekler.<\/li>\n<li><code>try-catch<\/code> bloklar\u0131, dosya okuma\/yazma s\u0131ras\u0131nda olu\u015fabilecek hatalar\u0131 y\u00f6netmek i\u00e7in kullan\u0131l\u0131r, b\u00f6ylece uygulama beklenmedik bir \u015fekilde \u00e7\u00f6kmez.<\/li>\n<\/ul>\n<p>Bu yap\u0131 sayesinde, gider y\u00f6neticisi uygulamam\u0131z kullan\u0131c\u0131lar\u0131n verilerini g\u00fcvenle saklayabilir ve her a\u00e7\u0131l\u0131\u015fta bu verilere eri\u015febilir. Bu, uygulaman\u0131n temel i\u015flevselli\u011fi i\u00e7in vazge\u00e7ilmez bir ad\u0131md\u0131r ve kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r. Ayr\u0131ca, JSON format\u0131 sayesinde verilerin ta\u015f\u0131nabilirli\u011fi ve di\u011fer sistemlerle entegrasyonu da olduk\u00e7a kolayla\u015f\u0131r. Bu model, Dart OOP'nin nesne modelleme ve serile\u015ftirme g\u00fcc\u00fcn\u00fc bir araya getirerek, sa\u011flam bir veri y\u00f6netim katman\u0131 olu\u015fturman\u0131n pratik bir \u00f6rne\u011fidir.<\/p>\n<h2>Uygulamay\u0131 Geli\u015ftirme ve Geni\u015fletme: \u0130leri Seviye \u00d6zellikler Eklemek Nas\u0131l M\u00fcmk\u00fcn?<\/h2>\n<p>Temel <code>Gider<\/code> ve <code>Kategori<\/code> s\u0131n\u0131flar\u0131m\u0131z\u0131 olu\u015fturup verileri kaydetme ve y\u00fckleme mekanizmalar\u0131n\u0131 kurduktan sonra, uygulamam\u0131z\u0131 daha kullan\u0131\u015fl\u0131 hale getirecek ileri seviye \u00f6zellikler eklemeye ba\u015flayabiliriz. Bu a\u015famada, Nesne Y\u00f6nelimli Programlaman\u0131n (OOP) bize sundu\u011fu esneklik ve geni\u015fletilebilirlik prensiplerini daha derinlemesine kullanaca\u011f\u0131z. Uygulamam\u0131za raporlama, filtreleme, g\u00fcncelleme gibi i\u015flevler eklemek, kullan\u0131c\u0131 deneyimini zenginle\u015ftirirken, kodumuzun mod\u00fcler yap\u0131s\u0131n\u0131 korumam\u0131z\u0131 sa\u011flayacakt\u0131r.<\/p>\n<h3>Farkl\u0131 Raporlama Y\u00f6ntemleri ve Veri Analizi: Giderlerden Anlam \u00c7\u0131karmak<\/h3>\n<p>Bir gider y\u00f6neticisinin en de\u011ferli \u00f6zelliklerinden biri, kullan\u0131c\u0131n\u0131n harcama al\u0131\u015fkanl\u0131klar\u0131n\u0131 analiz edebilmesi ve anlaml\u0131 raporlar sunabilmesidir. Kullan\u0131c\u0131lar, belirli bir d\u00f6nemdeki toplam harcamalar\u0131n\u0131, en \u00e7ok para harcad\u0131klar\u0131 kategorileri veya ayl\u0131k b\u00fct\u00e7e limitlerine ne kadar yakla\u015ft\u0131klar\u0131n\u0131 g\u00f6rmek isteyebilirler. Bu t\u00fcr raporlama i\u015flevlerini, <code>GiderYonetici<\/code> s\u0131n\u0131f\u0131m\u0131za metotlar ekleyerek veya daha ileri giderek, \u00c7ok Bi\u00e7imlilik (Polymorphism) kullanarak farkl\u0131 raporlama stratejileri olu\u015fturarak geli\u015ftirebiliriz.<\/p>\n<p>\u0130lk olarak, <code>GiderYonetici<\/code> s\u0131n\u0131f\u0131m\u0131za baz\u0131 temel analiz metotlar\u0131 ekleyelim:<\/p>\n<pre><code>\n    \/\/ GiderYonetici s\u0131n\u0131f\u0131n\u0131n devam\u0131...\n    class GiderYonetici {\n      \/\/ ... (\u00f6nceki alanlar ve metotlar) ...\n\n      \/\/ Belirli bir kategoriye ait toplam gideri hesaplama\n      double kategoriyeGoreToplamGider(String kategoriAdi) {\n        return _giderler\n            .where((g) => g.kategori.toLowerCase() == kategoriAdi.toLowerCase())\n            .fold(0.0, (toplam, gider) => toplam + gider.miktar);\n      }\n\n      \/\/ Belirli bir tarih aral\u0131\u011f\u0131ndaki toplam gideri hesaplama\n      double tarihAraligiToplamGider(DateTime baslangic, DateTime bitis) {\n        return _giderler\n            .where((g) => g.tarih.isAfter(baslang.subtract(Duration(days: 1))) && g.tarih.isBefore(bitis.add(Duration(days: 1))))\n            .fold(0.0, (toplam, gider) => toplam + gider.miktar);\n      }\n\n      \/\/ En \u00e7ok harcama yap\u0131lan kategorileri bulma (basit bir \u00f6rnek)\n      Map<String, double> enCokHarcamaYapilanKategoriler() {\n        final Map<String, double> kategoriHarcamalari = {};\n        for (var gider in _giderler) {\n          kategoriHarcamalari.update(gider.kategori, (value) => value + gider.miktar, ifAbsent: () => gider.miktar);\n        }\n        \/\/ Harcamas\u0131 en y\u00fcksek olan\u0131 \u00fcste al\n        var sortedList = kategoriHarcamalari.entries.toList()\n          ..sort((e1, e2) => e2.value.compareTo(e1.value));\n        return Map.fromEntries(sortedList);\n      }\n\n      \/\/ Gider g\u00fcncelleme (ID ile)\n      bool giderGuncelle(String id, {double? miktar, String? aciklama, DateTime? tarih, String? kategori}) {\n        final index = _giderler.indexWhere((g) => g.id == id);\n        if (index != -1) {\n          final existingGider = _giderler[index];\n          _giderler[index] = Gider(\n            id: existingGider.id,\n            miktar: miktar ?? existingGider.miktar,\n            aciklama: aciklama ?? existingGider.aciklama,\n            tarih: tarih ?? existingGider.tarih,\n            kategori: kategori ?? existingGider.kategori,\n          );\n          print('Gider g\u00fcncellendi: ${_giderler[index]}');\n          return true;\n        }\n        return false;\n      }\n    }\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu metotlar, kullan\u0131c\u0131lar\u0131n genel harcama e\u011filimlerini anlamalar\u0131na yard\u0131mc\u0131 olacak temel raporlar sunar. Ancak, daha karma\u015f\u0131k raporlar (\u00f6rne\u011fin, ayl\u0131k b\u00fct\u00e7e takibi, gider grafikleri) i\u00e7in daha soyut bir yakla\u015f\u0131m benimseyebiliriz. Bu, Soyutlama (Abstraction) ve \u00c7ok Bi\u00e7imlilik (Polymorphism) ilkelerinin g\u00fcc\u00fcn\u00fc g\u00f6sterir.<\/p>\n<p>Farkl\u0131 raporlama t\u00fcrleri i\u00e7in bir aray\u00fcz (veya soyut s\u0131n\u0131f) tan\u0131mlayabiliriz:<\/p>\n<pre><code>\n    \/\/ Raporlama Stratejisi Aray\u00fcz\u00fc\n    abstract class RaporlamaStratejisi {\n      String raporUret(List<Gider> giderler);\n    }\n\n    \/\/ Ayl\u0131k \u00d6zeti Raporu\n    class AylikOzetRaporu implements RaporlamaStratejisi {\n      @override\n      String raporUret(List<Gider> giderler) {\n        final Map<String, double> aylikToplamlar = {};\n        for (var gider in giderler) {\n          final ayYil = DateFormat('MM\/yyyy').format(gider.tarih);\n          aylikToplamlar.update(ayYil, (value) => value + gider.miktar, ifAbsent: () => gider.miktar);\n        }\n\n        StringBuffer rapor = StringBuffer('--- Ayl\u0131k Gider \u00d6zeti ---\\n');\n        aylikToplamlar.forEach((ayYil, toplam) {\n          rapor.writeln('$ayYil: ${toplam.toStringAsFixed(2)} TL');\n        });\n        return rapor.toString();\n      }\n    }\n\n    \/\/ Kategoriye G\u00f6re Detayl\u0131 Rapor\n    class KategoriDetayRaporu implements RaporlamaStratejisi {\n      @override\n      String raporUret(List<Gider> giderler) {\n        final Map<String, double> kategoriToplamlari = {};\n        for (var gider in giderler) {\n          kategoriToplamlari.update(gider.kategori, (value) => value + gider.miktar, ifAbsent: () => gider.miktar);\n        }\n\n        StringBuffer rapor = StringBuffer('--- Kategoriye G\u00f6re Gider \u00d6zeti ---\\n');\n        kategoriToplamlari.forEach((kategori, toplam) {\n          rapor.writeln('$kategori: ${toplam.toStringAsFixed(2)} TL');\n        });\n        return rapor.toString();\n      }\n    }\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu yap\u0131y\u0131 kullanarak, <code>GiderYonetici<\/code> s\u0131n\u0131f\u0131, bir <code>RaporlamaStratejisi<\/code> nesnesini al\u0131p rapor \u00fcretebilir:<\/p>\n<pre><code>\n    \/\/ GiderYonetici s\u0131n\u0131f\u0131n\u0131n i\u00e7ine eklenecek metot\n    String raporUret(RaporlamaStratejisi strateji) {\n      return strateji.raporUret(_giderler);\n    }\n  <\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi, farkl\u0131 raporlar olu\u015fturmak i\u00e7in sadece yeni bir raporlama stratejisi s\u0131n\u0131f\u0131 yazmam\u0131z yeterli olacakt\u0131r, <code>GiderYonetici<\/code> s\u0131n\u0131f\u0131n\u0131n i\u00e7ini de\u011fi\u015ftirmemize gerek kalmaz. Bu, A\u00e7\u0131k\/Kapal\u0131 prensibine (Open\/Closed Principle) uygun, bak\u0131m\u0131 kolay ve geni\u015fletilebilir bir tasar\u0131md\u0131r. Bu sayede uygulaman\u0131z, s\u00fcrekli olarak yeni raporlama ihtiya\u00e7lar\u0131na adaptasyon sa\u011flayabilirken, mevcut kodunuzun kararl\u0131l\u0131\u011f\u0131n\u0131 korur.<\/p>\n<p>Bu ileri d\u00fczey yakla\u015f\u0131mlar, Dart OOP'nin g\u00fcc\u00fcn\u00fc kullanarak uygulamalar\u0131n\u0131z\u0131 daha mod\u00fcler, test edilebilir ve s\u00fcrd\u00fcr\u00fclebilir hale getirmenizi sa\u011flar. Kullan\u0131c\u0131lar\u0131n ihtiya\u00e7lar\u0131 de\u011fi\u015ftik\u00e7e veya yeni analiz y\u00f6ntemleri ortaya \u00e7\u0131kt\u0131k\u00e7a, bu esnek yap\u0131 sayesinde uygulaman\u0131z\u0131 kolayca adapte edebilir ve geli\u015ftirebilirsiniz.<\/p>\n<h2>Mobil Uyumluluk ve Kullan\u0131c\u0131 Deneyimi: Kodumuz Her Yerde Nas\u0131l \u00c7al\u0131\u015f\u0131r?<\/h2>\n<p>Dart, Flutter sayesinde mobil uygulama geli\u015ftirmede olduk\u00e7a pop\u00fclerdir ve yazd\u0131\u011f\u0131m\u0131z OOP modelleri direkt olarak Flutter uygulamalar\u0131nda kullan\u0131labilir. Ancak, e\u011fer verilerimizi web \u00fczerinde de sunmak istersek veya bir Dart backend'i (\u00f6rne\u011fin, Dart Frog veya Shelf ile) kullanarak basit bir HTML aray\u00fcz\u00fc olu\u015fturuyorsak, bu HTML i\u00e7eri\u011finin mobil cihazlarda da d\u00fczg\u00fcn g\u00f6r\u00fcnmesi kritik \u00f6neme sahiptir. Kullan\u0131c\u0131 deneyimi, ekran boyutuna bak\u0131lmaks\u0131z\u0131n tutarl\u0131 ve eri\u015filebilir olmal\u0131d\u0131r.<\/p>\n<p>Bu b\u00f6l\u00fcmde, Dart ile olu\u015fturdu\u011fumuz gider verilerini basit bir web sayfas\u0131nda nas\u0131l sergileyebilece\u011fimizi ve bu sayfan\u0131n mobil cihazlarda nas\u0131l daha iyi bir deneyim sunabilece\u011fini CSS medya sorgular\u0131 (media queries) kullanarak g\u00f6sterece\u011fiz. Bu, Dart'\u0131n esnekli\u011finin ve verilerinizin farkl\u0131 platformlarda nas\u0131l kullan\u0131labilece\u011finin bir kan\u0131t\u0131d\u0131r. Unutmay\u0131n ki bu bir Flutter UI \u00f6rne\u011fi de\u011fil, Dart'\u0131n \u00fcretti\u011fi bir HTML \u00e7\u0131kt\u0131s\u0131n\u0131n responsivli\u011fini g\u00f6sterme \u00f6rne\u011fidir.<\/p>\n<h3>Gider Verilerini HTML'de G\u00f6sterme ve Mobil \u0130\u00e7in Optimize Etme<\/h3>\n<p>Varsayal\u0131m ki Dart backend'iniz, <code>GiderYonetici<\/code> s\u0131n\u0131f\u0131n\u0131zdaki verileri al\u0131p a\u015fa\u011f\u0131daki gibi basit bir HTML tablosu olu\u015fturuyor. Bu tablo, kullan\u0131c\u0131lar\u0131n giderlerini liste halinde g\u00f6rmesini sa\u011flar. Bu HTML'in mobil cihazlarda da okunakl\u0131 olmas\u0131 i\u00e7in CSS medya sorgular\u0131n\u0131 kullanaca\u011f\u0131z.<\/p>\n<pre><code>\n    <!DOCTYPE html>\n    <html lang=\"tr\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <title>Gider Y\u00f6neticisi Raporu<\/title>\n        <style>\n            body {\n                font-family: Arial, sans-serif;\n                margin: 0;\n                padding: 20px;\n                background-color: #f4f4f4;\n                color: #333;\n            }\n            .container {\n                max-width: 960px;\n                margin: 0 auto;\n                background-color: #fff;\n                padding: 20px;\n                box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n                border-radius: 8px;\n            }\n            h2 {\n                color: #0056b3;\n                text-align: center;\n                margin-bottom: 20px;\n            }\n            table {\n                width: 100%;\n                border-collapse: collapse;\n                margin-top: 20px;\n            }\n            th, td {\n                padding: 12px 15px;\n                text-align: left;\n                border-bottom: 1px solid #ddd;\n            }\n            th {\n                background-color: #007bff;\n                color: white;\n            }\n            tr:nth-child(even) {\n                background-color: #f2f2f2;\n            }\n            \/* Mobil uyumluluk i\u00e7in medya sorgular\u0131 *\/\n            @media (max-width: 768px) {\n                .container {\n                    padding: 10px;\n                }\n                table, thead, tbody, th, td, tr {\n                    display: block; \/* Tablo elemanlar\u0131n\u0131 blok olarak g\u00f6ster *\/\n                }\n                thead tr {\n                    position: absolute;\n                    top: -9999px;\n                    left: -9999px; \/* Ba\u015fl\u0131klar\u0131 gizle *\/\n                }\n                tr {\n                    border: 1px solid #ccc;\n                    margin-bottom: 10px;\n                    border-radius: 5px;\n                    overflow: hidden;\n                }\n                td {\n                    border: none;\n                    border-bottom: 1px solid #eee;\n                    position: relative;\n                    padding-left: 50%;\n                    text-align: right;\n                }\n                td:before {\n                    position: absolute;\n                    top: 6px;\n                    left: 6px;\n                    width: 45%;\n                    padding-right: 10px;\n                    white-space: nowrap;\n                    text-align: left;\n                    font-weight: bold;\n                    color: #0056b3;\n                }\n                \/* Her bir s\u00fctun ba\u015fl\u0131\u011f\u0131n\u0131 td:before i\u00e7eri\u011fine ekle *\/\n                td:nth-of-type(1):before { content: \"ID:\"; }\n                td:nth-of-type(2):before { content: \"Miktar:\"; }\n                td:nth-of-type(3):before { content: \"A\u00e7\u0131klama:\"; }\n                td:nth-of-type(4):before { content: \"Tarih:\"; }\n                td:nth-of-type(5):before { content: \"Kategori:\"; }\n            }\n        <\/style>\n    <\/head>\n    <body>\n        <div class=\"container\">\n            <h2>Gider Raporu<\/h2>\n            <table>\n                <thead>\n                    <tr>\n                        <th>ID<\/th>\n                        <th>Miktar<\/th>\n                        <th>A\u00e7\u0131klama<\/th>\n                        <th>Tarih<\/th>\n                        <th>Kategori<\/th>\n                    <\/tr>\n                <\/thead>\n                <tbody>\n                    <!-- Bu k\u0131s\u0131m Dart kodu taraf\u0131ndan dinamik olarak doldurulur -->\n                    <tr>\n                        <td>a1b2c3d4<\/td>\n                        <td>150.00 TL<\/td>\n                        <td>Market Al\u0131\u015fveri\u015fi<\/td>\n                        <td>2023-10-26<\/td>\n                        <td>G\u0131da<\/td>\n                    <\/tr>\n                    <tr>\n                        <td>e5f6g7h8<\/td>\n                        <td>50.00 TL<\/td>\n                        <td>Benzin<\/td>\n                        <td>2023-10-25<\/td>\n                        <td>Ula\u015f\u0131m<\/td>\n                    <\/tr>\n                    <tr>\n                        <td>i9j0k1l2<\/td>\n                        <td>80.00 TL<\/td>\n                        <td>Sinema Bileti<\/td>\n                        <td>2023-10-24<\/td>\n                        <td>E\u011flence<\/td>\n                    <\/tr>\n                    <!-- Daha fazla gider eklenebilir -->\n                <\/tbody>\n            <\/table>\n        <\/div>\n    <\/body>\n    <\/html>\n  <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki HTML ve CSS kodunda, <code>@media (max-width: 768px)<\/code> medya sorgusu, ekran geni\u015fli\u011fi 768 piksel veya daha az oldu\u011funda devreye girer. Bu durumda:<\/p>\n<ul>\n<li>Tablo elemanlar\u0131 (<code>table<\/code>, <code>thead<\/code>, <code>tbody<\/code>, <code>th<\/code>, <code>td<\/code>, <code>tr<\/code>) blok seviyesinde g\u00f6sterilir. Bu, normalde yan yana duran s\u00fctunlar\u0131n alt alta gelmesini sa\u011flar.<\/li>\n<li>Tablo ba\u015fl\u0131klar\u0131 (<code>thead tr<\/code>) gizlenir.<\/li>\n<li>Her bir sat\u0131r (<code>tr<\/code>) bir blok eleman\u0131na d\u00f6n\u00fc\u015f\u00fcr ve aralar\u0131nda bo\u015fluk b\u0131rak\u0131l\u0131r.<\/li>\n<li>Her bir h\u00fccre (<code>td<\/code>), i\u00e7eri\u011finin yan\u0131nda ger\u00e7ek ba\u015fl\u0131\u011f\u0131n\u0131 g\u00f6steren bir <code>:before<\/code> s\u00f6zde-eleman\u0131 al\u0131r. Bu sayede, mobil ekranda bile hangi bilginin neye ait oldu\u011fu a\u00e7\u0131k\u00e7a anla\u015f\u0131l\u0131r.<\/li>\n<\/ul>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: <code><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><\/code> etiketi, web sayfalar\u0131n\u0131z\u0131n mobil cihazlarda do\u011fru \u015fekilde \u00f6l\u00e7eklenmesi i\u00e7in hayati \u00f6neme sahiptir. Bu etiketi kullanmak, sayfan\u0131n geni\u015fli\u011finin cihaz\u0131n geni\u015fli\u011fine e\u015fit olmas\u0131n\u0131 ve ba\u015flang\u0131\u00e7 yak\u0131nla\u015ft\u0131rma seviyesinin 1.0 olmas\u0131n\u0131 sa\u011flar.\n  <\/div>\n<p>Bu y\u00f6ntem, Dart ile elde etti\u011finiz verileri sadece konsol \u00e7\u0131kt\u0131lar\u0131 olarak de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 dostu ve eri\u015filebilir web aray\u00fczleri arac\u0131l\u0131\u011f\u0131yla da sunabilece\u011finizi g\u00f6sterir. Bu esneklik, Dart'\u0131n ve OOP prensiplerinin, uygulaman\u0131z\u0131n farkl\u0131 platformlarda ba\u015far\u0131l\u0131 olmas\u0131na nas\u0131l katk\u0131da bulundu\u011funun harika bir \u00f6rne\u011fidir. Geli\u015ftirdi\u011finiz finansal model ne kadar sa\u011flam olursa olsun, son kullan\u0131c\u0131n\u0131n bu verilere kolayca eri\u015fip etkile\u015fime ge\u00e7ebilmesi, uygulaman\u0131z\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik bir fakt\u00f6rd\u00fcr.<\/p>\n<h2>Sonu\u00e7: Dart ile Gider Y\u00f6netimi Maceran\u0131z\u0131n Devam\u0131 Nas\u0131l Olacak?<\/h2>\n<p>Bu makalede, Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak ba\u015flang\u0131\u00e7 seviyesinde bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeyi ad\u0131m ad\u0131m inceledik. \u0130lk olarak, finansal takibin neden \u00f6nemli oldu\u011funu ve OOP'nin bu karma\u015f\u0131k verileri nas\u0131l daha iyi modelleyebilece\u011fini tart\u0131\u015ft\u0131k. Ard\u0131ndan, Dart'taki temel OOP kavramlar\u0131n\u0131 \u2013 s\u0131n\u0131flar, nesneler, kaps\u00fclleme, kal\u0131t\u0131m ve \u00e7ok bi\u00e7imlilik \u2013 ger\u00e7ek d\u00fcnya senaryolar\u0131yla ili\u015fkilendirerek ele ald\u0131k. <code>Gider<\/code> ve <code>Kategori<\/code> gibi ana veri modellerimizi nas\u0131l tasarlayaca\u011f\u0131m\u0131z\u0131 g\u00f6rd\u00fck, bu s\u0131n\u0131flar\u0131n alanlar\u0131n\u0131 ve davran\u0131\u015flar\u0131n\u0131 belirledik. Veri kal\u0131c\u0131l\u0131\u011f\u0131n\u0131 sa\u011flamak i\u00e7in JSON serile\u015ftirme ve dosya i\u015flemleriyle ilgili pratik \u00f6rnekler sunarak, uygulamam\u0131z\u0131n verileri g\u00fcvenle saklay\u0131p geri y\u00fcklemesini sa\u011flad\u0131k. \u0130leri seviye \u00f6zellikler eklemek i\u00e7in raporlama stratejileri ve dinamik veri analizi metotlar\u0131n\u0131 inceledik, b\u00f6ylece uygulaman\u0131n geni\u015fletilebilirli\u011fini ve s\u00fcrd\u00fcr\u00fclebilirli\u011fini art\u0131rd\u0131k. Son olarak, Dart taraf\u0131ndan \u00fcretilen verilerin mobil uyumlu bir HTML aray\u00fcz\u00fcnde nas\u0131l g\u00f6r\u00fcnt\u00fclenebilece\u011fini CSS medya sorgular\u0131 ile \u00f6rneklendirerek, uygulaman\u0131z\u0131n farkl\u0131 platformlardaki eri\u015filebilirli\u011fine de\u011findik.<\/p>\n<p>Bu rehber, Dart ile g\u00fc\u00e7l\u00fc, bak\u0131m\u0131 kolay ve esnek bir gider y\u00f6neticisi uygulamas\u0131n\u0131n temelini atman\u0131za yard\u0131mc\u0131 olmay\u0131 ama\u00e7lad\u0131. Ancak bu sadece ba\u015flang\u0131\u00e7! \u00d6\u011frendi\u011finiz bu temel prensipleri kullanarak uygulaman\u0131z\u0131 \u00e7ok daha ileri ta\u015f\u0131yabilirsiniz. \u00d6rne\u011fin, kullan\u0131c\u0131 aray\u00fcz\u00fc olarak Flutter ile zengin bir mobil uygulama geli\u015ftirebilir, verilerinizi yerel dosya yerine bir SQLite veritaban\u0131nda (<code>sqflite<\/code> paketi ile) veya Firebase gibi bulut tabanl\u0131 bir \u00e7\u00f6z\u00fcmde saklayabilirsiniz. Ayr\u0131ca, daha karma\u015f\u0131k b\u00fct\u00e7eleme kurallar\u0131, otomatik harcama etiketleme, \u00e7oklu para birimi deste\u011fi gibi \u00f6zellikler ekleyerek uygulaman\u0131z\u0131n yeteneklerini geni\u015fletebilirsiniz. Unutmay\u0131n, en iyi \u00f6\u011frenme yolu uygulamakt\u0131r. Bu bilgileri kendi projelerinizde kullanarak Dart ve OOP konusundaki becerilerinizi peki\u015ftirmeye devam edin. Kodlamaya devam edin, finansal bilgeli\u011finizi art\u0131r\u0131n!<\/p>\n<h2>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h2>\n<dl>\n<dt>Dart neden Nesne Y\u00f6nelimli Programlama (OOP) i\u00e7in iyi bir se\u00e7imdir?<\/dt>\n<dd>Dart, temiz ve sezgisel bir s\u00f6zdizimine sahiptir, bu da OOP kavramlar\u0131n\u0131 \u00f6\u011frenmeyi kolayla\u015ft\u0131r\u0131r. Ayr\u0131ca, tamamen nesne y\u00f6nelimli bir dil olmas\u0131 (her \u015fey bir nesnedir), g\u00fc\u00e7l\u00fc kaps\u00fclleme, kal\u0131t\u0131m, \u00e7ok bi\u00e7imlilik ve soyutlama gibi temel OOP prensiplerini do\u011fal bir \u015fekilde uygulaman\u0131z\u0131 sa\u011flar. Flutter ile entegrasyonu sayesinde mobil ve web uygulamalar\u0131nda OOP modellerini do\u011frudan kullanabilmesi de b\u00fcy\u00fck bir avantajd\u0131r.<\/dd>\n<dt>Bu gider y\u00f6neticisi uygulamas\u0131n\u0131 mobil uygulamaya d\u00f6n\u00fc\u015ft\u00fcrebilir miyim?<\/dt>\n<dd>Kesinlikle! Bu makalede olu\u015fturdu\u011fumuz <code>Gider<\/code>, <code>Kategori<\/code> ve <code>GiderYonetici<\/code> gibi s\u0131n\u0131flar, Dart dilinde yaz\u0131ld\u0131\u011f\u0131 i\u00e7in Flutter ile geli\u015ftirilecek bir mobil uygulaman\u0131n arka plan i\u015f mant\u0131\u011f\u0131 (business logic) olarak do\u011frudan kullan\u0131labilir. Tek yapman\u0131z gereken, Flutter widget'lar\u0131n\u0131 kullanarak bu s\u0131n\u0131flar \u00fczerinden kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fc (UI) tasarlamak ve etkile\u015fimleri sa\u011flamakt\u0131r. Veri kal\u0131c\u0131l\u0131\u011f\u0131 i\u00e7in <code>path_provider<\/code> zaten Flutter i\u00e7in d\u00fc\u015f\u00fcn\u00fclm\u00fc\u015ft\u00fcr, ancak <code>sqflite<\/code> gibi yerel veritaban\u0131 \u00e7\u00f6z\u00fcmlerini de tercih edebilirsiniz.<\/dd>\n<dt>Verilerimi JSON yerine bir veritaban\u0131nda saklamak daha m\u0131 iyidir?<\/dt>\n<dd>Daha b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalar i\u00e7in genellikle bir veritaban\u0131 (SQL veya NoSQL) kullanmak daha iyidir. JSON dosyalar\u0131 k\u00fc\u00e7\u00fck \u00f6l\u00e7ekli uygulamalar ve basit veri yap\u0131lar\u0131 i\u00e7in yeterli olsa da, milyonlarca gider kayd\u0131n\u0131 y\u00f6netmek, karma\u015f\u0131k sorgular \u00e7al\u0131\u015ft\u0131rmak veya \u00e7ok kullan\u0131c\u0131l\u0131 bir ortamda veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc sa\u011flamak i\u00e7in veritabanlar\u0131 (\u00f6rne\u011fin, SQLite, PostgreSQL, MongoDB) daha performansl\u0131 ve g\u00fcvenilirdir. Veritabanlar\u0131, ayn\u0131 zamanda veri do\u011frulama, indeksleme ve geli\u015fmi\u015f raporlama yetenekleri de sunar.<\/dd>\n<dt>Makale ba\u015fl\u0131\u011f\u0131ndaki \"B\u00f6l\u00fcm 9\" ne anlama geliyor?<\/dt>\n<dd>\"B\u00f6l\u00fcm 9\", bu makalenin bir ders serisinin veya vaka \u00e7al\u0131\u015fmas\u0131n\u0131n devam\u0131 niteli\u011finde oldu\u011funu g\u00f6sterir. Bu, okuyucunun \u00f6nceki b\u00f6l\u00fcmlerdeki temel bilgileri zaten edinmi\u015f olabilece\u011fini varsayar, ancak bu makale yeni ba\u015flayanlar i\u00e7in de anla\u015f\u0131l\u0131r olacak \u015fekilde temel OOP kavramlar\u0131n\u0131 tekrar ederek ve ad\u0131m ad\u0131m \u00f6rneklerle ilerleyerek ba\u011f\u0131ms\u0131z bir rehber niteli\u011findedir. Bu b\u00f6l\u00fcmde, gider y\u00f6neticisi uygulamas\u0131n\u0131n temel veri modellemesi ve kal\u0131c\u0131l\u0131k katman\u0131n\u0131n daha geli\u015fmi\u015f y\u00f6nlerine odaklan\u0131lm\u0131\u015ft\u0131r.<\/dd>\n<\/dl>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-31358","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)<\/title>\n<meta name=\"description\" content=\"Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak s\u0131f\u0131rdan bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeye ne dersiniz? Bu rehber, Dart\u2019\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffederken, finansal takibinizi kolayla\u015ft\u0131racak pratik bir uygulama olu\u015fturman\u0131za yard\u0131mc\u0131 olacak. Ad\u0131m ad\u0131m ilerleyecek, temel OOP kavramlar\u0131ndan ba\u015flay\u0131p ileri seviye veri y\u00f6netimine kadar pek \u00e7ok konuya de\u011finece\u011fiz.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)\" \/>\n<meta property=\"og:description\" content=\"Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak s\u0131f\u0131rdan bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeye ne dersiniz? Bu rehber, Dart\u2019\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffederken, finansal takibinizi kolayla\u015ft\u0131racak pratik bir uygulama olu\u015fturman\u0131za yard\u0131mc\u0131 olacak. Ad\u0131m ad\u0131m ilerleyecek, temel OOP kavramlar\u0131ndan ba\u015flay\u0131p ileri seviye veri y\u00f6netimine kadar pek \u00e7ok konuya de\u011finece\u011fiz.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-08T23:01:41+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"27 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)\",\"datePublished\":\"2025-10-08T23:01:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/\"},\"wordCount\":4152,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/\",\"name\":\"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-08T23:01:41+00:00\",\"description\":\"Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak s\u0131f\u0131rdan bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeye ne dersiniz? Bu rehber, Dart\u2019\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffederken, finansal takibinizi kolayla\u015ft\u0131racak pratik bir uygulama olu\u015fturman\u0131za yard\u0131mc\u0131 olacak. Ad\u0131m ad\u0131m ilerleyecek, temel OOP kavramlar\u0131ndan ba\u015flay\u0131p ileri seviye veri y\u00f6netimine kadar pek \u00e7ok konuya de\u011finece\u011fiz.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)","description":"Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak s\u0131f\u0131rdan bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeye ne dersiniz? Bu rehber, Dart\u2019\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffederken, finansal takibinizi kolayla\u015ft\u0131racak pratik bir uygulama olu\u015fturman\u0131za yard\u0131mc\u0131 olacak. Ad\u0131m ad\u0131m ilerleyecek, temel OOP kavramlar\u0131ndan ba\u015flay\u0131p ileri seviye veri y\u00f6netimine kadar pek \u00e7ok konuya de\u011finece\u011fiz.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/","og_locale":"tr_TR","og_type":"article","og_title":"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)","og_description":"Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak s\u0131f\u0131rdan bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeye ne dersiniz? Bu rehber, Dart\u2019\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffederken, finansal takibinizi kolayla\u015ft\u0131racak pratik bir uygulama olu\u015fturman\u0131za yard\u0131mc\u0131 olacak. Ad\u0131m ad\u0131m ilerleyecek, temel OOP kavramlar\u0131ndan ba\u015flay\u0131p ileri seviye veri y\u00f6netimine kadar pek \u00e7ok konuya de\u011finece\u011fiz.","og_url":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-08T23:01:41+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"27 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)","datePublished":"2025-10-08T23:01:41+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/"},"wordCount":4152,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/","url":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/","name":"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-08T23:01:41+00:00","description":"Finansal harcamalar\u0131n\u0131z\u0131 takip etmek, b\u00fct\u00e7enizi y\u00f6netmek ve gereksiz giderleri k\u0131smak i\u00e7in etkili bir araca m\u0131 ihtiyac\u0131n\u0131z var? Dart Nesne Y\u00f6nelimli Programlama (OOP) ilkelerini kullanarak s\u0131f\u0131rdan bir gider y\u00f6neticisi uygulamas\u0131 geli\u015ftirmeye ne dersiniz? Bu rehber, Dart\u2019\u0131n g\u00fcc\u00fcn\u00fc ke\u015ffederken, finansal takibinizi kolayla\u015ft\u0131racak pratik bir uygulama olu\u015fturman\u0131za yard\u0131mc\u0131 olacak. Ad\u0131m ad\u0131m ilerleyecek, temel OOP kavramlar\u0131ndan ba\u015flay\u0131p ileri seviye veri y\u00f6netimine kadar pek \u00e7ok konuya de\u011finece\u011fiz.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/dart-oop-ile-gider-yoneticisi-baslangic-seviyesi-rehberi-bolum-9\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Dart OOP ile Gider Y\u00f6neticisi: Ba\u015flang\u0131\u00e7 Seviyesi Rehberi (B\u00f6l\u00fcm 9)"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31358","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=31358"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/31358\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=31358"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=31358"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=31358"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}