دیزاین پترن های سی شارپ: الگوی استراتژی

جمعه 21 تیر 1398

آشنایی با دیزاین پترن ها می تواند در برنامه نویسی بسیار مفید باشد، در این مطلب قصد داریم کمی بیشتر درباره دیزاین پترنی به نام الگوی استراتژی صحبت کنیم.

 دیزاین پترن های سی شارپ: الگوی استراتژی

اگر این را شنیده اید مهم نیست باز تکرار کنید: شما باید دیزاین پترن ها را بیاموزید. به عنوان یک مهندس نرم افزار من معمولا مشکلات و مسائل زیادی را حل می کنم، با این وجود می توانم به جرات بگویم که بیشتر مشکلات شما مشکلات جدی نیستند. در واقع این مشکلات، مشکلاتی هستند که بسیاری از مهندسان نرم افزار با آن روبرو بوده اند، از آنجایی که این مشکلات در طبیعت برنامه نویسی همواره وجود داشته اند در طول زمان این مهندسان تصمیم گرفته اند که بهترین راه حل ها را برای حل این مشکلات به کل دنیا معرفی کنند که امروزه این راه حل ها را با نام دیزاین پترن ها می شناسید.


مقدمه ای درباره دیزاین پترن ها

به صورت کلی به مسائل استاندارد همراه با راه حل آنها دیزان پترن گفته می شود، این الگوهای طراحی به دو طریق مورد استفاده قرار می گیرند و مفید هستند، اول راه حل هایی را در اختیار مهندسان نرم افزار قرار می دهد تا به آنها کمک کند که مشکلاتی که با آنها روبرو هستند را حل کنند و دوم اینکه یک زبان مشترک را در اختیار توسعه دهندگان قرار می دهند تا بتوانند با این زبان درباره مشکلات خود صحبت کنند. من در این مقاله قصد دارم درباره الگوی استراتژی صحبت کنم و اقدام به معرفی آن کنم، این الگو در واقع یک دیزان پترن مشترک است که به برنامه شما کمک می کند انعطاف پذیری برنامه خود را در مورد نیازهای مختلف برقرار کنید.

 دیزاین پترن


خلاصه ای درباره Order Summary

فرض کنید که شما یک توسعه دهنده هستید که بر روی یک پروژه کار می کنید، هر بار که یک خرید انجام می شود یک OrderSummary را به سیستم downstream ارسال می کند.

public class OrderSummary

{

    public int UserId { get; set; }

    public int ItemId { get; set; }

    public DateTime PurchaseDate { get; set; }

}

ما یک شی داریم که شامل آی دی کاربر می باشد، آیدی آیتم و Purchase Date بسیار ساده ولی مفید هستند، این اپلیکیشن کمی قدیمی است به همین علت سیستم downstream شما با استفاده از XML ارتباط خود را برقرار می کند. بنابراین یک ApiClient ساده می تواند شامل موارد زیر باشد:

public class ApiClient

{

    private static HttpClient client;

    private static XmlSerializer serializer;


    static ApiClient()

    {

        //اطمینان حاصل کنید که این اساتیک باشد, https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

       

client = new HttpClient();

        

        //Serializer اگر دوباره استفاده نشود درباره مسائلی مانند عملکرد برنامه است,

       

//https://medium.com/p/comparing-c-serialization-techniques-be-wary-of-xml-38f3a4715bbd?source=email-89d87dcc9e73--writer.postDistributed&sk=fc54c021a33b48e8c1916f8d5ff44116

        var xRoot = new XmlRootAttribute();

        xRoot.ElementName = "OrderSummary";

        serializer = new XmlSerializer(typeof(OrderSummary), xRoot);

    }


    public async Task<HttpStatusCode> SendOrderSummary(string uri, OrderSummary orderSummary)

    {

        string orderSummaryString;

        using (StringWriter textWriter = new StringWriter())

        {

            serializer.Serialize(textWriter, orderSummary);

            orderSummaryString = textWriter.ToString();

        }


        var httpContent = new StringContent(orderSummaryString, Encoding.UTF8, "application/xml");

        var response = await client.PostAsync(uri, httpContent);

        return response.StatusCode;

    }

}

در این کد هیچ چیز باعث توقف برنامه نمی شود، این فقط یک کلاس ساده است که موضوعات را به صورت سریالی در می آورد و آن را به uri ارسال می کند.

 دیزاین پترن

نیازمندی های جدید

اخبار جالبی در راه است، شرکت شما در حال پیشرفت می باشد، نیازمندی های شما نیز به همین علت تغییر پیدا کرده است، حالا ما باید از یک Api Client پشتیبانی کنیم که پیغام ها را در جیسون بپذیرد. در اینجا چندین مورد از آپشن های مختلف وجود دارد که شما باید آنها را انتخاب کنید:

