28 Şubat 2014 Cuma

System Subsystem Specification Software Requirements Specification (SRS)

Giriş
System Software Specification (SSS) ve Software Requirements Specification (SRS) bir çok projede karşımıza çıkan iki belge. Aşağıda bu iki belge ile ilgili aldığım notlar var.

SSS Notları
 
Sistem Kalite Etkenleri ile İlgili Gereksinimler
SSS belgelerinde bazen aşağıdakine benzer sistem kalite etkenleri görüyorum. Bunları not etmek istedim.

Sistem kalite etkenleri, işlevsel olmayan ancak bir yazılımın "iyi", "sürdürülebilir", "güvenilir", "verimli", "kabul edilebilir" olması gibi "yüksek kalite" özelliklerini belirtirler.

Kalite ile "ölçülebilirlik" ayrılmaz ikilidirler. Aşağıdaki kavramların bir çoğu dolaylı olarak ölçülebiliyor.

Reliability
Bu kavram ile maturity,fault tolerance,recoverability kelimeleri genellikle iç içe kullanılırlar. Örnek:
System shall run on two identical servers for redundancy.

Maintainability
System shall have ethernet interface for maintenance purpose.
System shall record failures onto disk.

Availability
Örnek yaz

Flexibility
Örnek yaz

Portability
Bu kavram ile Adaptability, Instability, Co-existance, Replacability kelimeleri genellikle iç içe kullanılırlar.
Örnek yaz

Reusability
Örnek yaz

Testability
Örnek yaz

Usability
Bu kavram ile Undestandability, Learnability, Operability, Attractiveness kelimeleri genellikle iç içe kullanılırlar.
Örnek yaz

Deployability
Örnek yaz

SSS'in SRS'e Aktarımı
SSS belgesi SRS için girdi teşkil eder. Aktarımın tam yapıldığından emin olmak için izlenebilirlik (traceability) matrisinin olması ve her iki belgenin de gözden geçirilmesi (review) gerekir.

SRS


Bir CSCI'ın geliştirilmesi için kullanılan gereksinimleri içeren doküman. Projede her CSCI bileşeninin kendi  SRS dokümanının olması gerekir.

Türkçe Karşılığı

Aselsan'da Yazılım Gereksinim Özellikleri (YGÖ) kelimesi kullanılıyor. Bence makul bir karşılık.

Dili

SRS belgesini bir çok firma İngilizce olarak hazırlamaya çalışıyor. Hazırlayanların ana dili İngilizce olmadığı için ifade bozuklukları, anlaması güç cümleler ile dolu olabiliyor. Türkçe hazırlanırsa da karşılıkları olmadığı için mecburen İngilizce kavramlar/kelimeler kullanılıyor. Her iki durum da hoş değil.


İngilizce yazılan gereksinimlerde niçin "shall" kelimesinin kullanıldığı burada açıklanmış. Türkçesi "yapacaktır" gibi düşünülürse, daha bir kesinlik manası sağladığı için "will" yerine "shall" kullanılıyor.





Derived Gereksinimler Nedir


Bazı projelerde gereksinimler "Derived" olarak işaretlenirler. Derived Requirement sistem tasarımından kaynaklanmayan, sistem izlenebilirliği olmayan ister anlamına geliyor. Örneğin sistem tasarımı,  yazılımın kaç bölümlenmeden (partition) oluşacağını söylemeyebilir. Ancak SRS'te bu ister bulunabilir. Bu durumda SRS'teki ister "Derived Requirement" olarak işaretlenir. Aşağıdaki cümle de önemli.

"These are requirements that are generated by the development team, based on a number of sources such as regulatory agencies, corporate guidelines, and past experiences on similar projects."
Non-Functional Gereksinimler Nedir?

Bazı gereksinimler ise "Non-Functional" olarak sınıflandırılırlar. Bu tür gereksinimler genellikle (performance, reliability, and interoperability) yazılımın tasarım ve mimarisini şekillendiren gereksinimlerdir.

İzlenebilirlik Tablosu

Her SRS dokümanında, isterlerin hangi CSC'de ele alındığını gösteren bir izlenebilirlik tablosu bulunur. Aslında bu tablo genellikle işe yaramaz, çünkü SRS ve gerçek tasarım/kod arasında çoğunlukla büyük boşluklar bulunur. Mühendisler izlenebilirlik tablosunu kabaca kestirimlerine dayanarak doldururlar. SRS'i eline alıp okuyarak geliştirmeye başlayan bir mühendis, tek bir maddenin kaç bileşene dokunacağını, maliyetinin ne olacağını kestiremeyebilir.

DO-178B gibi süreçlerde ise bu boşluğu doldurmak üzere, High Level (bahse konu SRS belgesi) ve Low Level Requirements isimli iki belge üretilir. Low Level Requirements belgesi SRS ve kod/arasındaki boşluğu kapatır.


Yazılım Kalite Etkenleri ile İlgili Gereksinimler

SRS belgelerinde bazen aşağıdakine benzer yazılım kalite etkenleri (software quality factors) görüyorum. Bunları not etmek istedim.

Functionality Requirements
Örnek yaz

Reliability Requirements
Bazı örnek gereksinimler :
X shall be able to process following data during N hours.

Maintainability Requirements
Örnek yaz

Availability Requirements
Örnek yaz

Flexibility Requirements
Örnek yaz

Portability Requirements
X shall be developed independent from  OS specific system calls.

Reusability Requirements
Örnek yaz

Testability Requirements
Bu iyi bir örnekmi bilmiyorum ancak aşağıdakine benzer cümleler gördüm.
X shall provide health status. X shall perform BIT upon request.

Efficiency Requirements
Örnek yaz

Usability Requirements
Örnek yaz

Kalite Etkenleri Nasıl Test Edilir
Sistem veya Yazılım Kalite Etkenleri netice itibariyle birer gereksinim olduklarına göre, test edilmeleri de gerekir. Bu iş için "Fonksiyonel Olmayan Testler" başlığı altında toplanabilecek bazı faaliyetler gerçekleştirilir.
Performans Testleri :
Yükleme (Load) Testleri : Sistemin belli bir yük altında testi
Stres Testleri: Sistemin aşırı yük altında testi
Uyumluluk (Compatibility) Testleri :
Güvenlik Testleri :
Kullanılabilirlik Testleri :
Yerelleştirme (Localization) Testleri : Çeviriler, tarih, saat formatı vs.

