Mehmet Oya

Hap Bilgi 9: Code Review Roadmap

Dec 26, 2023
5 minutes

Developer hap bilgi sever; 9. bölüm: Code Review Roadmap. Aslında ilişkisi olan bir konuyu 7 bölümde işlemiştim. Göz atmak isteyenler için; Hap Bilgi 7: Bir Pull Requesti Kıdemli Bir Geliştirici Gibi İncelemek

Http method ve status code kullanımı

  • Request objesi hassas veri içermiyorsa, resource dönen endpoint’ler HttpGet olarak kullanılmalıdır.
  • ID; hassas bir veri değilse, resource’un gerçek kimliği ise, composite değilse, GET, PUT, DELETE işlemlerinde “api/resource/{id}” url formatı kullanılmalıdır.
  • Net bir standardı olmasa da proje içerisinde standart olması açısından, durum bildiren (true/false) metotlar GET ile kullanılmalı ve durum için bir model dönmelidir.
{
    "IsPresent": true
}

Detaylı bilgi: https://www.rfc-editor.org/rfc/rfc2616

Url isimlendirme

/api/resource/resource-action/{id}

Url’ler isimlendirilirken yukarıdaki format uygulanmalı, cümle gibi isimlendirmelerden kaçınılmalı, url anlaşılır ve sade tutulmalıdır.

Detaylı bilgi: https://restfulapi.net/resource-naming/

Değişken isimlendirme kuralları

  • Class, interface, struct isimleri PascalCase olarak kullanılmalıdır.
  • Class private değişkenleri _camelCase olarak kullanılmalıdır.
  • Metot parametreleri ve değişkenleri camelCase olarak kullanılmalıdır.
  • Sabitler PascalCase olarak isimlendirilmelidir.

Detaylı bilgi: https://docs.microsoft.com/tr-tr/dotnet/csharp/fundamentals/coding-style/coding-conventions#naming-conventions

Kodların yorum satırı olarak bırakılması

Kodun okunabilirliğini azaltacağı için geliştirilmesi iptal edilen kod blokları ileride tekrar lazım olur düşüncesi ile yorum satırı yapılmamalıdır. Tekrar kullanılacağı düşünülen kod blokları için git stash özelliği kullanılabilir.

Kaynak: https://rules.sonarsource.com/csharp/RSPEC-125

Magic number

Anlamını sadece geliştiren kişini bileceği belirsiz sayılar kullanılmamalı, anlamlı isimlendirilmiş sabitlerle ifade edilmelidir.

Kaynak: https://en.wikipedia.org/wiki/Magic_number_(programming)

Async metotlara cancellationToken geçilmesi

cancellationToken’ın işlemin başladığı noktadan bittiği noktaya kadar, metotlar izin verdiği ölçüde geçilmesi beklenmektedir. Yani cancellationToken bekleyen tüm metotlara eğer parametre olarak elimizde mevcutsa cancellationToken geçilmelidir.

Detaylı bilgi: https://docs.microsoft.com/tr-tr/dotnet/standard/threading/cancellation-in-managed-threads

Exception’ların öldürülmesi, stacktrace’in kaybı

// Hatalı
try
{
    ...
}
catch
{
    // ignore
}
  • try-catch bloklarında akışı kırmak istemiyorsak (throw eklenmediyse) loglama yapmamız gerekmektedir.
// Beklenen
try
{
    ...
}
catch (Exception ex)
{
    _logger.LogError(ex, ex.Message);
}
  • throw ex; kullanımı stackTrace’i kaybedeceği için kullanımı tavsiye edilmez.
// Hatalı
try
{

}
catch (Exception ex)
{
    throw ex;
}
// Beklenen
try
{

}
catch (Exception)
{
    throw;
}

kaynak: https://docs.microsoft.com/en-gb/dotnet/fundamentals/code-analysis/quality-rules/ca2200

Task, async, await, kullanımı

Task metot içerisinde async metotlar await ile bekletilmelidir. .Result, .GetResult() dikkatli kullanılmalı hatta Deadlock’a sebebiyet vereceği için kaçınılmalıdır.

