Flutter: Best Practices 💫 🌌 ✨
Tags: flutter, dart, bestpractices, flutterdev
Published: 2022-02-05 19:51:18

Not: Bu yazı [Kinjal Dhamat](https://medium.com/flutter-community/flutter-best-practices-and-tips-7c2782c9ebb5#:~:text=Naming%20convention%3A,parameters%20should%20be%20in%20lowerCamelCase.)'ın linkte paylaşılan makalesinin Türkçe çevirisi ve özeti nitelini taşır. Orijinal içeriğe linkten ulaşabilirsiniz.



Best practice'ler, bir alanda kabul edilmiş profesyonel standartlardır ve herhangi bir programlama dilinin kod kalitesini, okunabilirliğini, sürdürülebilirliğini ve sağlamlığını arttırır.



**Adlandırma kuralı:**

Class, enum, typedef ve extension adları `UpperCamelCase` olmalıdır.

```
class MainScreen { ... }
enum MainItem { .. }
typedef Predicate<T> = bool Function(T value);
extension MyList<T> on List<T> { ... }
```


Kitaplıklar, paketler, klasörler ve kaynak dosya adları `snake_case(lowercase_with_underscores)` olmalıdır.

```
library firebase_dynamic_links;
import 'socket/socket_manager.dart';
```
Değişken, constant(sabit), paremetre, ve adlandırılmış parametre isimleri `lowerCamelCase` olmalıdır


```
var item;
const bookPrice = 3.14;
final urlScheme = RegExp('^([a-z]+):');
void sum(int bookPrice) {
  // ...
}
```



`lib` içerisindeki dosyalar için göreli içe aktarmayı kullanın


Relative ve absolute importlar birlikte kullanıldığında, aynı sınıf iki farklı yoldan import edildiğinde karışıklık meydana gelebilir. Bu durumdan kaçınmak için lib/klasörde relative path kullanmalıyız.


```
// Yapma
import 'package:demo/src/utils/dialog_utils.dart';


// Yap
import '../../../utils/dialog_utils.dart';
```

**Class üyeleri için türleri belirtin:**

Değer türü (value type) bilindiğinde her zaman üyenin türünü belirtin.
Mümkün olduğunca var kullanmaktan kaçının.

```
//Yapma
var item = 10;
final car = Car();
const timeOut = 2000;


//Yap
int item = 10;
final Car bar = Car();
String name = 'john';
const int timeOut = 20;
```



**`as` operatörünü kullanmaktan kaçının bunun yerine is operatörünü kullanın**

Genellikle, `as` cast operatörü, cast mümkün değilse bir istisna atar. Bir istisnanın atılmasını önlemek için `is` operatörünü kullanın.


```
//Yapma
(item as Animal).name = 'Lion';


//Yap
if (item is Animal)
  item.name = 'Lion';
```



**Conditional expression (koşullu ifade) yerine `if` koşulunu kullanın**

Çoğu zaman, Satır ve Sütun'daki bazı koşullara dayalı olarak bir widget oluşturmamız gerekir. Conditional expression(koşullu ifade) her durumda null döndürür bu sebeple `if` koşulunu kullanmak daha iyi bir kullanımdır.


```
//Yapma
Widget getText(BuildContext context) {
  return Row(
    children: [
      Text("Hello"),
      Platform.isAndroid ? Text("Android") : null,
      Platform.isAndroid ? Text("Android") : SizeBox(),
      Platform.isAndroid ? Text("Android") : Container(),
    ]
  );
}


//Yap
Widget getText(BuildContext context) {
  return Row(
      children: 
      [
        Text("Hello"), 
        if (Platform.isAndroid) Text("Android")
      ]
  );
}
```



**`??` ve `?.` operatörlerini kullanın**


`if null` yerine `??` operatörünü, `null aware` yerine ise `?.` operatörünü kullanın.



```
//Kullanma
v = a == null ? b : a;

//Kullan
v = a ?? b;


//Kullanma
v = a == null ? null : a.b;

//Kullan
v = a?.b;
```



**Spread operatörünü kullanın**

Mevcut öğeler başka bir dizide depolandığında, spread collection sözdizimi daha basit koda sağlar.


```
//Kullanma
var y = [4,5,6];
var x = [1,2];
x.addAll(y);


//Kullan
var y = [4,5,6];
var x = [1,2,...y];
```



**Cascades operatörünü kullanın**

Aynı nesne üzerinde bir dizi işlem yapmak istiyorsanız Cascades(..) operatörünü kullanın.


```
// Kullanma
var path = Path();
path.lineTo(0, size.height);
path.lineTo(size.width, size.height);
path.lineTo(size.width, 0);
path.close();  


// Kullan
var path = Path()
..lineTo(0, size.height)
..lineTo(size.width, size.height)
..lineTo(size.width, 0)
..close(); 
```




**Raw string kullanın**

Yalnızca string bir ifade içinde \ ve $ kullanmanız gerekiyorsa raw string kullanın.

```
//Kullanma
var s = 'This is demo string \\ and \$';


//Kullan
var s = r'This is demo string \ and $';
```



**Değişkenleri null atayarak başlatmayın**

Dart'ta, değeri belirtilmediğinde değişken otomatik olarak null olarak başlatılır, bu nedenle null eklemek gereksizdir.

```
//Kullanma
int _item = null;


//Kullan
int _item;
```



**Expression function ifadesini kullanın**

Yalnızca bir ifade içeren işlevler için expression function kullanabilirsiniz. ( => Ok) gösterimi, expression function için kullanılır.

```
//Kullanma
get width {
  return right - left;
}
Widget getProgressBar() {
  return CircularProgressIndicator(
    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
  );
}


//Kullan
get width => right - left;
Widget getProgressBar() => CircularProgressIndicator(
      valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
    );
```



**`print()` çağrılarından kaçının**

`print()` ve `debugPrint()` konsola bir şey yazdırmak için kullanılır.
`print()` kullanıyorsanız ve çıktınız çok fazlaysa, Android bazen bazı log satırları atar. Bunu önlemek için` debugPrint()` kullanın.
Log datanız çok fazla veri içeriyorsa, `dart:developer` `log()` kullanın.
Bu, log çıktısına biraz daha ayrıntı düzeyi ve bilgi eklemenize olanak sağlar.




**Private olmayan local tanımlayıcılar için isimlendirmelerin başında alt çizgi (_) kullanmaktan kaçının.**



**Dizeleri oluşturmak için enterpolasyon kullanın**
Bir string oluşturmak için + kullanarak uzun zincirler oluşturmak yerine string ifadeyi daha temiz ve daha kısa tutmak için  $ enterpolasyonu kullanın.

```
//Kullanma
var description = 'Hello, ' + name + '! You are ' + (year - birth).toString() + ' years old.';


// Kullan
var description = 'Hello, $name! You are ${year - birth} years old.';
```



**Bir tear-off işlemi yapıldığında lambda oluşturmayın**

Kendisine iletilen aynı argümanlara sahip methodu çağıran bir fonksiyonunuz varsa, çağrıyı manuel olarak bir lambda içine sarmanız gerekmez.


```
List<String> names=[]
  
// Kullanma
names.forEach((name) {
  print(name);
});


// Kullan
names.forEach(print);
```



**async/await ifadelerini kullanın**

Asenkron kodun okunması ve hataların ayıklanması zordur. async/ await sözdizimi okunabilirliği artırır.


```
// Kullanma
Future<int> countActiveUser() {
  return getActiveUser().then((users) {
    
    return users?.length ?? 0;

  }).catchError((e) {
    log.error(e);
    return 0;
  });
}


// Kullan
Future<int> countActiveUser() async {
  try {
    var users = await getActiveUser();
     
    return users?.length ?? 0;
  
  } catch (e) {
    log.error(e);
    return 0;
  }
}
```



**Widget'ları alt Widget'lara ayırın.**

Bir setState() durumu çağrıldığında, tüm alt widget'lar yeniden oluşturulur. Bu nedenle, bir widget'ı küçük widget öğelerine bölerek, setState() ifadesini sadece arayüzün değişmesi gerektiği yerlerde çağırabilirsiniz.


```
Scaffold(
  appBar: CustomAppBar(title: "Verify Code"), // Sub Widget
  body: Container(
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        TimerView( // Sub Widget
            key: _timerKey,
            resendClick: () {})
      ],
    ),
  ),
)
```



**Uzun bir liste için ListView.builder kullanın**

Sonsuz veya çok büyük listelerle çalışırken, performansı artırmak için genellikle bir `ListView` builder kullanılması önerilir .
Varsayılan olarak ListView constructor , tüm listeyi bir kerede oluşturur. ListView.builder lazy bir liste oluşturur ve kullanıcı listeyi aşağı kaydırırken, Flutter isteğe bağlı widget'lar oluşturur.




**Widget'larda Const kullanın**

SetState çağrısı yapıldığında bir widget'ın değişmesini istemiyorsanız onu constant olarak tanımlayın. Bu durum Widget'ın yeniden oluşturulmasını engelleyerek performansı artırır.

```
Container(
      padding: const EdgeInsets.only(top: 10),
      color: Colors.black,
      child: const Center(
        child: const Text(
          "No Data found",
          style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w800),
        ),
      ),
    );
```



Umarım bu yazı, uygulamanızın performansını artırırken Flutter kodunuzu daha okunaklı hale getirmek için size birkaç fikir vermiştir. 💙✨


[reference](https://medium.com/flutter-community/flutter-best-practices-and-tips-7c2782c9ebb5#:~:text=Naming%20convention%3A,parameters%20should%20be%20in%20lowerCamelCase.)