SRS Hataları
SRS'e donanım özelliklerini yazmak gördüğüm hatalardan birisi. Örneğin software shall run on 1 GB memory, 1GHz processor gibi. Bu tür bir gereksinim bence sistem seviyesinde olmalı.

Yazılımın kapasitesini belirten ancak throughput, gecikme, bir işin ne kadar birim zamanda yapılacağını belirtmeyen gereksinim maddeleri bence doğru değiller. Örneğin bir yazılım 5000 nesneyi bellekte tutacaktır denirse ancak bu 5000 nesneyi veya 1 tanesini ne kadar zamanda işleyeceği belirtilmezse, yazılımı test etmek için referans zamanı verilmemiş olur.


SRS Hangi Ölçütlere Göre Gözden Geçirilebilir
Bazı ölçütleri not ediyorum.

Clarity
Anlaşılabilirlik. Örneğin kullanılan terminolji anlaşılabilir olmalı.

Completeness
Bütünlük. Bir örneği buradan aldım.
An incomplete requirement provided to the business analyst that led to a bug in implementation. Example: The user says to the analyst "We only record a customer when a sale is made". A developer getting this requirement may end-up creating a DDL rule that makes the relationship of customer and invoice mandatory such that when an invoice is deleted the corresponding customer information is also deleted. Unless the developer and business analyst confirm with the user that this required, this searing may be considered as a bug in requirements (and development).

Consistency
Tutarlılık. Bir örneği buradan aldım.
A requirement provided by the end-user that conflicts with another requirement or constraint. Example: The user wants to email all customers but does not want the system to collect customer emails.


Interfaces
Sistemin tüm arayüzleri tanılanmış olmalı. Arayüzlerde kullanılacak iletişim yöntemi belirlenmiş olmalı.


Müşterinin SRS'e Yorum Vermesi
Sözleşmede genellikle SRS teslim edildikten X gün sonrasına kadar müşteri yorum verebilir şeklinde bir madde bulunur.

Benzer şekilde SRS'i hazırlayan taraf ta yine Y gün içerisinde yorumlara cevap vermekle mükelleftir, şeklinde bir madde ile taraflar SRS'i ciddiye aldıklarını belirtirler.


DOORS Notları
Aşağıda DOORS ile ilgili notlarım mevcut.

Favorites

Doors Database ekranında bu menü kullanılarak bir modüle kısayol konulabilir.

Object ID
Object ID'sine gitmek için Ctrl + G kısayolu kullanılabilir.

Başka Object'e Giden Linki Takip Etmeke
Doors'ta sağ taraftaki dışarı bakan kırmızı oka tıklanınca seçili maddenin başka bir belgedeki hangi maddeden kaynaklandığı görülebilir. (out link)

Dizin Yapısı
Doors dizinleri aşağıdaki gibi Sistem ve Yazılım ayrımını gösterecek şekilde olabilir.

Software Products/SSS/XXX
 
Software Products/SRS/YYY
Word'e Aktarım 
Doors 8.1 ile gereksinimleri Word  dokümanına aktarmak için araç çubuğundaki Word simgesine tıklanır. Açılan pencereden "Layout" olarak "Table" seçilir ve gereksinimler Word belgesine aktarılır.

Doors'u Şifre Girmeden Çalıştırmak
-d databasenam -u username -p password seçenekleri  kullanılır. Örnek:
"C:\Program Files (x86)\Telelogic\DOORS_8.1\bin\doors.exe" -d databasename -u username -p password

DXL
Doors için scripting yapabilme imkanı tanır. C'ye benzer. Açılımı Doors Extension Language. Aşağıda bazı örnekler var. Bu dil büyük küçük harf farkına hassas değildir. (case insensitive) Bir değişkeni tipini tanımlamaya gerek kalmadan kolayca i =5 yazabiliriz.

Modulu Dolaşan Kod
string modulePath = "/Path/..."
string viewName = "MyView"
Module m = read (modulePath,true)
if (m != null)
{
  bool success = load (m,view (viewName))
  if (success)
  {
    Object o
     for o in m do
     {
        print o."Last Modified By" "\n"
     }
  }
  else
  {
    print "Could not load view" viewName
  } 
}
else
{
 print "Could not open view" modulePath
}

DXL ile If Koşulu
if (null current Module) {
 ack "Hata"
 halt
}
Hata Kutusu Çıkartma
string mesaj = "Hata mesajı\n. Hata açıklaması"
ack mesaj
halt
Dosya Dizini Alan Kutu 
DB dlgBox = create ("Input Box") //Formu başlık ile yarat
fileName (dlgBox,"Choose file","*.txt","Text Files") //Forma widget ekle

void okClick (DB dlgBox) {...}//Click handler
realize dlgBox
show dlgBox //Formu göster

Modul'e Ait Attribute Bulma

AttrDef attr1 = find (current Module, "Attr1")
if (null attr1) {
 halt
}
Stream
Stream ofstream;
ofstream = write ("C:\\file.txt")
ofstream << "test" nl

26 Şubat 2014 Çarşamba

Enterprise Architect Automation Interface

Enterprise Architect Notlarım
Giriş
Enterprise Architect Bir CASE (Computer Aided Software Engineering, Bilgisayar Destekli Yazılım Mühendisliği) aracıdır.

Bu tür araçların, CMMI sürecinin iyileştirilmesinde kullanılması konulu "akademik (!!)" bir çalışmada kullanılmasını görünce, insanın aklına Excel'in "not tutmak" için kullanılması geliyor.

CASE araçları kimileri tarafından modası geçmiş olarak görülse de, ben yazılım kod üretmek için olmasa bile, "Yazılım Ürün Hattı" konusu içinde bulunan Information Model'i betimlemek için faydalı olduklarını düşünüyorum.

Enterprise Architect Automation Interface İçin Ne Lazım ?
Enterprise Architect Automation Interface kullanabilmek içim eaapi.jar ve SSJavaCOM.dll doslayarı lazım. Her şey COM üzerinde inşa edildiği için EA.exe arka planda çalışmalı. Ayrcıa tüm veri yapıları başlangıç indeksi olarak Java'daki gibi 0 sayısı ile başlıyorlar.
Repository Sınıfı Nedir ?
Bu sınıf ile EA Automation arayüzüne erişim sağlanıyor. Aşağıdaki açıklamada entry point olduğu söyleniyor.

The Repository package contains the high level system objects and entry point into the model itself using the Models collection and the other system level collections.

Şekilden de tüm diğer sınıflara erişim için kullanılabileceği görülebilir.

Örnek:
import org.sparx.*;
Repository repository = new Repository ();
repository.open ("c:\\eatest.eap");
Eğer SQLServer'a bağlanmak istersek bu sefer bağlantı dizisini vermek lazım. Kullanılacak diziyi File/Open Project menüsünden görebiliriz. Örnek:
import org.sparx.*;
Repository repository = new Repository ();
String conn = "Model Ismi - DBType=1;Connect=Provider=SQLOLEDB.1;Password=mypass;Persist Security Info=true;User ID=myuser;Initial Catalog=MyModel;Data Source=MyServer\SQLEXPRESS";
repository.open (conn);
Package Sınıfı Nedir?
Bu sınıf ile paketlerin içindeki diagramlar bulunabilir.
Package1
  | -> Package2
           |->Diagram1
şeklinde bir ağaç yapısı varsa, Diagram1'e şöyle erişişir.

Collection<org.sparx.Package> packages = p.GetPackages();
Package package= packages.GetAt (0);
Collection<org.sparx.Diagram> diagrams= package.GetDiagrams();

Diagram Sınıfı Nedir?
Bu sınıf UML ile tasarlanan herhangi bir diagramı temsil ediyor.Yukarıdaki örnekten devam edersek. Diagram1 sınıfının içindeki nesnelere erişmek için aşağıdaki gibi yapılabilir.

Diagram diagram = diagrams.GetAt(0);
Collection<org.sparx.DiagramObject> diagramObjects = diagram.GetDiagramObjects();

Bir diagramı diske emf dosyası olarak kaydetmek için buradaki koda bakılabilir.

Element Sınıfı Nedir?
Bu sınıf ile diyagram içindeki sınıfın bilgisine erişmek mümkün. Aşağıdaki gibi GetElementByID metodu ile yapılabilir.

DiagramObject diagramObject = diagramObjects.GetAt (0);
int elementID = diagramObject.GetElementID (); //56110 verir
Element element = repository.GetElementByID (elementID);
String stereoType = element.GetStereoType ();//struct verir
String name = element.GetName (); //MyStruct verir
Collection<org.sparx.Attribute> attributes = element.GetAttributes();
Element'e direkt erişmek için GUID kullanılabilir. Örnek:
Element myClass = repository.GetElementbyGuid ("{7AC7AB80-DEE5-4CD1-...}");

Burada dikkat edilmesi gereken konu GetAttributes metodunun döndürdüğü Collection sınıfının java.util paketi içindeki Collection olmadığı. Bu sınıfı bir ArrayList'e çevirmek için aşağaki kod kullanılabilir

ArrayList<Attribute> list = new ArrayList <Attribute> ();
Iterator it = attributes.Iterator ();
while (it.hasNext ()){
  list.add (it.next());
}
Attribute Sınıfı Nedir?
Bu sınıf ile class veya struct içindeki alanların bilgisine erişmek mümkün.
Attribute attribute = attributes.GetAt (0);

String name = a.GetName();//m_MyAttributeString type = a.GetType ();//longint attributeID = a.GetElementID () //45789
Attribute'ları sıralama örneği
Collections.sort (list,new Comparator<Attribute> (){
  @Override  public int compare (Attribute left,Attribute right){
    if (left.GetPos () > right.GetPos ()){return 1;}
    if (left.GetPos () < right.GetPos ()){return -1;}
    return 0;
  }
});
Örnekler
EA kurulumunda C:\Program Files (x86)\Sparx Systems\EA\Code\Code Samples\ altında C# ve Java örnek projeleri var.

EA Plugin
EA için plug-in yazmayı gösteren güzel bir yazı burada.

Diğer EA Notlarım

Projeyi Import ve Export Yeteneği
EA'ya girilen herhangi bir paket, Project Browser ağacına sağ tıklanarak, XML olarak kaydedilebiliyor. Daha sonra paketi silip, tekrar import edebilmek mümkün.

Model Transformation
Burada Computation Independent Model'den Project Independent Model'e (PIM) ve daha sonra Platform Specific Model'e geçiş anlatılıyor.

Kaynak Kodu Import Yeteneği
Pakete sağ tıklanınca çıkan "Code Engineering" menüsünden "Input Source Directory" seçilir. Açılan penceredeki bazı seçenekler şu anlama geliyor.

Package Structure
Create Package per Directory : C++ projelerinde namespace yerine dizin yapısı bazen daha önemli olabiliyor. Dizin yapısını EA'da paket yapısını yansıtmak istersek kullanılır.

Create Package per Namespace : Java, C# gibi namespace'e dayalı projelerde aynı namespace içinde ancak farkı dizinlerdeki kodları aynı EA paket içine toplar.

Import işlemi sonucunda çıkan class diagram çok büyükse "Diagram/Zoom/Fit to Window" menüsünden harita görünümü elde edilebilir ve sınıflar düzenlenir.

Tersine Mühendislik Sonucunda Model Ne Yansır?

class, enum ve typedef'lerin modellenmesi
Araç C++ kodunu global space içinde bulunan class,enum ve typedef'leri başarıyla modelliyor. Her türe stereotype veriyor.

typedef'lerin UML ile modellediğini ilk defa bu araçta gördüm. Sağ üst köşede typedef'in gerçekte hangi tip olduğu olduğu da yazıyor.

Association'ların modellenmesi

