
Programlama Paradigmaları: Yazılım Geliştirmede Yönelimler
Yazılım geliştirme, bilgisayar sistemleri ve uygulamalarının oluşturulmasında kullanılan metodoloji ve yaklaşımların genel adıdır. Programlama paradigmaları da, yazılım geliştirme sürecinde temel yaklaşımlar ve yönelimleri tanımlayan kapsamlı ve yapısal kurallar bütünüdür. Bu paradigmalar, geliştiricilere kodun nasıl organize edileceğini, verinin nasıl işleneceğini ve mantığın nasıl ifade edileceğini anlamada rehberlik eder.

Nesne Yönelimli Programlama (Object-Oriented)
Nesne Yönelimli Programlama (OOP), nesnelerin bir araya gelerek karmaşık sistemlerin modellenmesini sağlayan bir paradigmadır. OOP, programlama öğelerini "nesneler" olarak adlandırılan temel birimlere böler. Her nesne, veriyi ve bu veri üzerinde çalışan işlevleri içerir. Sınıflar ise nesnelerin şablonlarını oluşturur. Miras ve çok biçimlilik gibi özellikler, OOP'nin kodun tekrar kullanılabilirliğini ve sürdürülebilirliğini artırmasını sağlar.
Nesne Yönelimli Programlamanın Temel Kavramları
Sınıflar ve Nesneler
OOP'de, programların temel yapı taşı "sınıflar" ve bu sınıflardan yaratılan "nesnelerdir". Bir sınıf, bir nesnenin taslağını oluşturur ve onun özelliklerini (alanlar) ve davranışlarını (metodlar) içerir.
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void Greet()
{
Console.WriteLine($"Hello, my name is {Name} and I'm {Age} years old.");
}
}
Yukarıdaki örnekte, Person
adında bir sınıf tanımlandı. Bu sınıf, Name
ve Age
adında özellikler ve Greet
isminde bir metod içerir.
Miras (Inheritance)
Mirasta, bir sınıfın başka bir sınıftan özelliklerini ve davranışlarını miras alabilmesi anlamına gelir. Miras, kodun tekrar kullanılabilirliğini artırır ve sınıflar arasında hiyerarşik ilişkiler kurar.
class Student : Person
{
public int StudentId { get; set; }
public void Study()
{
Console.WriteLine("Studying...");
}
}
Yukarıdaki örnekte, Student
sınıfı Person
sınıfından miras alıyor. Böylece Student
sınıfı, Name
, Age
ve Greet
özellikleri ile birlikte StudentId
özelliğini ve Study
metodunu içeriyor.
Soyutlama (Abstraction) Nedir?
Soyutlama, karmaşık bir nesnenin veya varlığın sadece önemli özelliklerini ve davranışlarını vurgulayarak gereksiz detayları gizlemeyi ifade eder. Bu yaklaşım, gerçek dünyadaki varlıkları programlamada temsil ederken, sadece kullanıcının ihtiyaç duyduğu bilgileri sunar ve karmaşıklığı minimumda tutar. Soyutlama sayesinde, bir nesnenin nasıl çalıştığına dair iç detaylara girmeden, sadece nasıl kullanılacağını bilmek yeterlidir.
class BankAccount
{
public string AccountNumber { get; set; }
public string AccountHolder { get; set; }
private decimal Balance { get; set; }
public void Deposit(decimal amount)
{
Balance += amount;
}
public void Withdraw(decimal amount)
{
if (Balance >= amount)
{
Balance -= amount;
}
else
{
Console.WriteLine("Insufficient balance.");
}
}
public decimal GetBalance()
{
return Balance;
}
}
Yukarıdaki örnekte, BankAccount
sınıfı bir banka hesabını temsil eder. Sınıfın dış dünyaya sunduğu arayüz sadece hesapla ilgili temel işlemleri içerir: para yatırma, para çekme ve bakiye kontrolü. Hesap bakiyesi gibi özel detaylar private
olarak belirtilerek gizlenir.
Kapsülleme (Encapsulation) Nedir?
Encapsulation (kapsülleme), bir nesnenin durumunu (alanlar) ve davranışını (metotlar) bir arada tutma prensibidir. Bu prensibe göre, bir nesne kendi içindeki verileri korur ve bu verilere sadece belirli metotlar aracılığıyla erişim sağlar. Yani nesnenin iç yapısı gizlenir ve sadece gerekli olan bilgiler ve işlevler dışarıya açılır. Bu, nesnenin kullanan diğer kodlar için daha güvenli ve daha kolay anlaşılır olmasını sağlar.
public class Person
{
private string name; // private alan
public Person(string name)
{
this.name = name;
}
public void SayHello()
{
Console.WriteLine("Merhaba, benim adım " + name);
}
}
class Program
{
static void Main(string[] args)
{
Person person = new Person("Ahmet");
person.SayHello(); // "Merhaba, benim adım Ahmet" çıktısı alınır
// person.name; // Hata! 'Person.name' gizli olduğundan erişilemez.
}
}
Yukarıdaki örnekte, "Person" sınıfı bir kişinin adını temsil eden özel bir alanla başlar. Bu alan "private" olarak tanımlanmıştır, bu nedenle dışarıdaki kodlar doğrudan bu alana erişemez. Ancak "SayHello" metodu aracılığıyla kişinin adı dışarıya açılır ve bu metot çağrılarak kişi kendini tanıtır.
Bu örnek, encapsulation'ın nasıl çalıştığını ve neden önemli olduğunu göstermektedir. Alanlar gizlenirken, metotlar aracılığıyla dış dünyaya açılır.
Çok Biçimlilik (Polymorphism)
Çok biçimlilik, aynı isimli metotların farklı türde nesnelerde farklı davranışlar sergileyebilmesini ifade eder. Bu, aynı arayüzü kullanarak farklı türden nesneleri yönetmeyi sağlar.
class Program
{
static void Main(string[] args)
{
Person person = new Person();
Student student = new Student();
DoGreet(person);
DoGreet(student);
}
static void DoGreet(Person person)
{
person.Greet();
}
}
Yukarıdaki örnekte, DoGreet
metodu hem Person
hem de Student
nesnelerini kabul edebilir. Bu sayede aynı metot, farklı türden nesnelerle çalışabilir.
Nesne Yönelimli Programlama (OOP), C# gibi modern programlama dillerinde sıkça kullanılan ve yazılım geliştirme sürecini daha modüler ve esnek hale getiren bir paradigmadır. Bu kavramları öğrenerek, büyük ve karmaşık projeleri daha iyi yönetebilir ve kodunuzu daha anlaşılır hale getirebilirsiniz.

Prosedürel (Procedural) Programlama
Prosedürel programlama, programın ardışık işlemler ve prosedürler olarak organize edildiği bir paradigmada odaklanır. Programlar, işlevlerin ve adımların sırasını takip ederek çalışır. Veri ve işlevler genellikle ayrı olarak saklanır. Bu yaklaşım, basit ve sıralı işlemlerin gerçekleştirilmesi için uygundur. Ancak büyük ölçekli ve karmaşık sistemlerde bakımı zorlaştırabilir.
Prosedürel Programlamanın Temel Kavramları
Fonksiyonlar ve İşlevler
Prosedürel programlamada, işlevler (fonksiyonlar) programın temel yapı taşıdır. İşlevler, belirli bir görevi gerçekleştirmek üzere tasarlanmış ardışık adımlardan oluşur. İşlevler, verileri alabilir, işleyebilir ve sonuçlar üretebilir.
Örnek olarak, iki sayının toplamını hesaplayan bir işlev:
using System;
class Program
{
static void Main(string[] args)
{
int num1 = 10;
int num2 = 20;
int sum = AddNumbers(num1, num2);
Console.WriteLine($"Sum: {sum}");
}
static int AddNumbers(int a, int b)
{
int result = a + b;
return result;
}
}
Yukarıdaki örnekte, AddNumbers
adında bir işlev tanımlandı. Bu işlev, iki sayının toplamını hesaplar ve sonucu döndürür.
Değişkenler ve Durumlar
Prosedürel programlamada, veriler değişkenler aracılığıyla saklanır ve işlenir. Durumlar (states) programın geçici durumunu temsil eder. İşlevler değişkenlere ve durumlara erişerek işlem yapar.
Örnek olarak, yaşa göre yetişkinlik durumunu belirleyen bir program:
using System;
class Program
{
static void Main(string[] args)
{
int age = 25;
DetermineAdultStatus(age);
}
static void DetermineAdultStatus(int age)
{
if (age >= 18)
{
Console.WriteLine("You are an adult.");
}
else
{
Console.WriteLine("You are a minor.");
}
}
}
Yukarıdaki örnekte, DetermineAdultStatus
adında bir işlev tanımlandı. Bu işlev, yaşa göre durumu belirler ve sonucu ekrana yazdırır.

Fonksiyonel (Functional) Programlama
Fonksiyonel programlama, yazılım geliştirmede işlevsel programlamaya dayalı bir programlama paradigmasıdır. Bu yaklaşım, matematiksel fonksiyonları ve fonksiyonel bileşenleri kullanarak programları oluşturmayı amaçlar.
Fonksiyonel Programlamanın Temel Kavramları
Temel İlkeler
Fonksiyonel programlama, işlevsel bileşenleri ve fonksiyonları merkezine alır. Programlar, değişken durumları minimumda tutarak ve yan etkileri (side effect) önleyerek işlem yapar. Yan etkileri önlemek, kodun daha tahmin edilebilir ve hata ayıklamasının daha kolay olmasını sağlar.
İsimsiz Fonksiyonlar (Lambda Expressions)
Fonksiyonel programlamada isimsiz fonksiyonlar, program içinde yerel olarak tanımlanan ve bir işlevi ifade eden fonksiyonlardır. Bu, işlevleri daha kolay taşımak ve iletmek için kullanışlıdır.
using System;
class Program
{
static void Main(string[] args)
{
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // Çıktı: 25
}
}
Yukarıdaki örnekte, isimsiz bir fonksiyon (lambda ifadesi) kullanılarak karesini hesaplayan bir fonksiyon oluşturuldu.

Reaktif (Reactive) Programlama
Reaktif programlama, olay temelli, asenkron ve veri akışı odaklı bir programlama paradigmasıdır. Bu yaklaşım, veri akışları ve olaylar üzerinde çalışmayı kolaylaştırarak etkileşimli ve gerçek zamanlı uygulamaların geliştirilmesini sağlar. C# .NET platformunda, Reactive Extensions (Rx) adı verilen bir kütüphane bu yaklaşımı destekler.
Reaktif Programlamanın Temel Kavramları
Veri Akışları ve Olaylar
Reaktif programlamada, veri akışları ve olaylar üzerinde işlem yapmak temel prensiptir. Veri akışları, zaman içinde değişen veri değerlerini ifade eder. Bu akışlar üzerinde filtreleme, dönüşüm, birleştirme gibi işlemler gerçekleştirilir. Olaylar ise bir işlemin gerçekleştiği anları temsil eder.
Gözlemci ve Gözlemlenebilir (Observer and Observable)
Reaktif programlamada, gözlemci (observer) ve gözlemlenebilir (observable) terimleri sıkça kullanılır. Gözlemciler, veri akışlarını dinleyen ve değişiklikleri izleyen bileşenlerdir. Gözlemlenebiller ise, veri akışını temsil eden bileşenlerdir. Gözlemciler gözlemlenebilleri takip ederek veri akışlarının değişikliklerini anında yakalayabilirler.

.NET Reactive Extensions Nedir?
.NET Reactive Extensions (Rx), Microsoft tarafından geliştirilmiş bir kütüphanedir ve asenkron ve olay temelli programlamayı daha kolay hale getirmek için tasarlanmıştır. Rx, LINQ (Language Integrated Query) yapısını temel alarak, veri akışlarını işlemek ve yönetmek için kullanılan bir araçtır. Rx, birden çok kaynaktan gelen verileri, olayları veya durum değişikliklerini hızlı ve etkili bir şekilde işlemek için kullanılır.
Nasıl Çalışır?
Rx, gözlemci (observer) ve yayıncı (observable) kavramları üzerine kurulmuştur. Bir yayıncı, veri akışını temsil eder ve bu akışı gözlemcilerle paylaşır. Gözlemciler, yayıncının üzerinden gelen veri akışını dinler ve bu verilere tepki gösterir. Bu yapı, reaktif programlamayı temsil eder.
Rx, LINQ yapısını kullanarak bu gözlemci-yayıncı modelini uygular. Bu sayede, veri akışını sorgulama, dönüşüm, filtreleme gibi işlemlerle kolayca manipüle edebilirsiniz. Rx, olayların, durum değişikliklerinin ve veri akışının karmaşık senaryolarını bile basit bir şekilde ele almanızı sağlar.
Neden Kullanılır?
.NET Reactive Extensions, aşağıdaki durumlarda kullanılabilir:
-
Asenkron İşlemler: Rx, asenkron işlemleri daha kolay ve anlaşılır hale getirir. Veri akışlarını izlemek ve yönetmek için bir standart sağlar.
-
Olay İşleme: Olay temelli programlamada, Rx olayların işlenmesini daha basit ve esnek bir şekilde sağlar. Birden çok olayın paralel olarak izlenmesi ve tepki verilmesi Rx ile kolaydır.
-
Veri İşleme ve Filtreleme: Rx, veri akışlarını LINQ operatörleri ile işleme ve filtreleme yeteneği sunar. Bu sayede verileri hızla analiz edebilirsiniz.
-
Durum Yönetimi: Uygulamanın durumu değiştiğinde tepki vermek için Rx kullanabilirsiniz. Örneğin, bir nesnenin durumu değiştiğinde otomatik olarak güncellemeler yapabilirsiniz.
Örnek:
using System;
using System.Reactive.Linq;
class Program
{
static void Main(string[] args)
{
var observable = Observable.Interval(TimeSpan.FromSeconds(1));
var subscription = observable.Subscribe(
value => Console.WriteLine($"Received: {value}"),
error => Console.WriteLine($"Error: {error}"),
() => Console.WriteLine("Completed")
);
Console.WriteLine("Press any key to unsubscribe...");
Console.ReadKey();
subscription.Dispose();
}
}
Yukarıdaki örnekte, Observable.Interval
ile 1 saniye aralıklarla bir sayı akışı oluşturulur. Subscribe
metodu ile bu akışı dinleriz. Programı çalıştırdığınızda, zaman içinde artan sayıları alacaksınız.
Örnek:
using System;
using System.Reactive.Linq;
class Program
{
static void Main(string[] args)
{
var observable = Observable.FromEventPattern<ConsoleCancelEventHandler, ConsoleCancelEventArgs>(
handler => Console.CancelKeyPress += handler,
handler => Console.CancelKeyPress -= handler
);
var subscription = observable.Subscribe(
eventPattern => Console.WriteLine("Ctrl+C Pressed!"),
error => Console.WriteLine($"Error: {error}"),
() => Console.WriteLine("Completed")
);
Console.WriteLine("Press Ctrl+C to trigger event...");
Console.ReadKey();
subscription.Dispose();
}
}
Yukarıdaki örnekte, FromEventPattern
ile Ctrl+C tuş kombinasyonunu dinleriz. Kullanıcı Ctrl+C tuş kombinasyonunu bastığında "Ctrl+C Pressed!" mesajı görüntülenir.
Reaktif programlama, veri akışları ve olaylar üzerinde çalışarak etkileşimli ve gerçek zamanlı uygulamalar geliştirmek için güçlü bir yaklaşımdır. C# .NET platformunda Reactive Extensions (Rx) kütüphanesi bu yaklaşımı destekler. Reaktif programlama, karmaşık veri akışlarını daha düzenli ve anlaşılır bir şekilde yönetmek için etkili bir araçtır.