Detaylı bilgi: https://docs.microsoft.com/tr-tr/dotnet/csharp/programming-guide/concepts/async/

Lock kullanımında double check pattern

Lock işlemini daha performanslı hâle getirmek için double check pattern uygulanmalıdır.

Detaylı bilgi: https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_C#

Disposable pattern

Dispose işlemi garbage collection mekanizmasının en verimli çalışacağı, microsoft’un önerdiği şekilde uygulanmalıdır.

Detaylı bilgi: https://docs.microsoft.com/tr-tr/dotnet/standard/garbage-collection/implementing-dispose

Kullanılmayan kodlar

Kullanılmayan class, metot, değişken, using vb. kodlar kod okunabilirliğini düşüreceği için silinmelidir.

kaynak: https://rules.sonarsource.com/csharp/RSPEC-1144

3th party service Request-Response, Entity Model, Domain Model/Args, core Request-Response isimlendirme kuralları

  • 3th party service Request: Input ile bitmelidir, örn: CreateCustomerInput
  • 3th party service Response: Output ile bitmelidir, örn: CustomerOutput
  • Entity model: Tablo adı ile aynı isimlendirilir
  • Domain service model: Model ile bitmelidir, örn: CustomerModel
  • Domain service metot parametresi: Args ile bitmelidir, örn: CreateCustomerArgs
  • Microservice request: Request ile bitmelidir, örn: CreateCustomerRequest
  • Microservice response: Response ile bitmelidir, örn: CustomerResponse

Adapter, Command/Query Handler, Controller içerisinde business logic yazılması

Business logic yalnızca domain service metotları içerisinde yazılmalıdır.

Yazılan tek satır kodun ekrana sığmayacak kadar uzun olması

var categories = _categoryService.GetAllAsync(args, cancellationToken).Where(p => categoryTypes.Contains(p.Type)).SubCategories.Where(p => p.Status == CategoryStatus.Active)...

şeklinde uzayan fluent kodlar daha rahat okunabilmesi için alt alta yazılmalıdır.

var categories = _categoryService
    .GetAllAsync(args, cancellationToken)
    .Where(p => categoryTypes.Contains(p.Type))
    .SubCategories
    .Where(p => p.Status == CategoryStatus.Active)
    ...

Tekrar eden kod bloklarının private metot olarak kullanılması

Tekrar eden kod bakımı zorlaştıracağı için private metotlar ile tekilleştirilmeli ve gerekli yerlerde kullanılmalıdır.

public int CalculateFoo(int x, int y)
{
    var bar = x / y;
    var foo = bar + x;

    ExecuteOtherInterestingCodes(foo);

    return foo;
}

public int CalculateBaz(int x, int y)
{
    var bar = x / y;
    var baz = bar + x;

    ExecuteOtherMagicCodes(baz);

    return baz;
}

yerine

private int Calculate(int x, int y)
{
    var bar = x / y;
    return bar + x;
}

public int CalculateFoo(int x, int y)
{
    var foo = Calculate(x, y);

    ExecuteOtherInterestingCodes(foo);

    return foo;
}

public int CalculateBaz(int x, int y)
{
    var baz = Calculate(x, y);

    ExecuteOtherMagicCodes(baz);

    return baz;
}

şeklinde kullanılmalıdır.

Class içerisindeki öğelerin sıralaması

Net bir standardı olmasa da proje bütünlüğünü korumak adına aşağıdaki sıralama kullanılmalıdır.

  • constants
  • variables
  • constructor
  • private methods
  • protected methods
  • public methods

Diğer notlar

  • Tüm projeyi etkileyen ve Master’a geçmiş olan bir geliştirmeden haberdar isek review edilen kişiyi bu konuda yönlendirmek gerekir.
  • Command ve Query’lerde auth attribute kullanılmalıdır.
  • Typo kontrolü yapılmalı, isimlendirmelerin İngilizce olduğuna dikkat edilmelidir.