Kaydet (Commit) 5f5cc23b authored tarafından Hamit Tokay's avatar Hamit Tokay

Fonksiyonlar kısmında 'Functions should do one thing

', 'Function names should say what they do', 'Functions should only be one level of abstraction', 'Remove duplicate code' kısımlarını Türkçeye çevirdim
üst 6388fafc
...@@ -177,70 +177,69 @@ function fabrikaOlustur(isim = 'Önceki Yazılımcı AŞ') { ...@@ -177,70 +177,69 @@ function fabrikaOlustur(isim = 'Önceki Yazılımcı AŞ') {
## **Fonksiyonlar** ## **Fonksiyonlar**
### Fonksiyon Argümanları (İdeal olanı 2 ya da daha az) ### Fonksiyon Argümanları (İdeal olanı 2 ya da daha az)
Limiting the amount of function parameters is incredibly important because it Fonksiyonların aldığı argümanları sınırlandırmak fonksiyonun test edilebilirliği
makes testing your function easier. Having more than three leads to a açısından oldukça önemlidir. Üçten fazla argümana sahip bir fonksiyonu test
combinatorial explosion where you have to test tons of different cases with etmeniz gerektiğinde, her bir durumu her bir argümanla ayrı ayrı test
each separate argument. edeceğinizden dolayı tonlarca teste maruz kalabilirsiniz.
One or two arguments is the ideal case, and three should be avoided if possible. Bir veya iki argüman normal olan durumdur, mümkün olduğunca üçüncüden kaçınılmadılır.
Anything more than that should be consolidated. Usually, if you have Bundan daha fazla olanlar iyileştirilmelidir. Eğer fonksiyonunuz ikiden fazla
more than two arguments then your function is trying to do too much. In cases argüman alıyorsa, muhtemelen yapması gerekenden fazla işi yapmaya çalışıyordur.
where it's not, most of the time a higher-level object will suffice as an Daha fazla argümana ihtiyacınız olduğunuz durumlarda daha kapsamlı bir nesne
argument. kullanmak yeterli olacaktır.
Since JavaScript allows you to make objects on the fly, without a lot of class Javascript size anında nesne oluşturma kabiliyetini verdiğinden dolayı, daha fazla
boilerplate, you can use an object if you are finding yourself needing a argümana ihtiyaç duyduğunuz durumlarda; herhangi bir sınıf üretmeye gerek kalmadan
lot of arguments. nesneler içerisinde argümanlarınızı gönderebilirsiniz.
To make it obvious what properties the function expects, you can use the ES2015/ES6 Fonksiyonun beklediği argümanları garantilemek için ES2015/ES6 ile gelen
destructuring syntax. This has a few advantages: yıkım işlemi (destructuring) sözdizimini kullanabilirsiniz. Bunun birkaç avantajı var:
1. When someone looks at the function signature, it's immediately clear what 1. Dışarıdan birisi fonksiyon iskeletine baktığı zaman, fonksiyonun dışarıdan aldığı
properties are being used. özellikleri kolayca anlayabilir.
2. Destructuring also clones the specified primitive values of the argument 2. Yıkım işlemi (destructuring) aynı zamanda nesne içerisinde gönderilen ilkel
object passed into the function. This can help prevent side effects. Note: değerleri klonlar. Bu yan etkilerin engellenmesinde yardımcı olur. Not: Argüman
objects and arrays that are destructured from the argument object are NOT nesneleri tarafından yıkıma uğratılmış (destruct edilmiş) nesne ve dizi değerleri klonlanmaz.
cloned. 3. Linterlar sizi kullanılmayan değerler için uyarabilir, ki bu durumu yıkım ("destruct") işlemi olmadan
3. Linters can warn you about unused properties, which would be impossible yapmanız mümkün değildir.
without destructuring.
**Kötü:** **Kötü:**
```javascript ```javascript
function createMenu(title, body, buttonText, cancellable) { function menuOlustur(baslik, icerik, butonIcerik, iptalEdilebilir) {
// ... // ...
} }
``` ```
**İyi:** **İyi:**
```javascript ```javascript
function createMenu({ title, body, buttonText, cancellable }) { function menuOlustur({ baslik, icerik, butonIcerik, iptalEdilebilir }) {
// ... // ...
} }
createMenu({ menuOlustur({
title: 'Foo', baslik: 'Takip Et',
body: 'Bar', icerik: 'Kullanıcı takip edilsin mi?',
buttonText: 'Baz', butonIcerik: 'TAKİP ET',
cancellable: true iptalEdilebilir: true
}); });
``` ```
**[⬆ en başa dön](#içindekiler)** **[⬆ en başa dön](#içindekiler)**
### Functions should do one thing ### Fonksiyonlar tek bir görevi yerine getirmelidir
This is by far the most important rule in software engineering. When functions Bu yazılım mühendisliğindeki en önemli kuraldır. Bir fonksiyon birden fazla
do more than one thing, they are harder to compose, test, and reason about. işi yerine getirmeye çalıştığı zaman; onu oluşturmayı, test etmeyi ve onla ilgili
When you can isolate a function to just one action, they can be refactored düşünmeyi zorlaştırır. Fonksiyonunuzu tek bir görevi yerine getirmekle yükümlü
easily and your code will read much cleaner. If you take nothing else away from kıldığınız zaman onu daha kolay düzenlebilir, daha kolay dokunabilir bir hale getirmiş olacaksınız.
this guide other than this, you'll be ahead of many developers. Sadece bu maddeleri yerine getirmeniz bile sizi bir çok geliştiricinin önüne geçirecektir.
**Kötü:** **Kötü:**
```javascript ```javascript
function emailClients(clients) { function emailAboneleri(clients) {
clients.forEach((client) => { aboneler.forEach((abone) => {
const clientRecord = database.lookup(client); const aboneKaydi = veritabanı.sorgula(abone);
if (clientRecord.isActive()) { if (aboneKaydi.aktifMi()) {
email(client); email(abone);
} }
}); });
} }
...@@ -248,104 +247,104 @@ function emailClients(clients) { ...@@ -248,104 +247,104 @@ function emailClients(clients) {
**İyi:** **İyi:**
```javascript ```javascript
function emailActiveClients(clients) { function aktifEmailAboneleri(aboneler) {
clients aboneler
.filter(isActiveClient) .filter(aboneAktifMi)
.forEach(email); .forEach(email);
} }
function isActiveClient(client) { function aboneAktifMi(abone) {
const clientRecord = database.lookup(client); const aboneKaydi = veritabanı.sorgula(abone);
return clientRecord.isActive(); return aboneKaydi.aktifMi();
} }
``` ```
**[⬆ en başa dön](#içindekiler)** **[⬆ en başa dön](#içindekiler)**
### Function names should say what they do ### Fonksiyon adları ne yaptığını söylemeli
**Kötü:** **Kötü:**
```javascript ```javascript
function addToDate(date, month) { function tariheEkle(tarih, ay) {
// ... // ...
} }
const date = new Date(); const tarih = new Date();
// It's hard to tell from the function name what is added // Fonkisyon adına bakarak neyin eklendiğini anlamak zor
addToDate(date, 1); tariheEkle(tarih, 1);
``` ```
**İyi:** **İyi:**
```javascript ```javascript
function addMonthToDate(month, date) { function tariheAyEkle(ay, tarih) {
// ... // ...
} }
const date = new Date(); const date = new Date();
addMonthToDate(1, date); tariheAyEkle(1, date);
``` ```
**[⬆ en başa dön](#içindekiler)** **[⬆ en başa dön](#içindekiler)**
### Functions should only be one level of abstraction ### Fonksiyonlar bir seviye soyutlaştırılmalıdır
When you have more than one level of abstraction your function is usually Fonkiyonunuz bir seviyeden fazla soyutlaşmış ise, gereğinden fazla
doing too much. Splitting up functions leads to reusability and easier iş yapıyor demektir. Fonksiyonlarınızı görevlerine göre küçük parçalara
testing. bölmek geri kullanılabilirlik ve kolay test edilebilirlik açısından önemlidir.
**Kötü:** **Kötü:**
```javascript ```javascript
function parseBetterJSAlternative(code) { function dahaIyiJSAlternatifineDonustur(kod) {
const REGEXES = [ const REGEXLER = [
// ... // ...
]; ];
const statements = code.split(' '); const kodParcaciklari = kod.split(' ');
const tokens = []; const simgeler = [];
REGEXES.forEach((REGEX) => { REGEXLER.forEach((REGEX) => {
statements.forEach((statement) => { kodParcaciklari.forEach((kodParcacigi) => {
// ... // ...
}); });
}); });
const ast = []; const ast = [];
tokens.forEach((token) => { simgeler.forEach((simge) => {
// lex... // lex...
}); });
ast.forEach((node) => { ast.forEach((node) => {
// parse... // dönüstür...
}); });
} }
``` ```
**İyi:** **İyi:**
```javascript ```javascript
function parseBetterJSAlternative(code) { function dahaIyiJSAlternatifineDonustur(kod) {
const tokens = tokenize(code); const simgeler = simgelestir(kod);
const ast = lexer(tokens); const ast = analizEt(simgeler);
ast.forEach((node) => { ast.forEach((node) => {
// parse... // dönüstür...
}); });
} }
function tokenize(code) { function simgelestir(kod) {
const REGEXES = [ const REGEXLER = [
// ... // ...
]; ];
const statements = code.split(' '); const kodParcaciklari = kod.split(' ');
const tokens = []; const simgeler = [];
REGEXES.forEach((REGEX) => { REGEXLER.forEach((REGEX) => {
statements.forEach((statement) => { kodParcaciklari.forEach((kodParcacigi) => {
tokens.push( /* ... */ ); simgeler.push( /* ... */ );
}); });
}); });
return tokens; return simgeler;
} }
function lexer(tokens) { function analizEt(simgeler) {
const ast = []; const ast = [];
tokens.forEach((token) => { simgeler.forEach((simge) => {
ast.push( /* ... */ ); ast.push( /* ... */ );
}); });
...@@ -354,83 +353,82 @@ function lexer(tokens) { ...@@ -354,83 +353,82 @@ function lexer(tokens) {
``` ```
**[⬆ en başa dön](#içindekiler)** **[⬆ en başa dön](#içindekiler)**
### Remove duplicate code ### Yinelenen kodu kaldırın
Do your absolute best to avoid duplicate code. Duplicate code is bad because it Yinelenen kodu kaldırmak için elinizden gelenin en iyisini yapın. Tekrarlanan kodun
means that there's more than one place to alter something if you need to change kötü olma nedeni, kodunuzda mantıksal bir durumu değiştirmeye çalıştığınızda
some logic. bunu birden fazla yerde yapmanız gerekecektir. Bu da oldukça hata açıktır.
Imagine if you run a restaurant and you keep track of your inventory: all your Bir restoran işlettiğinizi ve içinde domates, soğan, biber, sarımsak vs. olan bir deponuz
tomatoes, onions, garlic, spices, etc. If you have multiple lists that olduğunu ve deponuzu takip ettiğinizi düşünün. Eğer bu iş için birden fazla liste
you keep this on, then all have to be updated when you serve a dish with tutarsanız, en ufak bir servisinizde tüm listeleri yeniden güncellemeniz gerekecektir.
tomatoes in them. If you only have one list, there's only one place to update! Eğer tek bir listeniz olursa tek bir noktadan tüm listeyi yönetebilirsiniz
Oftentimes you have duplicate code because you have two or more slightly Çoğu zaman kod tekrarına düşersiniz. Çünkü iki veya daha fazla küçük farklılığı
different things, that share a lot in common, but their differences force you olan ama çoğunlukla aynı özellikleri taşıyan iki fonksiyon sizi bu küçük nedenlerden
to have two or more separate functions that do much of the same things. Removing dolayı çoğunlukla aynı özelliklere sahip olan ve temelde aynı işi yapan
duplicate code means creating an abstraction that can handle this set of iki farklı fonksiyon yazmaya zorlar. Tekrarlayan kodu kaldırmak demek; bu farklılıkları
different things with just one function/module/class. farklı bir yerde yerine getirebilecek soyut fonksiyonlar, modüller, sınıflar yazmak demektir.
Getting the abstraction right is critical, that's why you should follow the Soyutlamayı doğru yapmak çok kritikdir. Bu yüzden devam eden kısımlardaki *Sınıflar*
SOLID principles laid out in the *Classes* section. Bad abstractions can be kısmındaki KATI kuralları takip etmelisiniz. Kötü soyutlamalar kod tekrarından da kötüdür.
worse than duplicate code, so be careful! Having said this, if you can make Bu yüzden dikkatli olmalısınız. İyi bir soyutlama yapabilirim diyorsan bunu yap!
a good abstraction, do it! Don't repeat yourself, otherwise you'll find yourself Kendini tekrar etme, aksi takdirde kendini birden fazla yeri güncellerken bulacaksın.
updating multiple places anytime you want to change one thing.
**Kötü:** **Kötü:**
```javascript ```javascript
function showDeveloperList(developers) { function gelistiriciListesiniGoster(gelistiriciler) {
developers.forEach((developer) => { gelistiriciler.forEach((gelistirici) => {
const expectedSalary = developer.calculateExpectedSalary(); const beklenenMaas = gelistirici.beklenenMaasiHesapla();
const experience = developer.getExperience(); const deneyim = gelistirici.deneyimiGetir();
const githubLink = developer.getGithubLink(); const githubLink = gelistirici.githubLink();
const data = { const veri = {
expectedSalary, beklenenMaas,
experience, deneyim,
githubLink githubLink
}; };
render(data); yazdir(veri);
}); });
} }
function showManagerList(managers) { function showManagerList(yoneticiler) {
managers.forEach((manager) => { yoneticiler.forEach((yonetici) => {
const expectedSalary = manager.calculateExpectedSalary(); const beklenenMaas = yonetici.beklenenMaasiHesapla();
const experience = manager.getExperience(); const deneyim = yonetici.deneyimiGetir();
const portfolio = manager.getMBAProjects(); const portfolio = yonetici.projeleriniGetir();
const data = { const veri = {
expectedSalary, beklenenMaas,
experience, experience,
portfolio portfolio
}; };
render(data); yazdir(veri);
}); });
} }
``` ```
**İyi:** **İyi:**
```javascript ```javascript
function showEmployeeList(employees) { function personelListesiniGoster(personeller) {
employees.forEach((employee) => { personeller.forEach((personel) => {
const expectedSalary = employee.calculateExpectedSalary(); const beklenenMaas = personel.beklenenMaasiHesapla();
const experience = employee.getExperience(); const deneyim = personel.deneyimiGetir();
const data = { const veri = {
expectedSalary, beklenenMaas,
experience deneyim
}; };
switch (employee.type) { switch (personel.tip) {
case 'manager': case 'yonetici':
data.portfolio = employee.getMBAProjects(); veri.portfolio = personel.projeleriniGetir();
break; break;
case 'developer': case 'developer':
data.githubLink = employee.getGithubLink(); veri.githubLink = personel.githubLink();
break; break;
} }
render(data); yazdir(veri);
}); });
} }
``` ```
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment