Photo by Mathis Jrdl on Unsplash

JS ILE FONKSIYONEL PROGRAMLAMA

JS’in Güçlü ve Doğru Kullanılması

“The Elements of Style” by William Strunk Jr 1920 yılında İngilizce’nin yazılarda, hikayelerde doğru kullanılması için bir rehber niteliğinde stilleri belirtir. Aynısını JavaScript için de uygulayabiliriz.

Aşağıda belirttikleri kesin değişmez yasalar veya kurallar değil, zaman içerisinde doğruluğu ve başarısı kanıtlanmış stillerdir.

İngilizce dili için söylenmiş her prensip/stil aynısını kaynak kod içinde kullanabiliriz.

1. Make the function the unit of composition. One job for each function.

  • Paragrafı kompozisyon birimi yapın: Her konuya bir paragraf ile anlatın.
  • Fonksiyonu composition unit yapın. Her fonksiyon bir iş yapsın.

The essence of software development is composition. We build software by composing modules, functions, and data structures together.

Understanding how to write and compose functions is a fundamental skill for software developers.

Yukarıdaki söylemler yazılım geliştirmede composition(kapsama) çok çok önemli bir konu,

Modüller fonksiyonları ve veri yapılarını içeriyor, fonksiyonlar da diğer fonksiyonları kapsıyor. Ve esas olay uygulama state üzerinde çalışan fonksiyonların veriler üzerinde uygulanması ile gerçekleştiriliyor.

JavaScript 3 tip fonksiyon bulunuyor;

  • Communicating functions : I/O girdi çıktıları işleyen fonksiyonlar.
  • Procedural functions: Bir çok komut’un belli bir sıra ve grup içerisinde işletilmesi
  • Mapping functions: Verilen bir girdiyi başka bir çıktıya dönüştüren fonksiyonlar

Genelde yazılımlarda I/O işlemini → procedural fonksiyon grubu → sonrasında mapping adımları izler. Burada I/O ve mapping işlemlerini birbirine karışmayan ayrı fonksiyonlar içerisinde gerçekleştirebilmek olabildiğince önemlidir.

Yukarıdaki cümleden anlaşılacağı gibi composition yapmayı bilmek ve composition elemanlarını yani I/O ve Mapping fonksiyonlarını ayırıp, üzerinde işlem yaptığınız state/veri yapılarının Side Effecti olmasını engelleyecek işlemler yaptırmak oldukça önemlidir.

2. Omit needless code.

  • Gereksiz Kelimeleri Silin
  • Gereksiz Kodları Silin

Vigorous writing is concise. A sentence should contain no unnecessary words, a paragraph no unnecessary sentences, for the same reason that a drawing should have no unnecessary lines and a machine no unnecessary parts. This requires not that the writer make all sentences short, or avoid all detail and treat subjects only in outline, but that every word tell. [Needless words omitted.]
~ William Strunk, Jr., The Elements of Style

Güçlü yazı özlüdür. Bir cümle gereksiz kelimeleri, bir paragraf gereksiz cümleleeri içermez , resmin gereksiz bir çizgi, makinenin gereksiz parçaları içermemesi , tüm bunlar ürünün kaliteli olmasını sağlar, yazılımda da ne kadar az ve öz o kadar az o kadar az bug ve kodun anlaşılır olması anlamına gelir. Burada az gereksiz olanların çıkarıldığı öz kısmının kaldığı kod parçasıdır.

Return Kaldırılması

Örneğin aşağıdaki örneklerde return ortadan kaldırmak ve ara bir değişkende işlem sonuçlarını tutmamak, kodu daha anlaşılır ve kısa tutmanızı sağlar.

Point Free Style

Cury fonksiyonlar ile fonksiyonları parametrik ve içerde veri saklayabilen hale getirebiliriz. Bu sayede add2(1) gibi verdiğiniz sayı ile inc+1 fonksiyonu elde edebilirsiz. Bunun gibi istediğiniz fonksiyonları oluşturabilirsiniz.

Function Composition

2 fonksiyonun ortak kullanmasi gereken bir değişken olduğunda bunları ara değerlerde tutmak yerine function composition ile bu değişkenden kurtulabilirsiniz.

const g = n => n + 1;
const f = n => n * 2;
function calculate(n){
const result=g(n);
const result2=f(n);
return result;
}

yukarıda bu işlemi result değişkenleri üzerinde tutarak gerçekleştirdik. Halbuki bir değişkene atamadan bu işlemi aşağıdaki şekilde gerçekleştirebiliriz.

function calculate(n){
return f(g(n))
}

bunun yerine compose veya pipe ile fonksiyonları arka sıra verebilirsiniz.

 const compose2 = (f, g) => x => f(g(x)); 
compose(20) //42


const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
pipe(g, f)(20); // 42

3. Use Active Voice

“The active voice is usually more direct and vigorous than the passive.” ~ William Strunk, Jr., The Elements of Style

Burada ingilizce passive kelimer ve eylemler ile fonksiyonları anlatmak yerine aktif eylemler ile dili daha kuvvetli hale getirirsiniz.

myFunction.hasBeenCalled() → yerine →  myFunction.wasCalled()
User.create() --> createUser()
Notifier.doNotification() --> notify()

//Sonucu Boolen dönen fonksiyonlarda
getActiveStatus(user) --> isActive(user)
firstRun = false; --> isFirstRun = false;

//Name Function yerine
plusOne() --> inc()
filesFromZip() --> unzip()
matchingItemsFromArray(fn, array) --> filter(fn, array)

EventHandlers eylemin ne zaman yapıldığını belirttiği için yukarıdaki gibi Active Voice belirtmesinden öte zaman kavramını belirtmesi önemlidir.

element.click(handleClick) --> element.onClick(handleClick)
component.onDragStart(handleDragStart) --> component.startDrag(handleDragStart)

LifeCycle metodunda

componentWillBeUpdated(doSomething) --> component.beforeUpdate(doSomething)

Functional Mixinde sıfat olan eylemler *ing veya *able alabilen fiiller tercih edilmelidir.

const duck = composeMixins(flying, quacking);
const box = composeMixins(iterable, mappable);

4. Avoid a Succession of Loose Statements

  • Art arda gevşek cümlelerden kaçının.
  • Art arda gevşek ifadelerden kaçının

Aslında dilde de benzer problemler olabiliyor. Ard arda birbiri ile ilişkili olmayan cümleler gibi, produrel olarak arka arkaya birbiri ile ilişkilisi güçlü olmayan komutları sıraladığımızda bu monoton bir yapı oluşturur.

Bu tür diziler, her biri ustaca ve bazen beklenmedik bir şekilde farklı olan birçok paralel form tarafından sıklıkla tekrarlanır.

Örneğin, bir kullanıcı arayüzü bileşeni, neredeyse tüm diğer kullanıcı arayüzü bileşenleri ile aynı temel ihtiyaçları paylaşır. Ve bu yapılar yaşam döngüleri şeklinde parçalanabilir ve ayrı fonksiyonlar ile yönetilebilir.

const drawUserProfile = ({ userId }) => {
const userData = loadUserData(userId);
const dataToDisplay = calculateDisplayData(userData);
renderProfileData(dataToDisplay);
};

Yukarıdaki kod örneğin 3 farklı durumu içeriyor

  • Loading Data
  • Process Data
  • Render Data

Bunların farklılaştırılmasının aslında arka planda bir çok avantajlar sağlar ve modern frontend mimarileri veya framework’leri bu yapıları gözeterek bir takım altyapılar sunar.

Bu sayede Rendering katmanını istediğiniz bir Renderer ile değiştirebilirsiniz (ReactNative, WebVR, ReactDOM/Server, VirtualDOM, TestRenderer vb..)

Aynı şekilde Loading katmanını istediğiniz bir fetching kütüphanesi ile Axios, Fetching, XHTTPRequest WebAPIler veya GraphQL, ReactQuery vb.. şema veya caching için ekstra yapılar kullanılabilir.

ProcessData kısmında farklı business logicler uygulanabilir.

Bu şekilde farklı işlevlere sahip fonksiyonları ayrıştırabilirsek hem test edilmesi kolay birimler oluşturabiliriz, hemde bunları farklı opsiyonlar ile istediğimiz zaman değiştirebiliriz.

5. Keep related code together.

  • Birbiri ile ilişkili kelimeleri birbirine yakın tutmak.
  • Birbiri ile ilişkili kodları birbirine yakın tutmak.

Bu benim mevcut projelerimde sık sık karşıma çıkan bir durum. Mevcut projelerde dosyaları type göre ayırmanın daha mantıklı olduğunu düşündük. Buna göre çoğu yerde aşağıdaki gibi hatta daha fazla gruplayarak (containers, components, utils, stores, vb…) ayırmalar gerçekleştirdik.

Avantajı benzer şekilde kodları belli klasörler altında toplayıp, bunların farklı implementasyonla değiştirmenin sadece klasör değişikliği ile yapılabiliyor olması.

Dezavantajı ise giderek bölünmüş bu type kendi içerisinde büyüyerek tek bir feature için bir birinden farklı klasörlere bölünmüş yapılara ekstra kodlar eklemek.

Diğer bir yaklaşım ise Feature(yetenekler) bazında uygulama parçalarını bölümlemek.

ve o yeteneklerin altında type göre bölümleme yapmak. Avantajı , scroll ile farklı farklı işlevsel klasörler içerisinde aradığını bulmak yerine daha odaklı çalışabilme imkanı. Dezavantajı, birbirine ortak yapıları tutmada karşılaşılacak zorluklar. Buna ragmen yeni yaklaşım Feature bazlı gruplama yönünde..

7. Put statements and expressions in positive form.

“Make definite assertions. Avoid tame, colorless, hesitating, non-committal language. Use the word not as a means of denial or in antithesis, never as a means of evasion.”
~ William Strunk, Jr., The Elements of Style

Kodu daha positive komutlar ve koşullar üzerine inşaa etmek.

  • isNotFlying yerine isFlying
  • notOnTime yerine late

gibi daha positive değişken ve fonksiyon isimleri vermeye çalışalım…

If Statement

Negative ile başlamak yerine hata yoksa ne yapacağımıza başta else durumunda da negative ela alalım..

Tenary

vb… positive yaklaşımları önceliklendirin.

Referanslar

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store