8️⃣: از الگوی آبجکت نتیجه (Result Object Pattern) استفاده کنید 🎁
من گفتم که استفاده از استثناها برای کنترل جریان را ترجیح نمیدهم. اما چگونه میتوانیم این مشکل را برطرف کنیم؟
یک راهحل، استفاده از الگوی آبجکت نتیجه است.
شما میتوانید از یک کلاس جنریک Result برای نمایش انواع نتایج یا یک کلاس خاص مانند ProcessOrderResult استفاده کنید.
برای اینکه آبجکتهای نتیجه شما کپسوله شوند، مجموعهای از متدهای factory برای ایجاد نوع نتیجه مشخص، ارائه دهید.
public class ProcessOrderResult
{
private ProcessOrderResult(
ProcessOrderResultType type,
long orderId,
string message)
{
Type = type;
OrderId = orderId;
Message = message;
}
public ProcessOrderResultType Type { get; }
public long OrderId { get; }
public string? Message { get; }
public static ProcessOrderResult NotProcessable() =>
new(ProcessOrderResultType.NotProcessable, default, "Not processable");
public static ProcessOrderResult TooManyLineItems(long oderId) =>
new(ProcessOrderResultType.TooManyLineItems, orderId, "Too many items");
public static ProcessOrderResult NotReadyForProcessing(long oderId) =>
new(ProcessOrderResultType.NotReadyForProcessing, oderId, "Not ready");
public static ProcessOrderResult Success(long oderId) =>
new(ProcessOrderResultType.Success, orderId, "Success");
}
استفاده از یک enum مانند ProcessOrderResultType، مصرف کردن آبجکت نتیجه را با switch expressions آسانتر میکند. در اینجا enum برای نمایش ProcessOrderResult.Type آمده است:
public enum ProcessOrderResultType
{
NotProcessable = 0,
TooManyLineItems = 1,
NotReadyForProcessing = 2,
Success = 3
}
و حالا متد Process به این شکل در میآید:
const int MaxNumberOfLineItems = 15;
public ProcessOrderResult Process(Order? order)
{
if (!IsProcessable(order))
{
return ProcessOrderResult.NotProcessable();
}
if (order.Items.Count > MaxNumberOfLineItems)
{
return ProcessOrderResult.TooManyLineItems(order.Id);
}
if (order.Status != OrderStatus.ReadyToProcess)
{
return ProcessOrderResult.NotReadyForProcessing(order.Id);
}
order.IsProcessed = true;
order.Status = OrderStatus.Processed;
return ProcessOrderResult.Success(order.Id);
}
static bool IsProcessable(Order? order)
{
return order is not null &&
order.IsVerified &&
order.Items.Any();
}
`
در اینجا نحوه استفاده از یک enum برای ProcessOrderResult.Type به شما اجازه میدهد یک switch expression بنویسید:
var result = Process(order);
result.Type switch
{
ProcessOrderResultType.TooManyLineItems =>
Console.WriteLine($"Too many line items: {result.OrderId}"),
ProcessOrderResultType.NotReadyForProcessing =>
Console.WriteLine($"Not ready for processing {result.OrderId}"),
ProcessOrderResultType.Success =>
Console.WriteLine($"Processed successfully {result.OrderId}"),
_ => Console.WriteLine("Failed to process: {OrderId}", result.OrderId),
};
نکات پایانی 📝
تمام شد، ۸ نکته برای نوشتن کد تمیز:
1️⃣ اصل بازگشت زودهنگام
2️⃣ ادغام چندین دستور if
3️⃣ استفاده از LINQ برای اختصار
4️⃣ جایگزینی عبارت بولین با متد
5️⃣ ترجیح دادن پرتاب استثناهای سفارشی
6️⃣ جایگزینی اعداد جادویی با ثابتها
7️⃣ جایگزینی رشته جادویی با enumها
8️⃣ استفاده از الگوی آبجکت نتیجه
نوشتن کد تمیز، موضوعی از تمرین هدفمند و تجربه است.
اکثر مردم در مورد اصول کدنویسی تمیز میخوانند، اما تعداد کمی تلاش میکنند تا آنها را روزانه به کار ببرند.
اینجاست که شما میتوانید خود را متمایز کنید.
امیدوارم این مطلب مفید بوده باشد.
اقدام عملی امروز: 🚀
نگاهی به پروژه خود بیندازید و ببینید آیا برخی از اشتباهاتی که من در اینجا برجسته کردم را مرتکب میشوید یا نه. و سپس آنها را با استفاده از نکات کد تمیزی که با شما به اشتراک گذاشتم، برطرف کنید.