Kodunuzu gevşek bir şekilde birleştirmek için hatırlamanız gereken birkaç basit şey var:
Bölüm 1:
Teknik olarak "Endişelerin Ayrılması" olarak bilinir. Her sınıfın belirli bir rolü vardır, iş mantığını veya uygulama mantığını idare etmelidir. Her iki sorumluluğu da birleştiren sınıftan uzak durmaya çalışın. yani verileri yöneten (geniş terimli) bir sınıf uygulama mantığı iken, verileri kullanan bir sınıf iş mantığıdır.
Şahsen ben buna (kendi küçük dünyamda) atıfta bulunuyorum create it or use it
. Bir sınıf bir nesne yaratmalı veya hiçbir zaman ikisini birden yapmaması gereken bir nesne kullanmalıdır.
Bölüm 2:
Endişe ayrılığı nasıl uygulanır.
Başlangıç noktası olarak iki basit teknik vardır:
Not: Tasarım desenleri mutlak değildir.
Durumlara göre özelleştirilmeleri gerekiyor, ancak tüm uygulamalara benzer bir teması var. Bu yüzden aşağıdaki örneklere bakmayın ve bunu katı bir şekilde izlemem gerektiğini söyleyin; bunlar sadece örnektir (ve bu konuda biraz çelişkilidir).
Bağımlılık Enjeksiyonu :
Burası, sınıfın kullandığı bir nesneye geçtiğiniz yerdir. Bir arabirime dayanarak ilettiğiniz nesne, böylece sınıfınız onunla ne yapacağını bilir, ancak gerçek uygulamayı bilmesine gerek yoktur.
class Tokenizer
{
public:
Tokenizer(std::istream& s)
: stream(s)
{}
std::string nextToken() { std::string token; stream >> token;return token;}
private:
std::istream& stream;
};
Burada akışı Tokenizer'e enjekte ediyoruz. Belirteç, std :: istream arabirimini uyguladığı sürece akışın ne tür olduğunu bilmez.
Servis Konumlandırıcı Deseni :
Servis bulucu modeli bağımlılık enjeksiyonunda küçük bir değişikliktir. Kullanabileceği bir nesneyi vermek yerine, ona kullanmak istediğiniz nesneyi nasıl bulacağını (oluşturduğunu) bilen bir nesne iletirsiniz.
class Application
{
public:
Application(Persister& p)
: persistor(p)
{}
void save()
{
std::auto_ptr<SaveDialog> saveDialog = persistor.getSaveDialog();
saveDialog.DoSaveAction();
}
void load()
{
std::auto_ptr<LoadDialog> loadDialog = persistor.getLoadDialog();
loadDialog.DoLoadAction();
}
private:
Persister& persistor;
};
Burada uygulama nesnesine bir persistor nesnesi geçiyoruz. Bir kaydetme / yükleme eylemi gerçekleştirdiğinizde, eylemin nasıl yapılacağını gerçekten bilen bir nesne oluşturmak için persistor kullanılır. Not: Yine direnç bir arayüzdür ve duruma bağlı olarak farklı uygulamalar sağlayabilirsiniz.
Bu, potentially
her eylem başlattığınızda benzersiz bir nesne gerektiğinde kullanışlıdır .
Şahsen bunun birim testleri yazarken özellikle yararlı olduğunu düşünüyorum.
Desen Notu:
Tasarım modelleri kendi başına büyük bir konudur. Bu, gevşek bağlantıya yardımcı olmak için kullanabileceğiniz özel bir desen listesi değildir; bu sadece ortak bir başlangıç noktasıdır.
Tecrübe ile, zaten bu kalıpları kullandığınızı fark edeceksiniz, sadece onların resmi adlarını kullanmadığınızdır. İsimlerini standart hale getirerek (ve herkesin onları öğrenmesini sağlayarak) fikirleri iletmenin kolay ve hızlı olduğunu görüyoruz.