En genel iş ihtiyaçlarını yazılımı yapılabilir gereksinimlerine dönüştürmenin bir formülü/yöntemi olabilir mi? Sektör ve iş kolu farketmeden ve tüm yazılım geliştirme metodolojilerince (scrum, kanban, şelale vb.) gereksinim oluşturma sürecindeki problemleri aşmaya yarayacak bu formül her paydaşa istediği detayı vermeli, tüm gereksinimler birbiri ile ilişkili tutmalı, kod geliştirirken tarif, test aşamasında senaryo olarak kullanabilmeli. Formülün sonucunda gereksinimler anlaşılır, net, sade ve test edilebilir olarak yazılmalı ve tüm paydaşlar tarafından anlaşılabilmeli. Olabilir mi? Olursa hayal gerçekleşmiş demektir.
Yazılımlar pek çok şeyi yapabiliyorlar ve her geçen gün daha fazla şeyi daha iyi yapabilir hale geliyorlar. Yazılımlar ve yazılımların geliştirildiği yazılımlar çok gelişmiş olsalar da hala eski moda kalmış bir yanları var. Bir amacı gerçekleştirecek kod üretebilmek için önce o amacın belli olması gerekiyor. Kodu ister insan, ister yapay zeka üretecek olsun bu acı gerçek değişmemekte ve yazılım geliştirme süreci bir girdi olarak gereksinimlere gereksinim duymaktadır.
Gereksinim Nedir?
Peki gereksinim ya da Frenkçe ifadesi ile “requirement” nedir? Yazılım dünyasının gereksinimden anladığı şey ile günlük hayatta kullanılan gereksinim aynı değildir. Günlük hayatta daha ziyade olmazsa olmaz veya olmazsa fena şeylerin olacağı şeylere gereksinim deniyor. Örneğin havaya, suya, yiyeceğe barınmaya gereksinim duymak gibi. Yazılım dünyasında ise gereksinim bu derece hayati bir ihtiyaca karşılık gelmek zorunda değil. Belki de “ihtiyaç” kelimesi yazılım gereksinimlerini daha doğru tarif edebilir ama kavram kargaşası yaratmamak adına gereksinim kelimesini kullanmaya devam edeceğim. IEEE’nin Yazılım Mühendisliği sözlüğünde gereksinimi şu şekilde tanımlıyor: “A condition or capability needed by a user to solve a problem or achieve an objective. (2) A condition or capability that must be met or possessed by a system or system component to satisfy a contract, standard, specification, or other formally imposed documents. (3) A documented representation of a condition or capability as in (1) or (2).” Türkçeleştirecek olursak, (1) bir kullanıcının bir problemi çözmek veya bir hedefi gerçekleştirmek için ihtiyaç duyduğu koşul veya kaabiliyet. Ya da (2) bir sistemin/komponentin bir standardı, anlaşmayı karşılayabilmesi gereken koşul veya kaabiliyet. Ve en nihayetinde (1) ve (2)’de bahsi geçen koşul/kabiliyetin yazılı halde gösterimi.
Bir önceki paragraftaki laf kalabalığını biraz sadeleştirdiğimizde, gereksinimlerle ilgili üç şeyden bahsedebiliriz gibi görünüyor.
- Olmazsa olmaz şeyler olmak zorunda değildir.
- Arzu edilen, ulaşılmak istenen bir kabiliyeti tarif eder.
- Yazılı/matbu ifadelerdir.
Gereksinimler Niçin Önemlidir?
Gereksinimlere yazılım geliştirme yapabilmek için ihtiyaç duymaktayız. Henüz neyi geliştirmesi gerektiğini bulup geliştiren bir yazılım teknolojisi icat edilmedi. Edildi diyenler olursa da inanmayın. Yani, en azından ben inanmıyorum. Fakat gereksinimi önemli yapan şey sadece onun yazılım geliştirme sürecini tetikleyen şey olması değildir. Günümüzde hala pek çok yazılım projesi gereksinim kaynaklı problemler nedeniyle başarısız oluyor. (Bazı istatistiki bilgiler için bkz: Davey & Parker, 2015. Gereksinim ortaya çıkarma sırasında yaşanan zorluklar ve hatalar için bkz: Walia & Carver, 2015) Gereksinimler bir gömleğin ilk düğmesi gibidir. Yanlış iliklenirse sonraki aşamalar da yanlış ilerleyecek ve sonuçta arzu edilen amaca ulaşmak mümkün olmayacaktır. Bu konuda lafı uzatmak yerine bir klasik haline gelmiş aşağıdaki karikatürü incelemek kafi. Özetle doğru/iyi gereksinimler, aşağıdaki sorunları yaşamadan yazılım geliştirme projemizi tamlamamızı sağlar. Yani, gereksinimlere önem vermek zorundayız. Çevik arkadaşlar da dahil.
Gereksinimler Nasıl Oluşturulur?
Gereksinim nedir ve niçin önemlidir konusu ile ilgili pek çok şey bulunabilir. Ama gereksinimlerin nasıl oluşturulması gerektiği konusunda o kadar şanslı değiliz. Bu işin herkesçe kabul gören hap şeklinde kurallarını bulmak zor. Farklı yöntem ve yaklaşımlar mevcut. Genelde gereksinimleri toplarken (gather) ve ortaya çıkarırken (elicitation) nelerin yapılması gerektiği, veya yapılabileceği anlatılıyor. Bu süreçte kullanılabilecek çokça yöntem (anket-soru listeleri, birebir görüşmeleri beyin fırtınası, Joint Application Development (JAD) Vb) var. (Yöntemlerle ilgili güzel bir özet için bkz. [1])
Fakat eninde sonunda bölüm sonu canavarı karşımıza geldiğinde yani gereksinimleri nihai şekilde yazma noktasında onları nasıl yazacağımız ile ilgili çok net tarifler yok. Burada birkaç noktanın altını çizmekte fayda var.
- Gereksinimleri oluşturmak bir işlem değil, süreçtir
- Gereksinimler tek bir türden oluşan ifadeler değildir, katmanlı-hiyerarşik bir yapıları vardır.
- Madde 2’nin devamı olarak farklı paydaşlar, “gereksinim” ile farklı şeyleri anlamakta ve farklı şeyler beklemektedirler.
1. Gereksinim Ortaya Çıkarma Süreci (Requirement Elicitation Process)
Gereksinimlerin oluşturulmasının bir süreç olarak ele alınma ihtiyacı “Gereksinim Mühendisliği” (Requirements Engineering) kavramının doğmasına sebep olmuş. Ülkemizde Gereksinim Mühendisliği / Gereksinim Mühendisi ifadeleri pek kullanılmıyor. Biz genelde bu ikiliye İş Analizi / İş Analisti diyoruz. İş analizinin önemli bir kısmı ise gereksinim mühendisliği faaliyetlerinden oluşuyor. Her ne kadar bu süreç “mühendislik” kelimesi ile anlatılsa da “gereksinim mühendisliği” sayısal/yazılımsal yöntemlerden ziyade sosyal-sözel yöntemlerden oluşuyor. Ama sanırım kulağa daha afili geldiği için mühendislik denmiş.
Literatüre göre Gereksinim Mühendisliği gereksinimleri toplama (gathering), ortaya çıkarma (elicitation) ve yazılı hale getirme (documantation) adımlarından oluşur ve iteratif bir şekilde devam eder. Farklı araştırmacılar bu süreç için farklı önermelerde bulunmuş ama bu detaylar daha akademik kaldığı için yukardaki şekilde ifade etmek yeterli. (Detaylar için bkz:[3])
Dolayısıyla iş birimi/müşteri ile bir iki görüşme yapıp toplantı notlarını e-posta olarak paylaşmak çoğu yazılım talebi için yeterli olmayacaktır. “Gereksinimleri toplamak” yerine, toplanan gereksinimleri analiz etmek, yazılı hale getirmek ve doğrulayarak ilerlemek gerekmekte. Proje için önemli tüm gereksinimleri çıkarana kadar bu süreç devam etmek zorunda.
2. Gereksinim Türleri
O kadar çok ki…Fakat pareto yapıp işimize en çok yarayanlara odaklanabiliriz. Aslında gereksinimler yukarıda ifade edilen süreç içinde ilerlerken olgunlaşır ve detaylanır. Her aşamada belirlenecek gereksinimler, farklı özellikler göstermektedir. Yani esas mesele, bu süreç boyunca ilerlerken ipin ucunu kaçırmadan en tepedeki genel gereksinimleri en aşağıda sistem gereksinimlerine kadar kırabilmektir. Aşağıdaki şekil bunu çok güzel özetliyor.[2]
Gereksinimleri farklı şekillerde kategorize eden görüşler var. (Alrumaih, Mirza & Alsalamah (2018) ;Lauesen (2002); Sommerville (2011); Wiegers & Beatty (2013) [2]) Ben kendimce en kullanışlı bulduğum Wiegers ve Betty üzerinden devam edeceğim. Wiegers ve Betty gereksinimleri İş gereksinimler, Kullanıcı gereksinimleri ve Fonksiyonel gereksinim olarak üçe ayırıyor. Bu üç gereksinim türü hiyerarşik olarak birbirine bağlı. İş gereksinimleri yukardan bakan genel amaçları ifade ederken aşağıya doğru gidildikçe gereksinimler detaylı hale geliyor. Netice itibari ile bir toplantıda, yarım düzine kişi bir konu hakkında konuşurken, her birinin “gereksinim” dediği şey farklı olabilir ve karşı taraftan farklı şeyler bekleyebilir. Gereksinimleri ortaya çıkarırken o sırada hangi seviyede olunduğunun farkında olunması önemli, zira bir iş gereksinimin detayı ile kullanıcı gereksiniminki aynı olmayacaktır. Bu da bizi bir sonraki maddeye götürüyor.
3. Farklı Paydaşlar, Farklı Beklentiler
Bir yazılımcının gereksinimden anladığı ve ona göre ne içermesi gerektiği ile müşterinin, proje yöneticisinin, proje sponsorunun bekledikleri farklıdır. Bu farklı bakış açılarına ben naçizane “kapsam paradoksu” diyorum. BT çalışanları, müşteriden daha net ve detaylı tarifler beklerken müşteriler bu detaylı tariflerin oluşması için BT’nin çalışmasını arzu edebiliyor. Gereksinimlere sadece “gereksinim” denildiğinde ve tek aşamada toplanmaya çalışıldığında çıkmaz bir sokağa girilmiş oluyor. Bu çıkmaz sokağı aşmanın yolu gereksinimleri üst seviye iş gereksinimleri olarak alıp parça parça kırmak ve detaylandırmaktır. Tabi burada da yukardan aşağıya doğru detaylanan gereksinimleri derli toplu ve ana amaca bağlı bir şekilde dokümante etme ve doğrulama sorunu ile karşılaşılabiliyor.
Peki, Gereksinimler Nasıl Oluşturulur?
Yazının en başında gereksinim toplama ile ilgili pek çok yöntem olmasına rağmen gereksinimlerin nasıl yazılacağı ile ilgili detaylı, yönlendirici yaklaşımların azlığından bahsetmiştim. Şu ana kadar aslında tam da aynı şey bu yazıda yapıldı. Yani gereksinimler hakkında pek çok şey yazıp, onların tam olarak nasıl oluşturulması gerektiğinden bahsedilmedi. Yazının başlığı da işte burada anlam kazanıyor. İhtiyaçları en yukarıda iş gereksinimlerinden alıp, önce kullanıcı ve sonra sistem gereksinimlerine dönüştürmenin bir formülü olabilir mi? Bu formül her paydaşa istediği detayı vermeli, tüm gereksinimler birbiri ile ilişkili olmalı, yazılımcı kod geliştirebilirken, test mühendisi gereksinimleri test senaryosu olarak kullanabilmeli. Formülümüzün sonucunda gereksinimler anlaşılır, net, sade ve test edilebilir olarak yazılmalı ve tüm paydaşlar tarafından anlaşılabilmeli. Çevik-şelale fark etmeden kullanılabilmeli.
Gereksinimleri sistematik bir şekilde üretmek ve tekrar kullanabilir yapmak için gereksinim paternleri (requirement patterns) geliştirilmiş. Fakat kullanımdaki paternler oldukça karmaşık ve çoğunlukla fonksiyonel olmayan gereksinimleri hedefliyor. (Detay için Bkz [4])
Doğal dil ile yazılan gereksinimler, dilin yapısı gereği %100 doğru anlaşılır ifadeler olamıyorlar. Herkesin her durumda aynı şeyi anlaması için UML gibi özel modelleme dilleri ile gereksinimleri ifade etmek mümkün fakat bu modelleri tam ve düzgün kullanabilmek özel bir yetkinlik gerektiriyor. Bırakın müşterileri, analist ve yazılım mühendislerinin hepsi dahi bunu yapamayabilir.
Çevik yöntemler gereksinim toplama ve ortaya çıkarma süreçlerini proje başında uygulamak yerine yazılım geliştirme süreci boyunca uygulayarak bu soruna bir çözüm arıyorlar. Scrum’un kullanıcı hikayesi dediği (user story) yani meşhur “Ben……olarak,……. yapabilmek için, ………. İstiyorum” kalıbı iş gereksinimleri için yeterli ve güzel bir yaklaşım. Fakat bu gereksinimlerin daha detaya nasıl kırılacağı ile ilgili pek bir şey söylemiyor. Zaten kısa çevrimler içinde (sprint) küçük parçalar halinde geliştirmeleri canlıya almak bu detayda çalışmaya ihtiyacı azaltıyor. Ancak her şeyi bu şekilde yazmak ve yapmak çok kolay değil. Behavioral Driven Development (BDD) biraz daha detaylı ve test odaklı bir yaklaşım. Orijinal ifadesi ile “Given……. When……Then…..” kalıpları ile kullanıcı gözünden test senaryoları üretiliyor ki bu senaryolara gereksinim demekte bence bir mahsur yok. Fakat bu yöntem de test odaklı bir yaklaşım olup karmaşık bir yazılım projesinin tüm gereksinim oluşturma ihtiyacını uçtan uca taşıması zor görünüyor.
Bir Öneri: Gereksinim Küpü
Kurumumuzda yaptığımız bir çalışma ile “gereksinim rüyasına” doğru bir deneme yaptık. 5N1K sorularını bir gereksinim şablonu olarak kullanıp, iş-kullanıcı-fonksiyonel gereksinimlerini bir biri ile bağlı şekilde ve iş mimarisine içinde yazmayı hedefledik. Bu süreçte her seviye kendi detayında yazılırken bağlantı kopmadan detaya doğru inilebilmekte ve gereksinimler test senaryosu olarak kullanılabilmekte. Tabi rüya gerçekleşti demek için çok erken. Kullandıkça eksiklikler ve ihtiyaçlar daha net ortaya çıkacaktır. Netice itibari ile aramakla bulunmaz, ama bulanlar arayanlardır.
Yöntem ile ilgili detaylı bilgi için kaynakçadaki linki kullanabilirsiniz [4]
Özet
Bir yazılım projesini başarı ile tamamlayabilmek için gereksinimleri doğru şekilde belirlemek şarttır. Gereksinimlerin belirlenmesi daha doğrusu ortaya çıkarılması iteratif bir süreç olup bu süreç esnasında gereksinimler genel amaç içeren iş gereksinimlerinden aşağı doğru inilerek kullanıcı ve sistem(fonksiyonel) gereksinimlere kırılmalı ve doğrulanmadır (validation). Gereksinim kavramını tek bir tanıma indirgemek ve gereksinimleri belirlemeyi tekil bir toplama faaliyeti gibi düşünmek işler zorlaştıracaktır. Tüm süreci uçtan uca yürümeyi sağlayacak bir yöntem/standart, hayalimizdeki gereksinimlere bizi ulaştırabilir.
Dr. Yaşar Uğur Pabuçcu, Content Writer @BA-Works
Kaynakça:
[1] Al-Zawahreh, H., & Almakadmeh, K. (2015, November). Procedural model of requirements elicitation techniques. In Proceedings of the International Conference on Intelligent Information Processing, Security and Advanced Communication (pp. 1-6) . (https://dl.acm.org/doi/abs/10.1145/2816839.2816902)
[2] Wong, L. R., Mauricio, D. S., & Rodriguez, G. D. (2017). A systematic literature review about software requirements elicitation. Journal of Engineering Science and Technology, 12(2), 296-317.
[3] Wiegers K, Beatty J (2013) Software Requirements. Microsoft Press, Washington
[4] Pabuccu, Y. U., Yel, I., Helvacioglu, A. B., & Asa, B. N. (2022). The Requirement Cube: A Requirement Template for Business, User, and Functional Requirements With 5W1H Approach. International Journal of Information System Modeling and Design (IJISMD), 13(1), 1-18. https://www.igi-global.com/pdf.aspx?tid=297046&ptid=278050&ctid=4&oa=true&isxn=9781683181699