24 Kasım 2014 Pazartesi

CPPUnit

Not : JUnit başlıklı yazıya bakabilirsiniz.
Örnek Test
-----------------------
header dosyası
 #include "cppunit/TestFixture.h"
 #include "cppunit/extensions/HelperMacros.h"

class MyTester : public CPPUNIT_NS::TestFixture {
public:
 void testMethod1();

CPPUNIT_TEST_SUITE (MyTester);
CPPUNIT_TEST (testMethod1);
CPPUNIT_TEST_SUITE_END();
};

-------------------
cpp dosyası

CPPUNIT_TEST_SUITE_REGISTRATION(MyTester);

void MyTester::testMethod1(){
}

Koşulları sınamak için kullanılan macrolar şöyle:
CPPUNIT_ASSERT (condition)
Assert that condition is true. Verilen koşulun doğruluğunu dener.Örnek:
void ScreenScrapeTest::fileTest()
{
    CPPUNIT_ASSERT(ScreenScrape::getFile());   // test file validity
}
Diğer örnekler:
CPPUNIT_ASSERT(nullptr == some_class_ptr);
veya
CPPUNIT_ASSERT(!some_class_ptr);
CPPUNIT_FAIL(message): 
Fail with the given message.

CPPUNIT_ASSERT_MESSAGE (message,condition)
Assert that condition is true, and fail with message if it is not.

CPPUNIT_ASSERT_EQUAL (expected,actual)
Assert that expected equals actual.Note that expected and actual needs to be of the same type.
Verilen aynı tipteki iki değişkenin değerlerinin eşitliğini kontrol eder. Eğer iki değişken aynı tipte değilse derleme hatası alırız.

CPPUNIT_ASSERT_DOUBLES_EQUAL
Verilen iki kayan nokta sayının belli bir aralıkta yakın olup olmadığını dener.
C++'ta Private Yaratılan Sınıf  Nasıl Test Edilir
Örnek C#'ta ancak konuya uygun olduğu için aldım. Elimizdeki sınıf ISomething nesnesini kendi yaratıyor olsun. Eğer Bu sınıfı test amacıyla mocklamak istiyorsak, yeni bir constructor eklenebilir. Bu yöntemin kötü olduğunu iddia edenler de var. Ben daha iyi bir yöntem bilmiyorum.
public class MyClass
{
    private ISomething mySomething;

    public MyClass() { mySomething = new Something();  }

    /// <summary>
    /// Constructor - ONLY USE THIS FOR UNIT TESTING
    /// </summary>
    public MyClass(ISomething something) { mySomething = something; }

}

C++'ta Private Metod Nasıl Test Edilir
Bence private metod, public metodları kullanarak test edilmeli. Ancak yinede private metodu tek başına test etmek istiyorsak şu çözümler kullanılabilir.
  1. private metodu çağırabilen bir friend class yaratmak.
  2. private metodu virtual yapmak ve bir başka sınıfta override etmek. Herb Sutter'ın yazısında "Prefer to Make Virtual Functions Private" maddesine bakılabilir. 
  3. Memory Layout kullanmak. Herb Sutter'ın Uses and Abuses of Access Rights yazısına bakılabilir.
Memory Layout Örneği
Test etmek istediğimiz sınıf ile aynı layout'a sahip (taklit) bir başka sınıf yaratıyoruz. Daha sonra reinterpret_cast ile test etmek istediğimiz nesneyi taklit nesneye çevirip private metoduna erişiyoruz. Örnek:
class X 
{ 
public:
  X() : private_(1) { /*...*/ }

private: 
  int Value() { return private_; }
  int private_; 
};

// Nasty attempt to simulate the object layout
// (cross your fingers and toes).
//
class BaitAndSwitch
    // hopefully has the same data layout as X
{   // so we can pass him off as one
public:
  int Value() { return private_; }
private:
  int private_;
};

int mytestMethod( X& x )
{
  // evil laughter here
  return (reinterpret_cast<BaitAndSwitch&>(x)).Value();
}
Daha sonra X sınıfını şöyle kullanıyoruz.
int main()
{
    X x;
    std::cout << mytestMethod(x) << "\n"; // prints 0, not 1
    return 0;
}; 