class A {} class B {A* m_pA;} şeklindeki iki sınıf "association" olarak modelleniyor. Association yerine Aggregation veya Composition (Aggregation'a göre daha sıkı bir bağı temsil eder) denilseydi belki daha iyi olurdu. Ancak genel bir kelime olan "association" kullanılmış. Association düz bir çizgi ile gösteriliyor. Eğer direction değeri verilmişse ucunda ok vardır. Association ile her nesnenin kendi yaşam döngüsü olduğu ve bir nesnenin diğerinin sahibi olmadığı farz edilir.

Association çizgisine çift tıklayınca

General Sekmesinde 
Source : B Target : A Direction : Source -> Destination

Target Role Sekmesinde 
B Role : m_pA (çizgide gösterilen etiket) yazıldığını görebiliriz.


Attribute'ların Modellenmesi

Array
Araç array gibi attribute'ları Attributes penceresindeki Details sekmesinde bulunan Container Type alanında gösteriyor. C++ kodu için bu alana örneğin [4] yazıyor.

static, const vs
Araç static, const gibi modifier'ları Attributes penceresindeki General sekmesinde "static" ve "const" checkboxlarında gösteriyor. Ayrıca varsa "Initial" alanınıda dolduruyor

Attribute'ların Gruplanması veya Sıralanması
Araç eğer arzu edilirse attributeları gruplayıp her grubu kendi içinde sıralayabiliyor. Ben bu şekilde çalışmasını sevmiyorum çünkü koddan farklı bir şey gösterilmesi hoşuma gitmiyor. Bu yüzden Tools / Options altındaki "Group Operations by Stereotype", "Group Attributes by Stereotype", "Sort Features Alphabetically" seçeneklerini kapatıyorum.

Aggregate İlişkisi
Bu ilişkiyi kurmak için "Compose" düğmesine tıklanarak hedef sınıfı kaynak sınıfı birleştirmek gerekiyor.

Kaynak Kod Üretme Yeteneği
Burada Model Interpretation ve Code Generation arasında karşılaştırma yapılan bir yazı var.

Pakete sağ tıklanınca çıkan "Code Engineering" menüsünden "Generate Source Code" seçilir. "Auto Generate Files" seçeneği kullanılmazsa, her element için üretilecek dosya ismi istenir. EA element ile dosya ismini bir şekilde eşleştirip hatırlıyor. "Override Code" seçeneği kullanılırsa diskteki mevcut dosyanın üzerine yazılır.

Code Template
Kaynak kodu üretirken EA Code Template'ları kullanır. Hazır şablonlardaki  macroları şu şekilde okuyabiliriz.

%macro% : Aynı Windows bat dosyasında olduğu gibi macronun değerini verir.


Diyagram Düzenleme
Layout
Tersine mühendislik sonucunda yaratılan diagram çok düzensiz görünebilir. "Diagram/Layout Diagram" menüsünden diagram otomatik olarak daha düzenli hale getirilebilir.

Hizalama
Birden fazla nesne seçilip sağ tıklanarak "Align Centers / Align Horizontally" veya Vertically seçenekleri ile yatay dikey hizalama yapılabilir.

Arama
Açtığımız bir diagramı Project Browser içinde bulmak istersek "Diagram/ Find in Project Browser" menüsü kullanılabilir.

Aynı şekilde isim ile modelde  arama yapmak için "Model Search Window" simgesi kullanılabilir veya "Edit/Model Search" menüsü de aynı işlevi görür.


Class Attribute Düzenleme
Mevcut bir attribute "Copy" düğmesi ile kopyalanabiliyor.

Aynı Anda Birçok Kişinin Çalışması
Model üzerinde aynı kullanıcı ismiyle giriş yaparak, birden çok kişi çalışabilir. Bu durumda EA modelin değiştiğini anlıyor ve tekrar yüklenmesi gerektiği konusunda uyarı veriyor.

Eğer bir başka kişi tarafından modelin değiştirilmesi engellenmek istenirse, pakete sağ tıklayıp "Lock" seçeneği kullanılarak, kişi veya grup haricindekilerin paket/diyagramı değiştirmesi engellenebilir.

Eğer modeli kendimiz yenilemek istersek File/Reload Current Project menüsünü kullanabiliriz.

UML Patterns
Resources Penceresinde UML / Patterns GoF dizininde kullanıma hazır tasarım örüntüleri var. Örüntüye sağ tıklayıp "Add" seçeneği ile Class Diagrama eklemek mümkün.

UML Stereotype'ları
Enterprise Architect ile UML stereotype yaratmak istersek aşağıdaki adımları izleyebiliriz. UML stereotype'ları Resources penceresinde görünürler. Bu pencereyi açmak için View/Other Tools/Resources menüsü seçilmelidir.

1. Yeni bir paket açmak
Yeni bir paket aç ve paket "stereotype" tipi olarak combobox'tan "profile" seç. Paketi yaratmanın daha kolay bir yolu ise ToolBox'tan Profile Araçları altındaki "Profile" simgesini bir diyagram üzerine süreklemek ve bırak. EA otomatik olarak yeni bir paket yaratılması gerektiğini algılıyor.

2. Bir metaclass eklemek
Profile Araçları altındaki "Metaclass" simgesini bir diyagram üzerine süreklemek ve bırak. Metaclass'ı yaratırken EA element tipi seçmemizi istiyor. Element tipi olarak "Class" veya "Attribute" seçilebilir.


UML Note
"Note" kutusunu bir başka elemana bağlamak için "Note Link" kullanılır.

EA ve Data Flow Diyagramı
UML'de data flow diyagramı bulunmuyor. Bunun yerine activity diyagramı kullanılıyor. Ancak EA data flow diyagramı çizilebiliyor. Data flow diyagramı sistemin bileşenleri arasında akan mesaj tiplerini göstermek için çok güzel bir araç. Ayrıca sistemin dış aktörlerle etkileşimini gösteren System Context Diagram çizmek içinde de kullanılabilir.


UML Notlarım
UML'de kullanılan bazı kelimelerin Türkçeleri aşağıda. Bir kısmını buradan aldım.

Aggregation : İçerme. (İçerme olduğu için parçalar birbirlerinden ayrılabilirler)
Composition : Oluşum, Bileşim (Bileşim olduğu için birbirinden ayrılamaz parçaları kasteder)
Association : Bağıntı
Generelization : Genelleme

Class Diagram
UML bir sınıfın property ve operation'ları yerine feature kelimesini kullanıyor.

Association
İki sınıf arasındaki bağıntı ilişkisi. Düz çizgi ile gösterilir. Bağıntının adı ve çokluğu (multiplicity) olabilir. İki sınıf birbirini kullanırsa bu ilişki ile gösterilir.

Parça Bütün İlişkileri
Composition ve Aggregation ile gösterilir. İlişkinin bir ucu içi boş veya dolu elmas şeklindedir.

Realization
Bir arayüzün gerçekleştirilmesi. Kesikli çizgi ve ok ile gösterilir. Örnek:
Generalization
Sınıflar arası kalıtım. Düz çizgi ve ok ile gösterilir. Örnek:


UML Sequence Diyagramı
Bu diyagramlarda yapılan  ve bence faydası olmayan bir kullanım şekli var. O da metod çağrılarında kullanılan tüm parametrelerin diyagramda gösterilmesi. Sadece metod ismi bence yeterli olmalı. Aşağıdaki örnekte sadece metod isimlerinin kullanımı görülebilir.


UML 2.0'dan itibaren Bu diyagram türü için Interaction Frame eklenmiş. Bu eklenti döngü veya seçime bağlı (optional) işleri çerçeve içine alıp gruplamaya yarıyor.

Deployment View
Deployment Diagram
Deployment Diagram'da Node'lar kendi başına çalışan cihaz, bilgisayarları temsil eder. Node'ların içinde Package, bunların içinde ise Component'ler bulunabilir.

Model Driven Architecture ve Model Driven Development
Bunlar son zamanlarda öne çıkan kavramlar. Bir ara konuyla ilgili yazmak istiyorum.



25 Şubat 2014 Salı

Apache POI ve Word

Aşağıda Apache POI ve Word ile ilgili aldığım notlar var.

Dosya Okumak
FileInputStream is = new FileInputStream("C:\\desktop\\sample.docx")
XWPFDocument sourceDoc = new XWPFDocument(is);
Dosya Yazmak
XWPFHeader
Bu sınıf ile dokümandaki başlık bölümü değiştirilebilir. Örnek: 
InputStream input = new FileInputStream("c:\\doslot.docx");
XWPFDocument document=new XWPFDocument(input);
XWPFHeader head = document.getHeaderList().get(0);

List<XWPFParagraph> para= head.getParagraphs();
XWPFRun pararun=para.get(0).createRun();
pararun.setText("Header");

FileOutputStream out = new FileOutputStream("c:\\fin.docx");
document.write(out);
out.close();

Word Notlarım
ToC'te tablolar çıksın isteniyorsa tablolara caption eklemek gerekir. Tabloya sağ tıklanır ve + işaretine tıklanır. Add Caption menüsü seçilir. Caption tablonun altına gelecek şekilde ayarlanırsa daha iyi görünüyor.

24 Şubat 2014 Pazartesi

DNS Metodları

Kendi Sunucumuzun İsmini Bulma
gethostname
Bu metod ile kendi sunucumuzun ismini bulabiliriz. Örnek:

Yukarıdaki örnekte 80 karakterlik yer ayrılmış. Ancak HOST_NAME_MAX macrosu kadar yer ayırmak yeterli. Böylece farklı platformlarda bile çalışan bir kod yazmış oluruz.

Java
InetAddress.getHostName() metodu ile yapılır.

C#
Environment.MachineName ile bulunabilir.

Kendi Sunucumuzun IP Adresini Bulma
Bir sunucunun birden fazla IP adresi olabilir!
C#
DNS.GetHostEntry metodu kullanılır. Eğer string boş verilirse kendi IP adres veya adreslerimizi buluruz.
IPHostEntry ipHostEntry = Dns.GetHostEntry(string.Empty);
    
Sadece Metin Domain İsmi ile Bulma
gethostbyname - superseded by getaddrinfo
Örnek:
struct hostent *hent = gethostbyname ("hostname");
hostent veriyapısı ise aşağıda.

hostent veriyapısının h_addr_list alanı char** olarak görünse de aslında bir struct in_addr listesi.
Aşağıdak örnekte hostent veriyapısını dolaşma gösterilmiş. 

 Bir başka örnekte ise h_addr_list listesinin ilk elemanı kullanılmış.
struct hostent *h=gethostbyname("localhost");
if(!h) {return;}
struct sockaddr_in channel;
memset(&channel,0,sizeof(channel));
channel.sin_family=AF_INET;
memcpy(&channel.sin_addr.s_addr, h->h_addr, h->h_length);
channel.sin_port=htons(SERVER_PORT);

gethostbyname_r - superseded by getaddrinfo
gethostbyname statik bellek alanı kullandığı için kullanımı tavsiye edilmiyor. Bunun yerine gethostbyname_r kullanılabilir. Aşağıdaki örnekte hata kontrolü yok: Metoda geçilen hostbuf ve result parametrelerinin farkını ben de tam anlamadım.

string hostname = "myhost";
struct hostent hostbuf;
struct hostent *result;
int herr;

int tmplen = 1024;
char *tmp = malloc (tmplen);//tamponun büyüklüğünün yeterli olup olmadığını kontrol etmiyoruz
int hres = gethostbyname_r (hostname.c_str(),&hostbuf,tmp,tmplen,&result, &herr);

if (ret == 0 && result != NULL) //Hata yoksa
{

    char** pAddr = result->h_addr_list;
    while(*pAddr)
    {
        //(*pAddr)[0],(*pAddr)[1] ile ip adresini al
        ++pAddr;
    }
}
free(tmp);
inet_ntoa
Bu metod IPv4 için çalışır. Verilen binary IP adresini "192.168.1.2" örneğindeki gibi metne çevirir. İmzası
char *inet_ntoa(struct in_addr in); 
şeklindedir.
   
Metin Domain İsmi veya Metin IP ile Bulma 
getaddrinfo - posix
getaddrinfo verilen metini (isim veya IP adresi) binary formata çevirir. Döndürülen result listesi freeaddrinfo() ile silinmelidir, yoksa memory leak olur. Örnek:

struct addrinfo* result = NULL;

//set hints
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;

getaddrinfo("localhost"//hostname
            NULL//port
            &hints, //hints
            &result
            );

for(struct addrinfo *res = result; res != NULL; res = res->ai_next)
{
    struct sockaddr_in* saddr = (struct sockaddr_in*)res->ai_addr;
}
       
if (result)
{
    freeaddrinfo(result);
}   
inet_addr
Verilen IP metnini binary formata çevirir. Örnek:
struct sockaddr_in  sin;
memset(&sin,0,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_port=htons(1234);
sin.sin_addr.s_addr = inet_addr("10.0.0.1");
if(sin.sin_addr.s_addr == INADDR_NONE){} //Error 

Java
İsmi verilen bir sunucunun IP adresini bulmak için InetAddress.getByName() metodu kullanılır.  Parametre olarak domain ismi veya IP verilebilir. Eğer parametre boş bir string ise "localhost" döner.
InetAddress address = InetAddress.getByName("SERVER_IP");//IP veya hostname verilir
Kendi makinemin adresini bulmak için getLocalHost metodunu kullanabilirim. Örnek:


Metin IP Adresini Long'a Çevirme

inet_aton - deprecated. Use inet_pton
Verilen metin IP adresini long'a çevirir. Örnek:

inet_pton
Verilen metin IP adresini long'a çevirir.

Long'u Metin IP adresine çevirme

inet_ntoa - deprecated. use inet_ntop
Örnek yaz.

inet_ntop
Verilen long'u string'e çevirir. Örnek:

PING ICMP
Java
Java'da Ping yapabilmek için kolay bir yöntem yok. InetAddress.isReachable () metodu eğer çalıştıran program root ise ping gönderir, değilse değilse ping göndermez bunun yerine port 7'ye TCP Echo gönderir.


Reflection ile Annotation

Java
Annotation sınıfı tanımlamak
Örnek:
// declare a new annotation
@Retention(RetentionPolicy.RUNTIME)
@interface Demo {

String str();

int val();
}
getAnnotation
Örnek:
Class<?> myClass = Class.class;
MyAnnotation myAnnotation = myClass.getAnnotation(MyAnnotation.class);

Canvas

Java
Graphics sınıfı
create
Boyama olayı gelince verilen nesnenin kopyası çıkartılabilir. Örnek:
public void drawDashedLine(Graphics g, int x1, int y1, int x2, int y2){

//creates a copy of the Graphics instance
Graphics2D g2d = (Graphics2D) g.create();

//gets rid of the copy
g2d
.dispose();
}
Stroke sınıfı
Çizginin tipini belirtir. Örnek:
Stroke dashed = new BasicStroke(...);
C#
Brush
Brush text yazdırılırken kullanılır.


Font
Fontların pixel olarak büyüklüğü Height ile öğrenilebilir.

Graphics sınıfı
Çizimler Graphics sınıfı ile yapılıyor

Clear
Arka planı verilen renk ile boyar ve temizler.
g.Clear (Color.White);

DrawString
Belirtilen noktadan başlayarak, belirtilen font ve brush ile metin yazar.

Bir ekran bileşeninin sol üst köşesine yazmak
Control bileşeninin 0,0 noktasına yazmak yeterli. Örnek:
string text;
Control c;
Font font = new Font("Arial", 8);
Brush brush = Brushes.Black;
Graphics g = c.CreateGraphics();
g.DrawString (text,font,brush,0,0);
Bir ekran bileşeninin sağ alt köşesine yazmak
Başlangıç noktası Control bileşeninin yüksekliği - font yüksekliğinden bir kaç pixel daha az olmalı. Örnek:
string text;
Control c;
Font font = new Font("Arial", 8);
Brush brush = Brushes.Black;
Graphics g = c.CreateGraphics();
g.DrawString (text,font,brush,0,control.Height - font.Height - 2);
Bir ekran bileşeninin sağ üst köşesine yazmak
Yazılmak istenen string'in uzunluğu kadar geriden başlamak lazım. Örnek:
string text;
Control c;
Font font = new Font("Arial", 8);
Brush brush = Brushes.Black;
Graphics g = c.CreateGraphics();
SizeF stringSize = g.MeasureString (text,font);
g.DrawString (text,font,brush,control.Width- stringSize.Width,0);

Bir ekran bileşeninin sağ alt köşesine yazmak
Yazılmak istenen string'in uzunluğu kadar geriden ve font'un büyüklüğü kadar yukarıdan başlamak lazım. Örnek:
string text;
Control c;
Font font = new Font("Arial", 8);
Brush brush = Brushes.Black;
Graphics g = c.CreateGraphics();
SizeF stringSize = g.MeasureString (text,font);
g.DrawString (text,font,brush,
                         control.Width- stringSize.Width,
                         control.Height - font.Height - 2);
MeasureString
Verilen string'in belirtilen font ile kaç pixel tutacağını döndürür. Örnek yukarıda var.

Transform
Verilen nokta etrafında matris kadar döndürür. Örnek:
Matrix m = new Matrix ();
m.RotateAt (45);// clockwise direction
g.Transform = m;
//Do drawing
g.ResetTransform ();
Pen
Pen çizgi, kare, çember vs. şekiller çizdirilirken kullanılır.


JUnit

Birim Testi (Unit Test) Çapraz Yapılabilir mi ?
Bu konuda yapılmasının iyi olduğu yönünde bazı yazılar var ancak ben bu yöntemi kullanırken bazı eksiklikler gördüm. Çalıştığım projede çapraz testin stajyerlerce yapılmasını istendi.

Stajyerler, birim testi yazarken kodu tamamen anlayıp gerçek içeriğe yönelik test yerine, sadece kapsama yüzdesini artıracak testleri yazdılar. Birim testi yapan kişi, kodu geliştiren kişi ile birebir çalışan birisi değilse, test istenildiği kadar verimli olmayabilir.

Kodu geliştiren kişi birim testini kendi yazmayınca, kodun ne kadar test edilebilir olduğunu tam kavrayamıyor. Bu konuda da eksiklik olduğunu düşünüyorum.

Büyük Yazılımlarda Birim Testleri Nasıl Yönetmeli
Yazılım büyüdükçe birim test sayısı da artıyor. Çok fazla testi bir arada koşturmak, hatanın bulunmasını zorlaştırır. Bu yüzden birim testleri de kendi içinde bölümlemek gerekebilir.

Birim Testi İle Tümleyim (Integration) Testinin Farkı Nedir?
Sorunun cevabını ben de bilmiyorum. Tek anladığım tümleyim testleri bir veya daha fazla birimin bir araya getirilerek yapılması gerektiği. Hangi araçlar kullanılır ve seviyesi ne olmalıdır bilmiyorum.

Tümleyim testi için "big bang" yöntemi en kolay yöntem. Bottom up veya top down yöntemlerde birleştirilmesi gereken bileşenlerin sırasının belirlenmesi ve her birleşimi besleyecek kod ve araç geliştirilmesi gerekebiliyor.

Birim Testi Dışarıdan Bir Dosyayı Yükleyerek Yapılabilir mi ?
Dışarıdan dosya yüklemenin amacı eğer çok fazla sayıda olasılığı denemek ise makul sayılabilir. Ancak amacın birim testi yerine tümleyim testine doğru kaymamasına dikkat etmek lazım.

GUI Testi Nasıl Yapılır?
GUI uygulamalarının işlevsel testleri (functional test) bir test otomasyon aracı ile yapılırsa daha iyi olur.

Test Yöntemleri
Tüm test yöntemleri test için kullanılacak verinin rastgele değil de belli prensiplere göre seçilmesini amaçlar. Böylece testin etkinliği artırılarak

Equivalance Class Partitioning
Equivalance Class Partitioning - Türkçesi denklik sınıfı test tekniği  - yönteminde, test için kullanılacak girdi kümelere ayrılır ve her kümeden birer örnek denir. Böylece azami test kapsaması sağlanır. Aşağıdaki şekilleri buradan aldım.

Eğer girdi aralık ise ve aralığın dışında değerler yoksa
Örnekte ASCII aralığını büyük karaktere çevirmek için tablo hazırlanmış. Bu tabla ASCII karakterleri 3 aralığa bölmüş ve aralıkların dışında değer olmadığı varsayılmış. Bu durumda 4 tane test yapmak yeterli.


Eğer girdi aralık ise (range) ve aralığın dışında değerler de varsa
Aralık sürekli (continuous) veya kesikli (discrete) olabilir. Aralığa dahil olan mavi kümeden bir, dahil olmayan kırmızılar kümesinden de birer örnek denenir.
Eğer girdi nokta ise
Noktanın sabit değeri , ve nokta dışındaki kümeden bir değer denenir.
Boolean değerler de nokta gibi düşünülebilir. Yani bir true bir de false girdi denenmelidir.

Eğer girdi küme ise
Kümenin içindeki bir girdi, ve kümenin dışındaki bir girdi denenir.

Boundary Value Testing
Boundary Value Testing - türkçesi uç nokta test yöntemi - yukarıdaki denklik sınıfı yöntemine çok benziyor.  Aradaki en büyük fark kümeden girdi seçerken, tam uçtaki, ucun bir altındaki ve bir üstündeki değerleri kullanmak. Yani biraz daha fazla test yazılması anlamına geliyor. Eğer 3'ten fazla test yazılması gerekiyorsa girdiyi equivalence gruplarına ayırırken bir hata yapıldığı anlamına gelen bir yazı gördüm ancak tam ne demek isteniyor bilmiyorum.

Eğer girdi aralık ise (range)
Aralık sürekli (continuous) veya kesikli (discrete) olabilir. Aşağıdaki aralık örneğinde, a -1 , a ve a+1 ayrıca b -1 , b , b+1 değerlerini kullanarak 6 test yazılıyor. Örneğin bir büyüklüğü 10 olan array veri yapısı için indeksleri test ediyor olsaydık, -1,0,1 ve 8,9,10 indeks değerlerini kullanmamız gerekirdi. Kırmızı ile işaretli girdiler içinse , hata almayı beklerdik.
Eğer girdi nokta ise
Noktanın kendisi, bir eksiği ve bir fazlası için test yazılıyor. Boolean değerler de nokta gibi düşünülebilir. Yani bir true bir de false girdi denenmelidir.

Eğer girdi küme ise
Bu durumda mümkünse kümedeki tüm elemanların ve küme dışındaki bir elemanın denenmesi isteniyor.
Yine denklik sınıfı test tekniğine göre biraz daha fazla test yazılıyor.


JUnit
JUnit ile aldığım bazı notlar aşağıda

TestSuite Sınıfı
Bu sınıf koşturulacak Test nesnelerini içerir. @RunWith (AllTests.class) anotasyonu ile suite içindeki Test sınıfından türeyen testler koşturulur. Örnek:


Exception atılmasının test edilmesi
@Test (expected =IllegalArgumentException.class)
 public void testIllegal1() {
 }
Testin Çalışmaması
@Ignore anotasyonu ile bir testin çalışmaması sağlanabilir.

static import
Static import yaparak bir sınıfın public static metodları sınıf ismini belirtmeden kullanılabilir. JUnit ile bu yüzden static import yapılıyor. Örnek'te Math.min metodu yerine sadece min kullanılmış. Bir başka örnek ise burada.
assertEquals
Verilen iki nesnenin eşitliğini a.equals(b) şeklinde test eder.

assertFalse ve assertTrue
Verilen metodun false/true döndürdüğünü test eder.
Örnek :
assertFalse (a == b);
assertTrue  (a == b);

CPPUnit
Aşağıda CPPUnit ile ilgili bazı notlarım var.

Ö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(){
}

CPPUNIT_ASSERT
Verilen koşulun doğruluğunu dener.

CPPUNIT_ASSERT_EQUAL
Verilen iki aynı tipteki değişkenin değerlerinin eşitliğini kontrol eder.

CPPUNIT_ASSERT_DOUBLES_EQUAL
Verilen iki kayan nokta sayının belli bir aralıkda yakın olup olmadığını dener.

23 Şubat 2014 Pazar

Gabya Sınıfı Fırkateyn ve 3D Radar

Hangi Gemilere Takılıyor
Gabya sınıfı fırkateynlerdeki hava arama radarıın 2 boyutlu olduğunu içeren "Gabya Sınıfı Fırkateyn" yazısından sonra bazı gemilere (F494 Gökçeada, F495 Gediz, F496 Gökova, F497 Göksu) "Thales Smart-S MK2" 3 boyutlu hava arama radarı takılma projesi başlatıldı.

F246 SalihReis MEKO sınıfı bir fırkateyn olmasına rağmen bu gemilere de aynı radar takılıyor. Burada radar görülebilir.. Diğer MEKO'larda ise AWS-9 radarı bulunuyor.

Bu radar aynı zamanda Kolombiya donanmasındaki FS-1500 fırkateynlerinde de kullanılıyor. Endonezya donanması bu radarın yanında yine Thales ürünü Variant radarını da kullanıyor.

 Smart-S MK2 Radarı

Radarın tanıtım videosunu aşağıda bulabilirsiniz.

Radarın dönüşünü gösteren bir diğer video ise yine aşağıda.

Bu radar gemide bulunan Genesis-GSYS (Genesis-Gabya Savaş Yönetim Sistemi) sistemine de entegre edilecek. Radar deniz yüzeyini yalayarak gelen Mach 3+ hızındaki füzeleri ve 70 dereceden fazla açılarla yaklaşan cisimleri tesbit edebiliyor. SMART-S MK2 radarı 160 adede kadar hava hedefi ve 40 adede kadar deniz hedefini aynı anda izleyebilir.

Not : Aynı radar Milgem projesinde de kullanıldı. "Milgem ve 3D Radar"başlıklı yazıyı okuyabilirsiniz.

Proje neticesinde bazı yazılarda modernizasyona tabi tutulan bu gemilere Gökçeada sınıfı, tutulmayan diğer gemilere ise Gaziantep sınıfnı dendiğini gördüm ancak resmi olarak böyle bir ayrım henüz yok.

Bu radar S bandında çalışıyor. Geleneksel ve yeni bant isimlendirmesi için buraya bakınız. Yeni isimlendirmeye göre bu radar F bandına düşüyor ancak ben bu yazıda geleneksel bant isimlerini kullandım.

Radarın menzili 250 km ve muhtemelen L bandında çalışan AN/SPS-49 radarına göre daha fazla enerji çekiyordur.
 AN/SPS-49 Radarı

Radarın bandı
S bandında çalışan radarların L band radarlara göre idamesi biraz daha güç olmasına rağmen bu radarın üreticisi "solid state" teknolojisi kullandığını ve "high availability" sağladığını söylüyor. S bant radarların L radarlara göre dalga boyu daha küçük olduğu için daha küçük bir anten gerektiriyorlar. Buna ek olarak S band radarlar meteorolojik şartlardan daha az etkilenirler. Ayrıca bu radar kıyılarda (littoral) çalışmak üzere optimize edilmiş.

Radarın Üretimi
Cihazların üretimi konusunda Thales Türkiye ve Endonezya'da benzer bir model izliyor. İlk iki radarı kendi üretiyor kalanları ise satış yaptığı ülkede monte ediliyorlar. Endonzeya LCS gemilerinde uygulanan bu modeli burada görebilirsiniz.

ESSM
Bu modernizasyon programı kapsamında ayrıca gemilere Lockheed Martin tarafından üretilen MK 41 dikey lançerleri de takılmış. Bir çok füze çeşidini fırlatabilen bu sistemle beraber füze ve hava hedeflerine karşı koruma sağlayan ESSM (Evolved Sea Sparrow Missile) füzeleri de alınmış.ESSM radar güdümlü bir öz savunma füzesi. Hatta Roketsan ESSM füzesinin  uçuş sonlandırma biriminin tasarım, test ve üretimini gerçekleştiriyor.

ESSM ve SM-1'in amacı ve görevi farklıdır.ESSM geminin kendini koruması için tasarlanmıştır ve 4'lü gruplar halinde atılırlar. SM-1 ise daha uzun menzilli bir hava savunma füzesidir. Gemi kendini korumak için aşağıdaki sırayı izler.
  1. Daha uzun menzilli olan SM-1 füzesi.
  2. Daha kısa menzilli olan ESSM füzesi.(supersonik ve seyir füzelerini de avlayabliyor)
  3. Nokta savunması sağlayan Phalanx veya RAM 
ESSM ile SM-1 füzesinin beraber kullanılması durumu ise şu linkte açıklanmış. Böylece gemiye kademeli bir koruma sağlanıyor. ESSM'in en büyük avantajı sahip oldugu INS + X veya S band up-link ile, sadece terminal safhada aydinlatma radarina ihtiyac duymasi.
Özet olarak  "Thales Smart-S MK2" radarı yeni ESSM füzesini güdümlemek için de kullanılıyor.

SMART-L
Bu yazıyı yazdıktan sonra SMART-S Mk2 radarını müteakip SMART-L radarının çıktığını farkettim. Bu radar çok daha uzun menzilli.

Anlaşıldığına göre SMART-S radarının ilk ismi sadece SMART iken bu radarın çıkmasıyla beraber ismi SMART-S olarak değiştirilmiş.
 

SMART-L radarı

Bu radar yapılan bir yazılım güncellemesiyle ortaya çıkan Smart-L ELR (Extended Long Range) modelinin 400 km öteden ateşlenen bir balistic füzeyi tesbit edebildiği yazılıyor. 2012 yılında çıkan Royal Netherlands Navy and Thales Sign SMART-L Early Warning Capability Contract başlıklı yazıya göre balistik füze tesbit edebilme yeteneği Hollanda donanmasında kullanılmaya başlanmış.

Buradan aldığım şekilde Smart-L radarının yayın yeteneği ile ilgili bir şekil görebilirsiniz.
Yükseliş açısı (Elevation angle) hakkında bilgi almak için Radar Temelleri başlıklı yazıyı okuyabilirsiniz.