CodeMaid adalah ekstensi open source untuk visual studio yang bisa digunakan untuk melihat tingkat kompleksitas code program kita selain melakukan formating dan mengorganisir kode. Semakin tinggi nilai kompleksitas sebuah fungsi, semakin butuh fungsi itu untuk direfactor. Karena salah satu prinsip clean code adalah satu method harusnya hanya memiliki 1 high level abstraksi.
contoh code dengan kompleksitas yang tinggi seperti di bawah ini.
private Expression<Func<Vehicle, bool>> CreateVehicleFilter(VehicleFilterInput input) { Expression<Func<Vehicle, bool>> queryFilter = PredicateHelper.True(); if (!string.IsNullOrEmpty(input.Name)) queryFilter = queryFilter.And(ve => ve.VehicleTranslations.Any(t => t.Language == input.Language) ? ve.VehicleTranslations.Any(t => t.Language == input.Language && t.TranslatedText.ToLower().Contains(input.Name.ToLower())) : ve.Name.ToLower().Contains(input.Name.ToLower())); if (!string.IsNullOrEmpty(input.InternalNumber)) queryFilter = queryFilter.And(ve => ve.InternalNumber.ToLower().Contains(input.InternalNumber.ToLower())); if (!string.IsNullOrEmpty(input.ChassisNumber)) queryFilter = queryFilter.And(ve => ve.Chassis.ToLower().Contains(input.ChassisNumber.ToLower())); if (input.VehicleBrandId != null && input.VehicleBrandId != 0) queryFilter = queryFilter.And(ve => ve.VehicleModel.VehicleBrand.Id == input.VehicleBrandId); if (input.VehicleModelId != null && input.VehicleModelId != 0) queryFilter = queryFilter.And(ve => ve.VehicleModel.Id == input.VehicleModelId); if (input.DateOfEntry != null && input.DateOfEntry != DateTime.MinValue && input.DateOfEntryTo != null && input.DateOfEntryTo != DateTime.MinValue) queryFilter = queryFilter.And(ve => ve.DateEntry >= input.DateOfEntry && ve.DateEntry <= input.DateOfEntryTo); else { if (input.DateOfEntry != null && input.DateOfEntry != DateTime.MinValue) queryFilter = queryFilter.And(ve => ve.DateEntry >= input.DateOfEntry); if (input.DateOfEntryTo != null && input.DateOfEntryTo != DateTime.MinValue) queryFilter = queryFilter.And(ve => ve.DateEntry <= input.DateOfEntryTo); } if (input.ReleaseDate != null && input.ReleaseDate != DateTime.MinValue && input.ReleaseDateTo != null && input.ReleaseDateTo != DateTime.MinValue) { queryFilter = queryFilter.And(ve => (ve.DateActualRelease >= input.ReleaseDate && ve.DateActualRelease <= input.ReleaseDateTo) || (ve.DateSupposedRelease >= input.ReleaseDate && ve.DateSupposedRelease <= input.ReleaseDateTo)); } else { if (input.ReleaseDate != null && input.ReleaseDate != DateTime.MinValue) { queryFilter = queryFilter.And(ve => (ve.DateActualRelease >= input.ReleaseDate) || (ve.DateSupposedRelease >= input.ReleaseDate)); } if (input.ReleaseDateTo != null && input.ReleaseDateTo != DateTime.MinValue) { queryFilter = queryFilter.And(ve => (ve.DateActualRelease <= input.ReleaseDateTo) || (ve.DateSupposedRelease <= input.ReleaseDateTo)); } } if (!string.IsNullOrEmpty(input.Status)) queryFilter = queryFilter.And(ve => ve.Status.ToLower().Contains(input.Status.ToLower())); return queryFilter; }
Terlihat pada CodeMaid Spade di Visual Studio fungsi tersebut kompleksitasnya sangat tinggi, di atas nilai 10.
Kita refactor, dengan membaginya ke dalam beberapa fungsi yang lebih kecil seperti ini.
private Expression<Func<Vehicle, bool>> CreateVehicleFilter(VehicleFilterInput input) { Expression<Func<Vehicle, bool>> queryFilter = PredicateHelper.True(); FilterVehicleByName(input, ref queryFilter); FilterByDateOfEntry(input, ref queryFilter); FilterByChassisNumber(input, ref queryFilter); FilterByInternalNumber(input, ref queryFilter); FilterByVehicleBrand(input, ref queryFilter); FilterByVehicleModel(input, ref queryFilter); FilterByRangeReleaseDate(input, ref queryFilter); FilterByStatus(input, ref queryFilter); return queryFilter; }
CodeMaid akan menunjukan bahwa tingkat kompleksitasnya sekarang jauh lebih sedikit.