23 Kasım 2014 Pazar

Altyüklenici Olmak


  • Altyüklenici olmak yazıyla kendimi bağlamak yerine telefon açarım, sözlü konuşurum demek midir ?
  • Altyüklenici olmak, param üstyüklenicinin müşteriden ödeme para almasına bağlı değil, nasılsa paramı ödemek zorundalar mantığı mıdır?


STL Iterator'leri

Giriş
Iterator'ler her veri yapısında bulunuyorlar. Java ve C# gibi dillerden farklı olarak iterator'lerin çeşitleri var. Aşağıda konu ile ilgili notlarım bulunuyor.

Not : Konuyla ilgili olarak STL Stream Iteratorleri başlıklı yazıya da göz atabilirsiniz.

Iteratörler 
iterator ve end()
end() ile elde edilen nokta veriyapısının en son elemanından bir sonraki bir şeydir.Dolayısıyla her veriyapısı [begin,end) şeklinde yarı açık bir aralık verir. Aşağıdaki şekilde durum görülebilir.

Benzer bir şekil ise aşağıda.

Dolayısıyla end() ile verilen iterator'ü bir kere daha artırmaya çalışmak tanımsız davranıştır.

Bu yarı açık aralık yüzünden aşağıdaki döngü çalışır.
for (auto it = v.begin(); it != v.end(); ++it)
iterator ve erase
Bir çok STL veri yapısı için (özellikle vector için) yapıyı dolaşırken silme işlemi aşağıdaki gibi olur.
for (it = begin(); it != end(); ) {
    if (...) it = index.erase(it);
    else ++it;
}
List'te aynı şekilde çalışır. Örnek:


list<A*> myList;
list<A*>::iterator it = myList.begin();
while( it != myList.end() ) {
    (*it)->DoSomething();
    if( (*it)->WorksFnished() ) {
        it = myList.erase(it);
    } else {
        ++it;
    }
}
Burada if koşulundan sonra iterator'ün erase metodunun döndürdüğü değere eşitlendiğine dikkat etmek lazım.
erase metodu silinen elemandan bir sonraki elemanı gösteren değeri döndürür. iterator bu yeni değere eşitlendiği için ++ ile ilerletilmesi gerekmez. 

Iterator Tanımlama
İki çeşit iterator tanımlama yöntemi mevcut. İlk yöntemde iterator sınıfı veri yapısı sınıfına friend olarak tanıtılıyor. Böylece iterator veriyapısının rahatça dolaşabiliyor. STL iteratorleri bu yöntemi kullanıyorlar.Örnek:
class MyClass
{
    friend class MyClassIterator;
 private:
    Node* m_PrivateData;
}
Diğer yöntemde ise Iterator veriyapısına kendini geçerek, kullanacağı index'i veriyapısının güncellemesini istiyor.

Burada her veri yapısının Iterable arayüzünden türediği farz ediliyor. Iterable arayüzü AdvanceIterator(), GetCurrentValue() gibi arayüzler sunuyor.

Template kullanılamayan projelerde, Nesneye Yönelimli bir tasarım yapmak için bu yöntem kullanılabilir.Örnek:
bool Iterator::MoveNext()
{
    return m_pIterable->AdvanceIterator(this);
}
void* Iterator::CurrentItemValue()
{
    return m_pIterable->GetCurrentValue(this);
}
InputIterator
InputIterator yazısına taşıdım.

OutputIterator
OutputIterator yazısına taşıdım.

Random Access Iterator
Random Access Iterator sınıfı diğer iteratör sınıflarına göre en fazla özelliği sunan sınıftır. 
Vector gibi sınıfların döndürdüğü iteratorler random acces iterator olarak sınıflandırılıyor.Bu tür iteratörler "<" , "<=", ">", ">=" gibi karşılaştırmaları desteklerler. Örnek:
for(vector<int>::iterator it = myvector.begin(); it < myvector.end(); it++){
    // some code
}
Reverse Iterator
Reverse Iterator alt tarafata, ileriye doğru çalışan bir iterator'ü kullanarak çalışır. Bu yüzden base()diye bir metodu vardır.
base
Bu metod ile dikkat edilmesi gereken nokta, bir reverse iterator'de *it ve it farklı yerleri işaret ederler. Şekilde görülebilir.