1-      یک XMLApi Client و یک JsonApi Client بسازید.

2-      یک متد Send Order Summary Xml و Send Order Summary Json بسازید.

3-      از الگوی استراتژی استفاده کنید تا محتوای تولید شده را به صورت انتزاعی در بیارید.

از آنجایی که این مقاله درباره دیزاین پترن استراتژی می باشد اجازه دهید که آپشن شماره سوم را انتخاب کنیم.

ما یک اینترفیس جدید می سازیم تا یک قرارداد برای ساخت محتوای http تعریف کنیم.

public interface IOrder Summary Request Builder

{

    Http Content Build(Order Summary order Summary);

}

حال ما دو کلاس بهم چسبیده را تعریف می کنیم تا این اینترفیس جدید را پیاده سازی کنیم، یکی برای XML و دیگری برای JSON :

کلاس اول:

public class OrderSummaryXmlRequestBuilder : IOrderSummaryRequestBuilder

{

    private static XmlSerializer serializer;


    static OrderSummaryXmlRequestBuilder()

    {

        var xRoot = new XmlRootAttribute();

        xRoot.ElementName = "OrderSummary";

        serializer = new XmlSerializer(typeof(OrderSummary), xRoot);

    }


    public HttpContent Build(OrderSummary orderSummary)

    {

        string orderSummaryString;

        using (StringWriter textWriter = new StringWriter())

        {

            serializer.Serialize(textWriter, orderSummary);

            orderSummaryString = textWriter.ToString();

        }


        return new StringContent(orderSummaryString, Encoding.UTF8, "application/xml");

    }

}

کلاس دوم:

public class OrderSummaryJsonRequestBuilder : IOrderSummaryRequestBuilder

{

    public HttpContent Build(OrderSummary orderSummary)

    {

        var orderSummaryString = JsonConvert.SerializeObject(orderSummary);

        return new StringContent(orderSummaryString, Encoding.UTF8, "application/json");

    }

}

 دیزاین پترن


به روز رسانی ApiLient در این دیزاین پترن

حال ApiClient خود را به روز رسانی می کنیم تا با استفاده کردن از این اینترفیس بتوانیم محتوای http را برای پیغام خود تولید کنیم:

public class ApiClient

{

    private static HttpClient client;

    readonly IOrder Summary Request Builder order Summary Request Builder;


    static Api Client()

    {

        client = new Http Client();

    }


    public ApiClient(IOrder Summary Request Builder order SummaryRequest Builder)

    {

        this.orderSummaryRequestBuilder = orderSummaryRequestBuilder;

    }


    public async Task<HttpStatusCode> SendOrderSummary(string uri, OrderSummary orderSummary)

    {

        //فراخوانی اینترفیس برای تولید محتوای http

        var httpContent = orderSummaryRequestBuilder.Build(orderSummary);

        var response = await client.PostAsync(uri, httpContent);

        return response.StatusCode;

    }

}

همانطور که مشاهده می کنید متد Send Order Summary ما کمی سخت به نظر می رسد، این متد در واقع تمام تمرکز خود را بر روی تولید محتوای XML و JSON گذاشته است. حال دیگر Api Client ما درباره نوع محتوایی که ارسال می کند هیچگونه اطلاعی ندارد. در واقع رئیس شما در هر مجموعه ای دوست دارد که شما بتوانید با استفاده از دیزاین پترن ها و الگوی طراحی استراتژی بتوانید قابلیت استفاده مجدد برنامه خود را بهبود ببخشید.

 دیزاین پترن


برداشت های مهم و تفکر بیشتر درباره این موضوع

الگوی استراتژی یک دیزاین پترن مفید است که برای جدا کردن سیستم ها مورد استفاده قرار می گیرد. Api Client ما حالا می تواند هر نوع محتوای جدیدی را پشتیبانی کند بدون آنکه نیاز داشته باشد تغییراتی را در آنها ایجاد کند. برای این کار کافی است اینترفیس IOrder Summary Builder را با استفاده از هر نوع محتوایی که دارید پیاده سازی کنید که برای انجام این کار نیز نیاز دارید که به اندازه کافی خوب باشید.

یکی دیگر از پیشرفت هایی که ممکن است در این مسیر برای استفاده از دیزاین پترن ها میسر شود این است که الگوی استراتژی را دوباره به کار گیرید تا بدنه پاسخگوی برنامه را به یک کلاس سی شارپ تجزیه کنید. برای انجام این کار کافی است که یک اینترفیس به نام “IOrder Summary Response Builder” را با هر دو نسخه XML و JSON بسازید و از این کار خود نهایت لذت را ببرید.

 دیزاین پترن

ایمان مدائنی

نویسنده 1299 مقاله در برنامه نویسان
  • C#.net
  • 3k بازدید
  • 2 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید