31 Ocak 2020 Cuma

GoF- Mediator Örüntüsü - Enterprise Service Bus Denilebilir

Giriş
Diğer örüntüler için GoF Tasarım Örüntüleri yazısına bakabilirsiniz.

Mediator Nedir?
Mediator az kullanılan örüntülerden bir tanesi. GoF kitabındaki tanımı şöyle.
Mediator - Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. It is responsible for coordinating interactions for a group of objects.
Şeklen şöyle

Mediator İçin Kullanılabilecek Kütüphaneler
1. C# için MediatR kullanılabilir.
2. Java'da ben Guava EventBus sınıfını Mediator olarak kullandım
3. C++'ta Mediator kodunu kendim yazmıştım

Mediator Kelimesine Alternatif Şeyler
Belki Coordinator kelimesi kullanılabilir.

1. Mediator Karmaşık Kodları Gizler
Örneğin iletişim protokollerinin detaylarını gizleyebilir. Açıklaması şöyle.
The output stream returned from the URLConnection is a Mediator. You just write data to it. It encapsulates the complex interaction needed to establish a connection and implement whatever protocol was specified in the original URL.
1.1 Mediator ve Façade Arasındaki Fark
Fark çok basit. Façade yeni bir davranış eklemez. Mevcut davranışı daha kolay kullanmamızı sağlar. Mediator ise sisteme yeni davranış ekler.

2. Mediator Belki Publish/Subscribe Olarak Da Düşünülebilir
Bazıları Mediator örüntüsünü aslında publish/subscribe ile aynı şey olarak düşünüyor.

Publish/Subscribe kelimesi 1995 yılında yazılan GoF kitabında geçmiyor. Ancak şu anda bence ikisi aynı şeyler. Aralarındaki tek fark publish/subscribe dağıtık sistemler için kullanılırken, mediator örüntüsünün aynı uygulama içinde kullanılması.

Dolayısıyla mediator örüntüsü merkezi (centralized) bir altyapıdır (infrastructure). Amacı nesneler arasında mesajlaşmayı sağlamaktır. Kendi düşünceme yakın bir cümle şöyle.
"Instead of using the Observer pattern to explicitly set many-to-many listeners and events, Mediator allows you to broadcast events globally across colleagues." — Paul Marcotte
Bu örüntüye EventHub, Event Aggregator diyenler de var. Subscribe olmak isteyen şöyle yapar.
// core.js
mediator.subscribe('newMemberAdded', function newMemberAddedHandler(id){
    this.membersModule.add(id);
});
Publish etmek isteyen şöyle yapar.
// membersUI.js
$('#addMember').click(function(){
    ...
    mediator.publish('newMemberAdded', 998);
    ...
});
2.1 Mediator ve Observer Arasındaki Fark
En temel fark şu. Her subject kendisine eklenen observer'ları içeren bir liste tutmak zorunda. Bu da her observer nesnesi içinde bir çeşit altyapı kodu olmasını gerektiriyor. Bu altyapı kodu kullanılan dile göre çok basit bir kelime ile tanımlanabilirken (örneğin C#, Java) daha karmaşık bir kütüphane kullanılmasını da gerektirebilir (örneğin boost signal).

Bir subject'in sıfır sayıda observer'ı varken, bir başka subject'in n tane observer'ı olabilir. Subject kendisine bağlı observer'ları tetikleyince observer'ların hangi sırada tetikleneceği bilinmez.

Klasik bir mediator örüntüsünde tek bir subject tipini dinleyen tek bir processor vardır. Örnek'te A subject, M mediator, B ise processor yani A nesnesi tarafından M aracılığıyla tetiklenen nesne olarak görülebilir.
  M
 / \
A   B (Processor)

Tek bir processor sayesinde yapılması gereken işler sıraya konulabilir. Dolayısıyla eğer sıralamanın önemi varsa, mediator kullanılmalıdır.



30 Ocak 2020 Perşembe

Encapsulation Nedir

