اصول طراحی SOLID

ساخت وبلاگ

اصول پباده سازی SOLID سرنامی برای پنج اصل پباده سازی طراحی اپلیکیشن میباشد: اصل تک وظیفه‌ای(SRP)، اصل تفکیک اینترفیس (ISP)، اصل بسته و گشوده (OCP)، اصل جایگزینی لیسکوف (LSP)، اصل وارونگی تعلق (DIP).


اصل تک وظیفه‌ای (Single Responsibility Principle)

طبق SRP هر کلاس یا این که ماژول مسئولیت یک بخش از عملکردهای ارائه گردیده به وسیله اپ را بر عهده داراست. این عملکردها تنها می بایست یک عامل برای تغییر‌و تحول داشته باشند و این در‌حالتی که میباشد که یک قسمت از مسئولیت نیاز به تغییر تحول داشته باشد.

public interface IUser
{
void AddUser();
void RemoveUser();
void UpdateUser();
void Logger();
void Message();
}
درصورتی که نگاهی عمیق به متدهای فوق داشته باشیم، می توانیم به روشنی دریابیم که برای IUser متدهایی مثل Log() و Message() مفهوم ندارد تا بخشی از آن باشند. بدین ترتیب ما آن را به اینترفیس‌های غیروابسته میشکنیم.

public interface IUser
{
void AddUser();
void RemoveUser();
void UpdateUser();
}
public interface ILog
{
void Logger();
}
public interface IMessage
{
void Message();
}
از اینجا می توانیم بگوییم که هر سه اینترفیس مسئولیت‌های منحصر به فرد خویش را جاری ساختن می دهند. اینک ما از تزریق تعلق (Dependency injection) برای پیاده‌سازی کدهای پایین به کار گیری میکنیم.

public class User : IUser
{
public void AddUser()
{
Console.WriteLine("Added User");
}
public void RemoveUser()
{
Console.WriteLine("Removed User");
}
public void UpdateUser()
{
Console.WriteLine("User Updated");
}
}

public class Log : ILog
{
public void Logger()
{
Console.WriteLine("Logged Error");
}
}

public class Msg : IMessage
{
public void Message()
{
Console.WriteLine("Messaged Sent");
}
}
class Class_DI
{
private readonly IUser _user;
private readonly ILog _log;
private readonly IMessage _msg;
public Class_DI(IUser user, ILog log, IMessage msg)
{
this._user = user;
this._log = log;
this._msg = msg;
}
public void User()
{
this._user.AddUser();
this._user.RemoveUser();
this._user.UpdateUser();
}
public void Log()
{
this._log.Logger();
}
public void Msg()
{
this._msg.Message();
}
}

class Example1
{
public static void Main()
{
Class_DI di = new Class_DI(new User(), new Log(), new Msg());
di.User();
di.Log();
di.Msg();
Console.ReadLine();
}
}

************End of Single Responsibility Principle*********
اصل تفکیک اینترفیس (Interface Segregation Principle)

ISP توضیح میدهد که هیچ کلاینتی نباید ناچار خواهد شد به متدهایی که از آن به کار گیری نمی‌نماید متعلق خواهد شد. به مکان داشتن یک اینترفیس بدون نقص و چند کاربردی می بایست آن را به اینترفیس‌های خرد‌خیس و مرتبط‌ تری تقسیم کنیم تا کلاینت‌ها تنها از متدهایی که مربوط به آن ها میباشد باخبر باشند.

نکته: ما تا قبل از این ISP را با نمونه قبل از SRP پوشش داده‌ایم.

public interface IUser {
void AddUser();
void RemoveUser();
void UpdateUser();
void Logger();
void Message();
}
اینترفیس‌های تعالی و چند‌منظوره به اینترفیس‌های مربوطه برای کلاینت تقسیم میشوند.

public interface IUser {
void AddUser();
void RemoveUser();
void UpdateUser();
}
public interface ILog {
void Logger();
}
public interface IMessage {
void Message();
} ** ** ** ** ** ** End of Interface Segregation Principle ** ** ** ** *
اصل گشوده و بسته (Open Closed Principle)