Örnek:
  
  

Türetilen Iterator Fikirleri
Bir çok kütüphane kendi iterator uzantılarını sunuyor. Burada bazı iterator fikirleri var. 
Arka arkaya aynı değer varsa sadece birini dönen deduplication iterator.

Iterator Traits
iterator_traits yazısına taşıdım.

16 Kasım 2014 Pazar

Domain Driven Design - Anti Corruption Layer - Translation Layer Gibi Düşünülebilir

Anti Corruption Layer Nedir?
Anti Corruption Layer, Domain Driven Design ile karşımıza çıkan bir kavram. Bir çok açıklaması mevcut. 

1. Uygulamalar Arasındaki Katman Olabilir
Uygulamalar arasında olabilir. Açıklaması şöyle
When one system needs to talk to another system and if these 2 systems are not compatible, you can use an intermediate layer which is capable of translating first systems communication to the protocol which is used by the second system and vice versa, this intermediate system is called as an Anti Corruption Layer since that layer helps to avoid the data corruption which would have happened otherwise. This is not a new concept and the traditionally, Enterprise Service Bus (ESB) has been used as this intermediate layer.
Şeklen şöyle

2. Uygulama ve Veri tabanı arasında olabilir
Açıklaması şöyle.
If your application needs to deal with a database or another application whose model is undesirable or inapplicable to the model you want within your own application, use an Anticorruption Layer to translate to/from that model and yours.
3. Bounded Context' ler Arasındaki Katman Olabilir
Bir açıklaması şöyle. İki tane Bounded Context arasına yerleştirilir. Böylece birbirlerinden yalıtılmış hale gelirler. 
Anticorruption Layer is a means of linking two Bounded Contexts. Create an isolation layer to provide clients with functionality in terms of their own domain model. The layer talks to the other system through its existing interface, requiring little or no modification to the other system. Internally, the layer translates in both directions as necessary between the two models.

The public interface of the ACL usually appears as a set of services. One way of organizing the design of the ACL is as a combination of facades, adapters, and translators, along with the communication and transport mechanisms usually needed to talk between systems.
4. Microservice ve Legacy Sistem Arasındaki Katman Olabilir
Açıklaması şöyle
A legacy system may have unmaintainable code and an overall poor design, but we still rely on the data that comes from this module. An anti-corruption layer provides the façade, or bridge, between new microservices architecture and legacy architecture. Therefore, it allows us to stay away from manipulating legacy code and focus on feature development. 
Şeklen şöyle


Anti Corruption Layer Ne Değildir
Software ICD mesajlarını kendi yapımıza çeviren arayüz katmanına Anti Corruption Layer denilemez. Çünkü bu  çevrim işlevini yapacak kod parçası zaten yazılacaktır.

15 Kasım 2014 Cumartesi

Supervisor Yazılım

Giriş
Yönetici yazılım (Supervisor) bileşenlerin durumlarını sorgulayarak, hayatta olup olmadıklarına bakarak tüm sistemin state'ini belirler. Eğer state değişmişse tüm bileşenlere duyurarak, herkesin yeni state'e uygun şekilde davranmasını ister. Yani Supervisor bir sistemin state değiştirmesi görevini yerine getiren yazılımdır.

UML
Sistemin state'leri arasındaki geçişleri görsel olarak çizmek için UML'deki State Diagram uygun olabilir.

Önce sistemin ne zaman state değiştireceğini gösteren bir şekil çizilir. Bu şekil geçiş koşullarını (transition criteria) gösterir. Belli şartlar sağlanırsa geçiş gerçekleşir. Örneğin bir cihazın hata vermesi, bir bileşenin heartbeat göndermeyi kesmesi (liveness'ın kaybedilmesi gibi)

Örnek sistem state'leri

State::Unknown --->
State::Operational<--->State::Degraded
                               |--->State::Failure

Design Pattern
Yönetici yazılımı geliştirirken de "State Pattern" tasarım örüntüsü kullanılabilir.

Periyodik Mesajlar Varsa Window Yöntemi
Örnek
Her saniye çalışan bir timer ve elimizde son 5 saniyelik veri olsun 
- En son 3 saniyede 3 mesaj almışsa sistem Operational State içindedir
- Eğer daha az mesaj almışsa bu sefer pencereyi biraz daha büyütür ve son 5 saniyeye bakar.
  Eğer 2 veya daha fazla mesaj almışsa sistem Degraded State'tedir. 
  Eğer 2'den de az mesaj almışsa sistem Not Operational State'tedir.

Örnek
Her saniye çalışan bir timer ve elimizde son 5 saniyelik veri olsun
- Eğer 5 saniye içinde 3 tane ardışık veri almışsa Operation State içindedir. Ardışık veri kontrolü için bu kod kullanılabilir. Şöyle yaparız
public boolean hasConsecutiveNumbers(List<Integer> list, int reqiredConsecutives) {

  boolean result = false;     
  int consecutives = 1;

  for (int i = 1; i < list.size(); i++) {
    // Going through each number here
    if (list.get(i) - list.get(i-1) == 1) {
      consecutives++; // Numbers were consecutive
      if (consecutives == reqiredConsecutives) {
        result = true;
        break;
      }
    } else {
      consecutives = 1;
    }
  }
  return result;
}

14 Kasım 2014 Cuma

C# Enumerable sınıfı

Giriş
Enumerable sınıfı IEnumerable<T> arayüzünü gerçekleştirir. Sınıfın arayüzden gelmeyen kendine özgü bazı metodları da vardır.

Empty metodu
Normalde şöyle bir kod olması beklenir.
public static IEnumerable<TResult> Empty<TResult>()
{
    yield break;
}

13 Kasım 2014 Perşembe

C++ ve Exception

Not : Bu konu ile ilgili olarak Linux Sinyalleri başlıklı yazıya göz atabilirsiniz.

Exception Bilgileri
C++ İle Exception yazısına taşıdım.

Uygulamadan Çıkma Bilgileri

std::terminate()
Bir exception atıldıktan sonra eğer onu yakalayan bir catch() ifadesi yoksa C++ tarafından std::terminate() fonksiyonu çağırılır. Bu fonksiyon da direkt std::abort() fonksiyonunu çağırır . std::abort isminden de belli olduğu gibi SGABRT sinyalinin gönderilmesine sebep olur ve uygulama kapanırken çağırmak üzere atadığı atexit() vs. gibi fonksiyonları işletemeden, yani temizlik yapamadan kapanır. Eğer işletim sisteminde gerekli ayarlar yapılmışsa bir core dosyası oluşturulur.

std::abort()
std::abort yazısına taşıdım.

std::set_terminate()
std::set_terminate yazısına taşıdım.

std::exit()
Aşağıdaki şekli buradan aldım ve std::exit()'in nasıl çalıştığını gösteriyor. Şeklin sadece ortasındaki exit function yazan kısmına bakarsak exit handler'ların çağırıldığı ve standart I/O cleanup yapıldığını görmek mümkün. std::exit() metodunun tek kötü tarafı stack üzerinde yaratılmış olan değişkenlere ait destructor'ların çağırılmaması, yani "Destructors of variables with automatic storage durations are not called." cümlesine dikkat etmek lazım.


Aşağıdaki atexit metodunun kodu var.
int atexit (void (* __func) (void) ) {
  if (atexitCurEntries >= atexitMaxEntries){
     return ERROR;
  }
  pAtexitTable [ atexitCurEntries ].__func = __func;
  atexitCurEntries++;
  return OK;
}
std::_Exit
Bu metod fork() ile başlatılan child process'leri bitirmek için kullanılır. Böylecek atexit() ile kaydedilen metodlar çalıştırılmaz. _Exit() bir C metodudur. _exit() ise POSIX çağrısıdır.

std::quick_exit()
Eğer static desctructorları çağırmak istemiyorsak ancak I/O streamler boşaltılsın istiyorsak std::quick_exit() metodunu da kullanmak faydalı olabilir.

std::atexit()
std::atexit yazısına taşıdım.