Encapsulation Nedir
Açıklaması şöyle. Sanki sadece Nesneye Yönelik Programlama'da kullanılıyor gibi anlatılıyor ancak bence bu doğru değil.
In object-oriented programming (OOP), encapsulation refers to the bundling of data with the methods that operate on that data, or the restricting of direct access to some of an object's components. Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them. 
Türkçesi Ne Olmalı
Encapsulation kelimesini bence Information Hiding/Bilgi Saklama olarak kullanmak anlaşılırlığı artırıyor. Information Hiding/Data Hiding bilim ve yazılım dünyasında sıkça karşılaşılan genel bir kavram. Encapsulation kelimesi ise hem Nesneye Yönelik Programlama hem de Functional Programming dünyasında kullanılan bir kavram. Her ikisi de aynı şey. Encapsulation şöyle tarif edilir.
"Encapsulation (aka information hiding) is the idea that one shouldn't expose implementation details"
Tarihteki en büyük "encapsulation failure" örneklerinden bir tanesi Y2K problemidir. İşletim sisteminin verdiği bilgi formatının değişmesi, sayılamayacak kadar çok yazılımı etkilemiştir.

Immutability Varsa Halen Encapsulation Gerekir mi ?
Immutability'nin açıklaması şöyle.
In object-oriented and functional programming, an immutable object (unchangeable object) is an object whose state cannot be modified after it is created.
Bir nesnenin Immutable olması gerçekleştirimin detaylarına erişilmesini gerektirmez.

Encapsulation (Bilgi Saklama) Gerçekleştirimin Gizlenmesi Anlamına Gelir.
Encapsulation iş mantığının yani gerçekleştirimin dış dünyadan gizlenmesidir. Açıklaması şöyle.
You should encapsulate state and implementation details so that object has full control on that. Logic will be focused inside object and will not be spread all over the codebase. Encapsulation is still essential in programming as the code will be more maintainable.
Örnek
Elimizde şöyle bir kod olsun.
class Color
{
  private readonly uint argb;

  public Color(byte red, byte green, byte blue, byte alpha)
  {
    argb = alpha << 24 | red << 16 | green << 8 | blue;
  }
}
Encapsulation kullandığımız için daha sonra kodu şöyle yapabiliriz. Bu yeni kodda her parametreyi birleştirmek yerine ayrı ayrı saklamayı tercih ettik ve sınıfımız yine eski haliyle çalışmaya devam edebilir.
class Color
{
  private readonly byte[] argb;

  public Color(byte red, byte green, byte blue, byte alpha)
  {
    argb = new []{alpha, red, green, blue};
  }
}
Örnek
Nesye yönelik programlama dillerinden olmayan C dilinde de Encapsulation vardır. Elimizde şöyle bir header dosyası olsun. Bu kodda AddperImpl yapısı'nın içini belirtmediğimiz halde metod imzalarında kullanabiliyoruz.
#ifndef ADDER_H
#define ADDER_H

typedef struct AdderImpl *Adder;

Adder Adder_new(int x);
void Adder_free(Adder self);
int Adder_add(Adder self, int y);

#endif
Daha sonra Adder.C dosyasında şöyle yaparız.
Adder plus2 = Adder_new(2);
if (!plus2) abort();
printf("%d\n", Adder_add(plus2, 7));  /* => 9 */
Adder_free(plus2);
Encapsulation Sadece Güvenlik İçin Değildir
Bazen şöyle söyleniyor. Bu cümle doğru, ancak gerçek anlatılmak istenen şey değil.
Encapsulation is used to hide the values or state of a structured data object inside a class, preventing unauthorized parties' direct access to them.
Getter ve Setter Encapsulation Sayılır mı ?
Bazıları basit Getter ve Setter'lar bu halleriyle encapsulation saymıyor. Gerekçesinin açıklaması şöyle.
Encapsulation is hiding implementation internals of the object behind its public contract (usually, an interface). Getters and setters does exactly the opposite thing - they expose the object's internals, so the problem is in getters/setters, not encapsulation.
Ancak ileride kodun değişebileceğini düşünerek yani basit getter ve setter değil de bir mantık eklenebileceğini düşünerek encapsulation'a hazırlık demek lazım :) Yani encapsulatin bize esneklik (flexibility) verir.

Örnek
Elimizdeki basit kod şöyle olsun.
class User {
  private int age;

  public int getAge() {
    return age;
  }
}
Eğer age alanına direkt erişime izin vermediğimiz için ileride kodu şu hale getirmek kolay olur. Şöyle yaparız.
class User {
  private LocalDate dateOfBirth;

  public int getAge() {
    LocalDate now = LocalDate.now();
    int year = ...; // calculate using dateOfBirth and now
    return year;
  }

  // other behaviors can now make use of dateOfBirth
}