OCP ذکر می‌نماید که هر موجودیت قابل انعطاف‌افزاری می بایست برای پیشرفت قابلیت و امکان‌هایش گشوده باشد البته برای تغییرات بسته باشد و اذن این عمل را ندهد.

در اینجا ما به وسیله یک نرم افزار کنسول بی آلایش محرک معلمان را احتساب می کنیم.

public class Teacher
{
public int EmpId;
public string Name;
public Teacher(int id, string name)
{
this.EmpId = id;
this.Name = name;
}
public decimal Bonus(decimal salary)
{
retu salary * .2M;
}
}
class Example2
{
public static void Main()
{
Teacher teacher = new Teacher(101, "Zeko");
Console.WriteLine("Employee ID: {0} Name: {1} Bonus: {2}", teacher.EmpId,teacher.Name,teacher.Bonus(10000));
Console.ReadLine();
}
}
Teacher Employee ID: 101, Name: Zeko, Bonus: 2000.0

هم اکنون بیایید فرض کنیم ارتقاء احتساب مشوق برای معلمان دایم و موقت داریم. برای پیاده‌سازی آن بایستی کلاس مو جود و اسلوب آن را تغییر‌و تحول داده و اصلاح کنیم. در اینجا به وضوح میتوانیم بگوییم که‌این فرمان نقض‌کننده اصل Open Closed میباشد.

نقض ضابطه

public class Teacher
{
public int EmpId;
public string Name;
public string EmpType;
public Teacher(int id, string name, string emptype)
{
this.EmpId = id;
this.Name = name;
this.EmpType = emptype;
}
public decimal Bonus(decimal salary)
{
if(EmpType=="Permanent")
retu salary * .2M;
else
retu salary * .1M;
}
}
Permanent Teacher Employee ID: 101, Name: Zeko, Bonus: 2000.0

Temporarty Teacher Employee ID: 102, Name: Priyanka, Bonus: 1000.0

پس ما می بایست چه فعالیت کنیم؟

برای رعایت اصل OCP کلاس Teacher را تحت عنوان abstract class با داشتن Bonus() تحت عنوان abstract method می سازیم.

public abstract class Teacher
{
public int EmpId;
public string Name;
public Teacher(int id, string name)
{
this.EmpId = id;
this.Name = name;
}
public abstract decimal Bonus(decimal salary);
}
در حال حاضر مکتب میتواند به راحتی مشوق معلمان همیشگی خویش را با پیاده‌سازی کلاس پایین به حساب آوردن نماید.

public class PermanentTeacher : Teacher
{
public PermanentTeacher(int id, string name):base(id,name)
{
}
public override decimal Bonus(decimal salary)
{
retu salary * .2M;
}
}

class Example2
{
public static void Main()
{
Teacher teacher = new PermanentTeacher(101, "Zeko");
Console.WriteLine("Employee ID: {0} Name: {1} Bonus: {2}", teacher.EmpId,teacher.Name,teacher.Bonus(10000));
Console.ReadLine();
}
}
مزیت استعمال از کلاس abstract در اینجا این میباشد که در شرایطی‌که مکتب در آجل تمایل به دادن مشوق به معلمان موقت خویش نیز نماید دیگر مورد نیاز وجود ندارد کلاس Teacher را همچون پیشین تغییر‌و تحول دهیم، چون فعلا برای بسط گشوده میباشد.

صحیح مثل Permanent Teacher یک کلاس دیگر TemporaryTeacher اضافه نمایید.

مقالات کامل و جامع طراحی اپلیکیشن...
ما را در سایت مقالات کامل و جامع طراحی اپلیکیشن دنبال می کنید

برچسب : طراحی اپلیکیشن, نویسنده : عباسی app02 بازدید : 144 تاريخ : دوشنبه 2 خرداد 1401 ساعت: 13:52