Cephe Yönelimli Programlama (AOP)
Cephe Yönelimli Programlama (AOP), yazılım geliştirme sürecinde tekrar eden işlemleri ve kod parçacıklarını merkezi bir şekilde yönetmek amacıyla kullanılan bir programlama yaklaşımıdır. Bu yaklaşım, bir programın farklı noktalarında gerçekleşen işlemleri ("cephe") ve bu işlemlere uygulanan mantıkları ayrı ayrı ele alarak kodun daha temiz, modüler ve sürdürülebilir olmasını sağlar.
Cephe Yönelimli Programlamanın Temel Kavramları
Cephe (Aspect)
Cephe, bir programın farklı noktalarında gerçekleşen işlemleri ifade eder. Örneğin, hata işleme, günlükleme veya yetkilendirme gibi işlemler birer cephe olabilir. Her cephe, belirli bir endişeyi ele alır.
Kesme Noktası (Join Point)
Kesme noktası, bir cephenin uygulandığı yerleri ifade eder. Bu, özel bir kod noktası olabilir, örneğin bir metodun başlangıcı veya bitişi gibi.
Cephe Ratsmanı (Advice)
Cephe ratsmanı, bir cephenin kesme noktalarında ne tür bir işlem yapılacağını ifade eder. Örneğin, bir hata oluştuğunda bir hata mesajı görüntüleme işlemi bir cephe ratsmanı olabilir.
Cephe Noktaları (Pointcuts)
Cephe noktaları, cephe ratsmanlarının nerede uygulanacağını belirten tanımlardır. Örneğin, tüm hataların yakalandığı nokta bir cephe noktası olabilir.
Örnek:
using System;
using System.Collections.Generic;
namespace AspectOrientedExample.Aspect
{
public interface IAspect
{
}
public interface IAfterAspect : IAspect
{
object OnAfter(object value);
}
public interface IAfterVoidAspect : IAspect
{
void OnAfter(object value);
}
public interface IBeforeAspect : IAspect
{
object OnBefore();
}
public interface IBeforeVoidAspect : IAspect
{
void OnBefore();
}
public abstract class AspectBase : Attribute, IAspect
{
}
public class AspectContext
{
private readonly static Lazy<AspectContext> _Instance = new Lazy<AspectContext>(() => new AspectContext());
private AspectContext()
{
}
public static AspectContext Instance
{
get
{
return _Instance.Value;
}
}
public string MethodName { get; set; }
public object[] Arguments { get; set; }
}
}
namespace AspectOrientedExample.Aspect.Attributes
{
public class CacheAttribute : AspectBase, IBeforeAspect, IAfterVoidAspect
{
public int DurationInMinute { get; set; }
public object OnBefore()
{
string cacheKey = GenerateCacheKey();
if (CacheExists(cacheKey))
{
Console.WriteLine("Returning data from cache with cache key: {0}", cacheKey);
return GetCachedData(cacheKey);
}
return null;
}
public void OnAfter(object value)
{
string cacheKey = GenerateCacheKey();
UpdateCache(cacheKey, value, DurationInMinute);
}
private string GenerateCacheKey()
{
return string.Format("{0}_{1}", AspectContext.Instance.MethodName, string.Join("_", AspectContext.Instance.Arguments));
}
private bool CacheExists(string cacheKey)
{
// Check if the cache contains the specified key.
return false;
}
private object GetCachedData(string cacheKey)
{
// Retrieve data from the cache using the cache key.
return null;
}
private void UpdateCache(string cacheKey, object value, int duration)
{
// Add or update data in the cache using the cache key and duration.
}
}
public class LogAttribute : AspectBase, IBeforeVoidAspect, IAfterVoidAspect
{
public void OnBefore()
{
Console.WriteLine("Method Name: {0}", AspectContext.Instance.MethodName);
Console.WriteLine("Arguments: {0}", string.Join(", ", AspectContext.Instance.Arguments));
Console.WriteLine("Logging: Before method call");
}
public void OnAfter(object value)
{
Console.WriteLine("Logging: After method call");
}
}
}
namespace AspectOrientedExample
{
public class Order
{
public int Id { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
}
public interface IOrderService
{
Order CreateOrder(string productName, int quantity);
}
public class OrderService : IOrderService
{
private static List<Order> _orders = new List<Order>();
[Log]
public Order CreateOrder(string productName, int quantity)
{
var order = new Order { Id = _orders.Count + 1, ProductName = productName, Quantity = quantity };
_orders.Add(order);
Console.WriteLine("Order created: Id={0}, Product={1}, Quantity={2}", order.Id, order.ProductName, order.Quantity);
return order;
}
}
class Program
{
static void Main(string[] args)
{
var orderService = TransparentProxy<OrderService, IOrderService>.GenerateProxy();
var order = orderService.CreateOrder("TEST", 11111);
Console.WriteLine("Created Order: Id={0}, Product={1}, Quantity={2}", order.Id, order.ProductName, order.Quantity);
Console.ReadLine();
}
}
}

PostSharp Nedir?
PostSharp, Cephe Yönelimli Programlama (AOP) prensiplerini kullanarak, tekrar eden işlemleri ve kesme noktalarını kodunuzdan ayırmanızı sağlayan bir araçtır. Bu kütüphane, .NET platformunda geliştirme yaparken kodunuzu temiz ve düzenli tutmanızı kolaylaştırır. PostSharp sayesinde, kodunuzun içine karışmadan, işlevsel olmayan işlemleri ve mantığı ayırabilirsiniz.
PostSharp Nasıl Çalışır?
PostSharp, özel nitelikler (attributes) ve işlemcepleri (aspects) kullanarak çalışır. Bir özel nitelik, bir metodu veya sınıfı işaretler ve bu nitelikleri kullanarak bir işlemcebi tetiklersiniz. İşlemcepler, giriş ve çıkış işlemleri, günlükleme, hata yönetimi gibi işlevselliği yönetmek için kullanılır. PostSharp, işlemcepleri kullanarak kodunuzun içine karışmadan işlevselliği eklemenizi sağlar.
PostSharp Örnek:
using System;
using PostSharp.Aspects;
[Serializable]
public class LoggingAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine($"Entering {args.Method.Name}");
}
public override void OnExit(MethodExecutionArgs args)
{
Console.WriteLine($"Exiting {args.Method.Name}");
}
}
class Program
{
[LoggingAspect]
static void Main(string[] args)
{
Console.WriteLine("Hello, AOP!");
}
}

Aktör Model (Actor-Model) Programlama
Bilgisayar programlaması, gün geçtikçe daha karmaşık ve ölçeklenebilir hale gelmektedir. Bu nedenle, paralel ve dağıtık programlama modelleri üzerine çalışmalar yapılmış ve çeşitli yaklaşımlar geliştirilmiştir. Aktör Model de bu yaklaşımlardan biridir ve özellikle ölçeklenebilir ve paralel uygulamalar geliştirmek için kullanılan etkili bir modeldir.
Aktör Model Nedir?
Aktör Model, paralel ve dağıtık sistemlerin tasarım ve uygulamasını kolaylaştırmak için kullanılan bir programlama modelidir. Aktör Model'de, sistemi oluşturan temel birimler "aktörler"dir. Her bir aktör, hafıza alanı ve işlemci gibi kaynakları bağımsız olarak kullanabilen, kendine ait durumu tutabilen ve diğer aktörlerle iletişim kurabilen bir varlıktır. Aktörler, asenkron olarak mesaj alışverişi yaparak birbirleriyle etkileşimde bulunurlar.
Neden Aktör Model?
Aktör Model'in tercih edilme nedenleri şunlar olabilir:
-
Paralellik ve Ölçeklenebilirlik: Aktör Model, paralel ve ölçeklenebilir uygulamaların geliştirilmesini kolaylaştırır. Aktörler, birbirinden bağımsız olarak çalışabilir ve böylece uygulamalar çoklu işlemcili sistemlerde daha verimli bir şekilde çalışabilir.
-
Durum Yönetimi: Her bir aktörün kendi durumu vardır ve bu durumun güncellenmesi sadece ilgili aktör tarafından yapılabilir. Bu, hataları azaltır ve daha tahmin edilebilir bir sistem davranışı sağlar.
-
Yüksek Erişilebilirlik: Aktörler, kendi durumlarını yönettiği için ölçeklendirme ve hata toleransı açısından yüksek erişilebilirlik sağlar. Bir aktörün hata yapması diğerlerini etkilemez.
Microsoft Orleans Framework
Microsoft Orleans, Aktör Model'i temel alan bir çerçevedir ve dağıtık sistemlerin geliştirilmesini kolaylaştırmak için tasarlanmıştır. Orleans, .NET platformu üzerinde çalışır ve dağıtık uygulamaların tasarımını ve geliştirmesini basitleştirir.
Orleans Temel Kavramlar
-
Aktörler: Orleans, aktörleri temsil eden temel yapı taşlarıdır. Her bir aktör, Orleans çerçevesi tarafından yönetilen bir varlıktır.
-
Gruplar: Aktörler belirli gruplar halinde düzenlenebilir. Gruplar, belirli bir işlevi yerine getiren aktörlerin koleksiyonunu temsil eder.
-
Stream'ler: Orleans, aktörler arasında veri akışını sağlamak için stream kavramını kullanır. Stream'ler, aktörler arası iletişimde kullanılan veri akış kanallarıdır.
Orleans Örnek Uygulama
Aşağıda, Orleans çerçevesini kullanarak basit bir örnek uygulamayı ele alacağız. Bu örnekte, bir "User" adında bir aktör oluşturacağız ve bu aktörün mesajlaşma yoluyla bir "Counter" aktörü ile etkileşime geçeceğiz.
using System;
using System.Threading.Tasks;
using Orleans;
using Orleans.Configuration;
using Orleans.Hosting;
namespace OrleansActorExample
{
// Aktör arayüzü
public interface IUser : IGrainWithIntegerKey
{
Task<int> GetCounterValue();
Task IncrementCounter();
}
// Aktör sınıfı
public class User : Grain, IUser
{
private int _counter = 0;
public Task<int> GetCounterValue()
{
return Task.FromResult(_counter);
}
public async Task IncrementCounter()
{
var counter = GrainFactory.GetGrain<ICounter>(0);
await counter.Increment();
_counter = await counter.GetCount();
}
}
// Counter arayüzü
public interface ICounter : IGrainWithIntegerKey
{
Task Increment();
Task<int> GetCount();
}
// Counter sınıfı
public class Counter : Grain, ICounter
{
private int _count = 0;
public Task Increment()
{
_count++;
return Task.CompletedTask;
}
public Task<int> GetCount()
{
return Task.FromResult(_count);
}
}
class Program
{
static async Task Main(string[] args)
{
var host = await StartSilo();
await RunExample();
await host.StopAsync();
}
static async Task<ISiloHost> StartSilo()
{
var builder = new SiloHostBuilder()
.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "OrleansActorExample";
})
.ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(IUser).Assembly).WithReferences())
.ConfigureLogging(logging => logging.AddConsole());
var host = builder.Build();
await host.StartAsync();
return host;
}
static async Task RunExample()
{
var client = new ClientBuilder()
.UseLocalhostClustering()
.ConfigureLogging(logging => logging.AddConsole())
.Build();
await client.Connect();
var user = client.GetGrain<IUser>(0);
Console.WriteLine("Counter value: " + await user.GetCounterValue());
await user.IncrementCounter();
Console.WriteLine("Counter value after increment: " + await user.GetCounterValue());
await client.Close();
}
}
}
Bu örnekte, "User" adında bir aktör oluşturduk ve bu aktörün bir "Counter" adında başka bir aktör ile etkileşime geçtiğini gördük. Orleans, aktörlerin dağıtık olarak nasıl yönetildiğini ve nasıl iletişim kurduğunu basit ve etkili bir şekilde göstermektedir.
Aktör Model, ölçeklenebilir ve paralel uygulamaların geliştirilmesinde önemli bir rol oynamaktadır. Microsoft Orleans framework'ü, Aktör Model'i temel alarak dağıtık sistemlerin tasarımını ve geliştirmesini kolaylaştırmaktadır. Bu model ve çerçeve, modern uygulama geliştirmede büyük önem taşıyan konular arasında yer almaktadır.
Hoşcakalın.
Görüşmek dileğiyle..
☜(゚ヮ゚☜)