<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمد خوش کشت</title>
        <link>https://virgool.io/feed/@m_khoshkesht</link>
        <description>طراح  و توسعه دهنده نرم افزار، با سوابق مختلف در زمینه زیر ساخت و SQL Server</description>
        <language>fa</language>
        <pubDate>2026-04-14 23:12:13</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/253541/avatar/BQ6p0H.jpeg?height=120&amp;width=120</url>
            <title>محمد خوش کشت</title>
            <link>https://virgool.io/@m_khoshkesht</link>
        </image>

                    <item>
                <title>Top 10 New .NET 6.0 API</title>
                <link>https://virgool.io/@m_khoshkesht/top-10-new-net-60-api-ik0bwkjb9fey</link>
                <description>در .NET 6 API های جدید را برای توسعه ساده تر و سریعتر معرفی کرده که به توضیح آنها میپردازیم:Top 10 New .NET 6.0 - Recompile.ir
1- تا به حال دو کلاس DateTime , TimeSpan برای هندل کردن عملیات تاریخ وجود داشت اما د ر.NET 6 دو تابع DateOnly , TimeOnly برای کار راحت تر با تاریخ و زمان اضافه شده استvar dateOnly = new DateOnly(2021,7,7);
Assert.IsTrue(dateOnly.ToString() == &amp;quot07-Jul-21&amp;quot);
Assert.IsTrue(dateOnly.AddMonths(1).ToString() == &amp;quot07-Aug-21&amp;quot);
 
var timeOnly = new TimeOnly(11, 43, 57);
Assert.IsTrue(timeOnly.ToString() == &amp;quot11:43 AM&amp;quot);
Assert.IsTrue(timeOnly.AddHours(1) &gt; timeOnly);
Assert.IsTrue(timeOnly.AddHours(1) - timeOnly == new TimeSpan(1,0,0));
 
DateTime dateTime = dateOnly.ToDateTime(timeOnly);
Assert.IsTrue(dateTime.ToString() == &amp;quot07-Jul-21 11:43:57 AM&amp;quot);
Assert.IsTrue(DateOnly.FromDateTime(dateTime) == dateOnly);
Assert.IsTrue(TimeOnly.FromDateTime(dateTime) == timeOnly);2- برای پرفورمنس بالاتر صف اولویت دار PriorityQueue اضافه شده است که در آن اولویت آیتمها قبل تغییر نیست (سریعتر پیمایش می شود) و پیاده سازی آن هم الزاما پایدار نمی باشد. صف اولویت دار زمانی پایدار است که آیتمها به همان ترتیب برداشته شدن وارد صف شوندvar youngerFirstQueue = new PriorityQueue&lt;string, int&gt;();
youngerFirstQueue.Enqueue(&amp;quotLena&amp;quot, 7);
youngerFirstQueue.Enqueue(&amp;quotPatrick&amp;quot, 46);
youngerFirstQueue.Enqueue(&amp;quotPaul&amp;quot, 7);
Assert.IsTrue(youngerFirstQueue.Dequeue() == &amp;quotLena&amp;quot);
Assert.IsTrue(youngerFirstQueue.Dequeue() == &amp;quotPaul&amp;quot);
Assert.IsTrue(youngerFirstQueue.Dequeue() == &amp;quotPatrick&amp;quot);3- Index و Range در LINQ قابل استفاده شده اند.Index , Range از قابلیتهای C#8 هستند. توضیح// 6 element indexed from 0 to 5
var arr = new [] {0, 1, 2, 3, 4, 5};
Assert.IsTrue(arr.ElementAt(^2) == 4); // Take the second element from the end
Assert.IsTrue(arr.ElementAtOrDefault(^10) == default); // No such index
Assert.IsTrue(arr.Take(2..4).SequenceEqual(new[] { 2, 3 }));
Assert.IsTrue(arr.Take(2..^2).SequenceEqual(new[] { 2, 3 }));
 
// New Index Range usage with their pre .NET 6 equivalent
Assert.IsTrue(arr.Take(..2).SequenceEqual(new[] { 0, 1 }));
Assert.IsTrue(arr.Take(2).SequenceEqual(new[] { 0, 1 }));
 
Assert.IsTrue(arr.Take(2..).SequenceEqual(new[] { 2, 3, 4, 5 }));
Assert.IsTrue(arr.Skip(2).SequenceEqual(new[] { 2, 3, 4, 5 }));
 
Assert.IsTrue(arr.Take(^2..).SequenceEqual(new[] { 4, 5 }));
Assert.IsTrue(arr.TakeLast(2).SequenceEqual(new[] { 4, 5 }));
 
Assert.IsTrue(arr.Take(..^2).SequenceEqual(new[] { 0, 1, 2, 3 }));
Assert.IsTrue(arr.SkipLast(2).SequenceEqual(new[] { 0, 1, 2, 3 }));4- برای FirstOrDefault(), LastOrDefault() SingleOrDefault() میتوانید مقدار پیش فرض تعیین کنیدvar arr = new [] {0, 1, 2, 3, 4, 5};
Assert.IsTrue(arr.FirstOrDefault(x =&gt; x &gt; 6) == 0);
Assert.IsTrue(arr.FirstOrDefault(x =&gt; x &gt; 6, -1) == -1);5- قابلیتهای MaxBy(), MinBy(), DistinctBy(), UnionBy(), IntersectBy(), ExceptBy() اضافه شد اندvar buckets1 = new[] {
   (Color: &amp;quotRed&amp;quot, Price: 7), 
   (Color: &amp;quotBlue&amp;quot, Price: 10), 
   (Color: &amp;quotGreen&amp;quot, Price: 7),
};
var buckets2 = new[] {
   (Color: &amp;quotWhite&amp;quot, Price: 7), 
   (Color: &amp;quotBlack&amp;quot, Price: 12),
};
Assert.IsTrue(buckets1.MaxBy(p =&gt; p.Price).Color == &amp;quotBlue&amp;quot); 
Assert.IsTrue(buckets1.MinBy(p =&gt; p.Price).Color == &amp;quotRed&amp;quot);
 
// bucket from buckets1 distinct by price
Assert.IsTrue(buckets1.DistinctBy(p =&gt; p.Price)    
   .Select(p =&gt; p.Color).SequenceEqual(new [] {&amp;quotRed&amp;quot, &amp;quotBlue&amp;quot }));
 
// Union from buckets1 and buckets2 distinct by price
Assert.IsTrue(buckets1.UnionBy(buckets2, p =&gt; p.Price)    
   .Select(p =&gt; p.Color).SequenceEqual(new[] { &amp;quotRed&amp;quot, &amp;quotBlue&amp;quot, &amp;quotBlack&amp;quot }));
 
// Unique bucket from buckets1 with a price in buckets2
Assert.IsTrue(buckets1.IntersectBy(buckets2.Select(p =&gt; p.Price), p =&gt; p.Price)    
   .Select(p =&gt; p.Color).SequenceEqual(new[] { &amp;quotRed&amp;quot }));
 
// Unique bucket from buckets1 with a price Not in buckets2
Assert.IsTrue(buckets1.ExceptBy(buckets2.Select(p =&gt; p.Price), p =&gt; p.Price)    
   .Select(p =&gt; p.Color).SequenceEqual(new[] { &amp;quotBlue&amp;quot}));6- چون ممکن است پیدا کردن تعداد پروفورمنس را تحت تاثیر بگذارد تابع TryGetNonEnumeratedCount برای تست کردن گرفتن تعداد طراحی شده که true, false می دهدclass MyCollection&lt;T&gt; : IEnumerable&lt;T&gt; {
   public IEnumerator&lt;T&gt; GetEnumerator() { throw new NotImplementedException(); }
   IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
 
...
 
IEnumerable&lt;int&gt; seq1 = new[] { 0, 1, 2, 3, 4, 5 };
Assert.IsTrue(seq1.TryGetNonEnumeratedCount(out int count1));
Assert.IsTrue(count1 == 6);
 
IEnumerable&lt;int&gt; seq2 = new MyCollection&lt;int&gt;();
Assert.IsFalse(seq2.TryGetNonEnumeratedCount(out int count2));7- اضافه شدن IEnumerable Chunk و IQueryable Chunk و برای راحت تر کردن عملیات chunk کردن و خواندن توالیvar arr = new[] { 0, 1, 2, 3, 4, 5, 6 };
IEnumerable&lt;int[]&gt; chuncks = arr.Chunk(3);
Assert.IsTrue(chuncks.ElementAt(0).SequenceEqual(new[] { 0, 1, 2 }));
Assert.IsTrue(chuncks.ElementAt(1).SequenceEqual(new[] { 3, 4, 5 }));
Assert.IsTrue(chuncks.ElementAt(2).SequenceEqual(new[] { 6 }));8- تا به حال می شد تا 2 توالی را Zip کنیم اما حالا امکان Zip کردن سه توالی اضافه شده است.var integers = Enumerable.Range(0, 4);
var squares = integers.Select(i =&gt; i * i);
var cubes = integers.Select(i =&gt; i * i * i);
var zip = integers.Zip(squares, cubes).ToArray();
foreach ((int i, int square, int cube) in zip) {
   Assert.IsTrue($&amp;quot{i} {square} {cube}&amp;quot == $&amp;quot{i} {i * i} {i * i * i}&amp;quot);
}9- اضافه شدن EnsureCapacity() به List, Stack, Queue . باتوجه به اینکه همه این کالکشن ها یک ظرفیت داخلی دارند و با اضافه شدن به لیست آنها ظرفیت افزایش پیدا می کند و این کار می تواند در پرفورمنس موثر باشد، شما می توانید ظرفیت لازم را برای هر کدام تعیین کنید.var list = new List&lt;int&gt; {1, 2};
Assert.IsTrue(list.Capacity &lt; 100);
list.EnsureCapacity(100);
Assert.IsTrue(list.Count == 2);
Assert.IsTrue(list.Capacity == 100);
list.EnsureCapacity(50);
Assert.IsTrue(list.Capacity == 100);
for(int i = list.Count; i &lt; 100; i++) {
   list.Add(i);
}
Assert.IsTrue(list.Count == 100);
Assert.IsTrue(list.Capacity == 100);10- اضافه شدن متد جدید Task.WaitAsync() .اگر timeout رخ بدهد هم تسک و هم wait کنسل می شوندpublic Task Task.WaitAsync(CancellationToken cancellationToken);
public Task Task.WaitAsync(TimeSpan timeout);
public Task Task.WaitAsync(TimeSpan timeout, CancellationToken cancellationToken)ترجمه: http://recompile.ir/learning/top-10-new-net-6-0-api/منبع : https://blog.ndepend.com/top-10-new-net-6-0-api</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Sat, 10 Jul 2021 14:36:54 +0430</pubDate>
            </item>
                    <item>
                <title>محدودیتها و مثال از گراف دیتابیس (بخش سوم)</title>
                <link>https://virgool.io/@m_khoshkesht/%D9%85%D8%AD%D8%AF%D9%88%D8%AF%DB%8C%D8%AA%D9%87%D8%A7-%D9%88-%D9%85%D8%AB%D8%A7%D9%84-%D8%A7%D8%B2-%DA%AF%D8%B1%D8%A7%D9%81-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D8%A8%D8%AE%D8%B4-%D8%B3%D9%88%D9%85-konuggksa7ei</link>
                <description>محدودیتهادر این بخش به معرفی محدودیتهای گراف دیتابیس sql و همچنین یک مثال عملی می پردازیم-جداول موقت (temporal table) ها نمی توانند از نوع نود و یال باشندTable types و  table variables ها نمی توانند از نوع نود و یال باشند-قابلیت temporal table برای جداول نود و یال پشتیبانی نشده است-جداول نود و یال نمی توانند بصورت memory optimized table ایجاد شوند-فیلدهای $from_id , $to_id آپدیت نمی شوند و در صورت نیاز به تغییر باید حذف شوند و ارتباط مجدد درج شود-Cross database کوئری ها برای این جداول پشتیبانی نشده استیک مثالمنبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Wed, 20 Jan 2021 15:25:42 +0330</pubDate>
            </item>
                    <item>
                <title>معماری SQL Server Graph Database (بخش دوم)</title>
                <link>https://virgool.io/@m_khoshkesht/%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-sql-server-graph-database-%D8%A8%D8%AE%D8%B4-%D8%AF%D9%88%D9%85-nfl7tlf7wvzq</link>
                <description>معماری graph database ? Node Table (گره جدول)یک گره جدول ، موجودی موجود در یک طرح گراف را نشان می دهد. هر بار که یک گره جدول ایجاد می شود ، همراه با ستون های تعریف شده توسط کاربر ، یک ستون ضمنی  $node_id ایجاد می شود ، که به طور یونیک به یک مپ می شود. مقادیر $node_id به طور خودکار تولید می شوند و ترکیبی از object_id آن گره جدول و مقدار bigint تولید شده در داخل هستند. با این حال ، وقتی ستون  $node_id انتخاب می شود ، یک مقدار محاسبه شده به شکل یک رشته JSON نمایش داده می شود. همچنین ،  $node_id یک ستون کاذب است که به یک نام داخلی با رشته hex مپ می شود. وقتی  $node_id را از جدول انتخاب کنید ، نام ستون به صورت $node_id_&lt;hex_string&gt; ظاهر می شود. بهتر است از نام ستون کاذب در کوئری ها برای رسیدن به $node_id داخلی  و باید از استفاده از نام داخلی با رشته hex خودداری شود.به کاربران توصیه می شود که در هنگام ایجاد جدول node ، constraint یا ایندکس یونیک به فرد را در ستون  $node_id ایجاد کنند ، اما اگر یکی ایجاد نشود ، یک ایندکس nonclustered پیش فرض به طور خودکار ایجاد می شود. با این حال ، هر index در یک ستون کاذب  گراف در ستون های داخلی زیر ایجاد می شود. یعنی ایندکسی که در ستون  $node_id ایجاد شده است ، در ستون داخلیgragh_id_&lt;hexstring&gt; ظاهر می شود.Edge Table (یال جدول)یک یال جدول نشان دهنده یک رابطه در یک گراف است. یال ها همیشه دو گره (نود) را به هم متصل می کنند. یک جدول edge کاربران را قادر می سازد روابط many to many را در گراف مدلسازی کنند. یک یال جدول ممکن است هیچ attribute  مشخص شده توسط کاربر را در خود نداشته باشد. هر بار که یال جدول ایجاد می شود ، همراه با attribute های تعریف شده توسط کاربر ، سه ستون ضمنی در یال جدول ایجاد می شود:$edge_id : شناسه یونیک یک یال است . این ستون از ترکیب object_id جدول و یک مقدار bigint داخلی است. با این حال ، وقتی ستون  $edge_id انتخاب می شود ، مقدار محاسبه شده ای به شکل رشته JSON نمایش داده می شود.$form_id  : node_id   شناسه جدول نود که ارتباط از آن شروع شده را ذخیره می کند$to_id: node_id   شناسه جدول نود که ارتباط از تا آنجا ادامه دارد را ذخیره می کندنود هایی که در یک یال آمده می تواند داده هایی که توسط داده های درج شده در ستون  $from_id و  $to_id اداره می شود را به هم متصل کند. در اولین نسخه ، امکان تعریف constraint برای یال جدول ها جهت محدود ارتباط با چند نوع نود وجود ندارد. یعنی یک یال می تواند هر دو گره(نود)ی را در گراف به هم وصل کند ، صرف نظر از نوع آن.نحوه ذخیره جداول گره و یال در دیتابیسمنبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Mon, 18 Jan 2021 09:14:36 +0330</pubDate>
            </item>
                    <item>
                <title>گراف دیتابیس چیست؟ (بخش اول)</title>
                <link>https://virgool.io/@m_khoshkesht/%DA%AF%D8%B1%D8%A7%D9%81-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%DA%86%DB%8C%D8%B3%D8%AA-%D8%A8%D8%AE%D8%B4-%D8%A7%D9%88%D9%84-ehgmm92r4xyn</link>
                <description>گراف دیتابیس ها(graph database) این امکان را برای ما فراهم می کنند که ما داده ها و رابطه ها رو در قالب ساختار گراف ذخیره کنیم .در پایگاه داده های رابطه ای بستگی به نوع سناریو که داریم بعضی اوقات نیاز هست که برای پیاده سازی روابط خیلی پیچیده ، داده ها را در قالب جداول متعدد ذخیره کنیم .. این جا ما مجبور به نوشتن Query ها و Join های زیادی بودیم که بتوانیم خروجی و گزارش دلخواه مان را بسازیم . هرچقدر کوئری های ما بزرگ و پیچیده بشود و روابط بین جداول زیاد (Join) ، هزینه اجرای دستور ما (Cost of Query) بالا میرود و سرعت اجرای دستورات پایین و پایین تر …با استفاده از امکانات گراف دیتابیس می توانیم این پیچیدگی ها را ساده کنیم .Neo4j, OrientDB , Amazon Neptune از معروف ترین پایگاه داده های مبتنی بر گراف هستندمفاهیم اصلی Graph Database ها :گره‌ها یا node ← نشان دهنده موجودیت یا entitiy های ما هستند .. مثل مردم، کسب و کار ، حساب‌های کاربری  …یال‌ها یا edge ← و به‌طور کلی یال‌ها وظیفه نمایش روابط را در دیتابیس بر عهده دارند. همچنین بسیاری از اطلاعات مهم در یال‌ها ذخیره می‌شوند.چه موقع از ساختار گراف بهتره استفاده کرد ؟مواقعی که برنامه شما دارای داده ها با ساختار سلسله مراتبی است (hierarchy) .. مثل  چارت سازمانیموجودیت های شما دارای روابط پیچیده چند به چند باشدبه عنوان مثال ، یک گره جدول (node table)  Personهمه نود های Person متعلق به یک گراف را در خود نگه می دارد. به طور مشابه ، یال جدول (edge table) مجموعه ای از نوع مشابه لبه ها(یال ها) است. به عنوان مثال ، یک یال جدول Friends تمام یال هایی را که یک شخص را به شخص دیگری متصل می کند ، نگه می دارد. از آنجا که گره ها و یال ها در جداول ذخیره می شوند ، بیشتر عملیات پشتیبانی شده روی جداول معمولی بر روی جدول های گره یا یال پشتیبانی می شوند.</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Mon, 11 Jan 2021 10:58:16 +0330</pubDate>
            </item>
                    <item>
                <title>الگوهای رفتاری -Behavioral Design Patterns</title>
                <link>https://virgool.io/@m_khoshkesht/%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D8%B1%D9%81%D8%AA%D8%A7%D8%B1%DB%8C-behavioral-design-patterns-dal4ohiovlab</link>
                <description>Chain of Responsibilityبه شما امکان می دهد درخواست ها را از طریق زنجیره ای از کلاسها منتقل کنید. با دریافت یک درخواست ، هر یک از کارگزاران (کلاسها) تصمیم می گیرند که درخواست را پردازش کنند یا آن را به مدیر بعدی در زنجیره منتقل کنند.Commandیک درخواست را به یک شی مستقل تبدیل می کند که شامل تمام اطلاعات مربوط به درخواست است. این تحول به شما امکان می دهد روش ها را با درخواست های مختلف پارامتر کنید ، اجرای درخواست را به تأخیر بیاندازید یا در صف قرار بگیرید و از عملیات غیرقابل انعطاف پشتیبانی کنید.Iteratorبه شما امکان می دهد عناصر یک مجموعه را بدون نمایش نمایانگر اصلی آن (لیست ، stack، treeو غیره) مرور کنید.Mediatorبه شما امکان می دهد وابستگی های آشفته بین اشیا را کاهش دهید. این الگو ارتباطات مستقیم بین اشیا را محدود می کند و آنها را مجبور به همکاری فقط از طریق یک شی میانجی می کند.Mementoبه شما اجازه می دهد تا وضعیت قبلی یک شی را ذخیره کرده و بازیابی کنید بدون اینکه جزئیات اجرای آن مشخص شود.Observerبه شما اجازه می دهد مکانیسم اشتراک برای آگاه کردن چندین اشیا در مورد هر رویدادی که برای شی مورد مشاهده آنها رخ می دهد ، تعریف کنید.Stateاجازه می دهد یک شی object هنگام تغییر وضعیت داخلی ، رفتار خود را تغییر دهد. به نظر می رسد مثل اینکه شی کلاس خود را تغییر داده باشد.Strategyبه شما اجازه می دهد تا خانواده ای از الگوریتم ها را تعریف کنید ، هر یک از آنها را در یک کلاس جداگانه قرار دهید و اشیا آنها را جایگزین کنید.Template Methodاسکلت یک الگوریتم در ابر کلاس را تعریف می کند اما به شما اجازه می دهد بدون تغییر ساختار ساختار ، زیر کلاس ها از مراحل خاص الگوریتم override شوند.Visitorبه شما امکان می دهد الگوریتم ها را از اشیایی که روی آنها کار می کنند جدا کنید.منبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Sun, 13 Dec 2020 12:02:33 +0330</pubDate>
            </item>
                    <item>
                <title>مایکروسافت چه می کند؟</title>
                <link>https://virgool.io/@m_khoshkesht/%D9%85%D8%A7%DB%8C%DA%A9%D8%B1%D9%88%D8%B3%D8%A7%D9%81%D8%AA-%DA%86%D9%87-%D9%85%DB%8C-%DA%A9%D9%86%D8%AF-bwyttloibalj</link>
                <description> روی sql2017 آپدیت cu20 نصب نمی شد. خطای زیر رو داشتمAttempted to perform an unauthorized operation&quot; error when you set up or update SQL Server instances کل اینترنت رو زیر رو رو کردم و هزار تا روش رو رفتم! آخر سر تو رجیستری به یک کلید Microsoft edge مجوز دادم ، نصب شد!HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edgeخدا می دونه Edge چه ربطی به SQL داره؟این ارتباط بیشتر ترسناک هست تا جالب باشه(بزرگان اشتباه نمی کنند، امنیت!)اینم لینک رفع اشکال:https://support.microsoft.com/en-us/help/4594205/kb4594205-setup-or-patching-sql-server-instances-fail-with-error-attem </description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Wed, 02 Dec 2020 15:03:06 +0330</pubDate>
            </item>
                    <item>
                <title>الگوهای طراحی ساختاری – Structural Design Patterns</title>
                <link>https://virgool.io/@m_khoshkesht/%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%B3%D8%A7%D8%AE%D8%AA%D8%A7%D8%B1%DB%8C-structural-design-patterns-ad1lyh6crk0n</link>
                <description>الگوهای ساختاری چگونگی جمع آوری اشیا و کلاسها را به ساختارهای بزرگتر توضیح می دهد در حالی که این ساختارها را انعطاف پذیر و کارآمد نگه می دارد.Adapterبه اشیا دارای رابط کاربری (interface)ناسازگار امکان همکاری می دهد.Bridgeبه شما امکان می دهد یک کلاس بزرگ یا مجموعه ای از کلاسهای نزدیک را به دو سلسله مراتب جداگانه تقسیم کنید – انتزاع و پیاده سازی – که می تواند به طور مستقل از یکدیگر توسعه یابد.Compositeبه شما اجازه می دهد اشیا را در ساختارهای درختی ترکیب کنید و سپس با آنها مانند یک کلاس  جداگانه کار کنید.Decoratorبه شما اجازه می دهد با قرار دادن اشیا در داخل کلاسهایی  که مخصوص و حاوی این رفتارها هستند ، رفتارهای جدیدی را به اشیا پیوند دهید.Facadeیک اینترفیس ساده برای کتابخانه ، یک چارچوب یا هر مجموعه پیچیده دیگری از کلاس ها فراهم می کند.Flyweightبه شما امکان می دهد با تقسیم قطعات مشترک حالت بین چندین شی به جای نگهداری تمام داده ها در هر شی ، اشیا بیشتری را در مقدار RAM موجود قرار دهید.Proxyپروکسی یک الگوی طراحی ساختاری است که به شما امکان می دهد جایگزین یا placeholder دیگری استفاده کنید. پروکسی دسترسی به شی اصلی را کنترل می کند ، به شما امکان می دهد کاری را قبل یا بعد از ورود درخواست به شی اصلی انجام دهید.</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Mon, 30 Nov 2020 18:41:26 +0330</pubDate>
            </item>
                    <item>
                <title>الگوهای طراحی – Design Patterns</title>
                <link>https://virgool.io/@m_khoshkesht/%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7%DB%8C-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-design-patterns-lkwrtab0hm6r</link>
                <description>لگوی طراحی چیست؟الگوهای طراحی(دیزاین پترن) راه حل های معمول برای مشکلات معمول در طراحی نرم افزار است. آنها مانند نقشه های از پیش ساخته شده ای هستند که می توانید آنها را برای حل مشکلات طراحی تکراری در کد خود سفارشی کنید.اصولا نمی شود یک الگو را پیدا کنید و آن را در برنامه خود کپی کنید ، همانطور که نمی توانید از library ها (کتابخانه ها) به این کل استفاده کنید. الگو کد خاصی نیست ، بلکه یک مفهوم کلی برای حل یک مسئله خاص است. می توانید جزئیات الگو را بررسی کنید و راه حلی را متناسب با واقعیت برنامه خود اجرا کنید.الگوها اغلب با الگوریتم ها اشتباه گرفته می شوند ، زیرا هر دو مفهوم راه حل های معمول برخی از مشکلات شناخته شده را توصیف می کنند. در حالی که یک الگوریتم همیشه مجموعه مشخصی از اقدامات را تعریف می کند که می تواند به هدفی برسد ، در صورتیکه الگو ها در سطح بالاتر قرار دارند. کد یک الگوی اعمال شده برای دو برنامه مختلف ممکن است متفاوت باشد.در تشبیه به الگوریتم مثل یک دستور العمل پخت و پز است: هر دو مراحل مشخصی برای رسیدن به یک هدف دارند. از طرف دیگر ، یک الگوی بیشتر شبیه یک طرح اولیه است: شما می توانید ببینید که نتیجه و ویژگی های آن چیست ، اما ترتیب دقیق اجرای آن به شما بستگی دارد.الگو(پترن) از چه چیزی تشکیل شده است؟بیشتر الگوها بسیار رسمی توصیف می شوند ، بنابراین افراد می توانند آنها را درمفاهیم مختلف تفسیر کنند.موارد زیر بخشهایی هستند که در تعریف یک الگو معمولا وجود دارند:هدف  ابطور خلاصه توضیحاتی در مورد هدف الگو داده می شودکاربرد هم مسئله و راه حل ممکن را برای الگو توضیح می دهد.ساختار وضعیت کلاسها و هر قسمت از الگو و نحوه ارتباط آنها را نشان می دهد.کد سمپل ارائه کد مثال در یکی از زبانهای برنامه نویسی درک الگو را ساده تر می کندالگوهای طراحی جزو معماری‌های نرم افزاری نیستند و فقط شیوه ای صحیح از کدنویسی شی گرا را ارائه می‌دهند. بنابراین این الگوها فقط در قلمرو کدنویسی شی گرا وارد می‌شوند و مستقل از زبان‌های برنامه نویسی هستند.در پستهای بعدی در مورد تاریخچه، دسته بندی و توضیح هر کدام از الگوها خواهیم نوشت.منبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Tue, 27 Oct 2020 12:45:55 +0330</pubDate>
            </item>
                    <item>
                <title>تکنیکهای ریفکتور</title>
                <link>https://virgool.io/@m_khoshkesht/%D8%AA%DA%A9%D9%86%DB%8C%DA%A9%D9%87%D8%A7%DB%8C-%D8%B1%DB%8C%D9%81%DA%A9%D8%AA%D9%88%D8%B1-fflxy38gqgex</link>
                <description>بازآرایی متد ها (Composing Methods)بخش اعظمی از refactoring شامل اصلاح و بازآرایی متد ها است. در بیشتر موارد ، متدهای بیش از حد طولانی ریشه همه مشکلات هستند. مبهم بودن کد موجود در این متد ها منطق اجرا را پنهان می کند و درک متد را بسیار دشوار کرده و تغییر آن را سخت تر می کند.تکنیک های refactoring در این گروه ساده سازی متد ها ، حذف کدهای تکراری و زمینه سازی برای پیشرفت های آینده است.Extract MethodInline MethodExtract VariableInline TempReplace Temp with QuerySplit Temporary VariableRemove Assignments to ParametersReplace Method with Method ObjectSubstitute Algorithmانتقال متد ها و… بین کلاسهااین تکنیک های refactoring نشان می دهد که چگونه می توان با خیال راحت فانکشنالیتی ها را بین کلاس ها را جابجا کرد ، کلاس های جدید ایجاد کرد و جزئیات پیاده سازی را از دسترسی عمومی پنهان کردMove MethodMove FieldExtract ClassInline ClassHide DelegateRemove Middle ManIntroduce Foreign MethodIntroduce Local Extensionسازماندهی داده هااین تکنیک های refactoring به پردازش داده ها کمک می کنند و داده های اولیه را با فانکشنالایتی کلاس غنی جایگزین می کنند. نتیجه مهم دیگر ، جدا کردن ارتباط بین کلاسها برای اینکه بتوان از آن ها بصورت مستقل استفاده کرد.Change Value to ReferenceChange Reference to ValueDuplicate Observed DataSelf Encapsulate FieldReplace Data Value with ObjectReplace Array with ObjectChange Unidirectional Association to BidirectionalChange Bidirectional Association to UnidirectionalEncapsulate FieldEncapsulate CollectionReplace Magic Number with Symbolic ConstantReplace Type Code with ClassReplace Type Code with SubclassesReplace Type Code with State/StrategyReplace Subclass with Fieldsساده سازی عبارات شرطیشرط ها با گذشت زمان در منطق خود پیچیده تر می شوند و تکنیک های بیشتری برای مبارزه با این مسئله نیز وجود دارد.Consolidate Conditional ExpressionConsolidate Duplicate Conditional FragmentsDecompose ConditionalReplace Conditional with PolymorphismRemove Control FlagReplace Nested Conditional with Guard ClausesIntroduce Null ObjectIntroduce Assertionساده کردن فراخوانی های متداین تکنیک ها فراخوانی های متد را ساده و قابل فهم تر می کنند. این به نوبه خود ، interface  های بین کلاس ها را ساده می کندAdd ParameterRemove ParameterRename MethodSeparate Query from ModifierParameterize MethodIntroduce Parameter ObjectPreserve Whole ObjectRemove Setting MethodReplace Parameter with Explicit MethodsReplace Parameter with Method CallHide MethodReplace Constructor with Factory MethodReplace Error Code with ExceptionReplace Exception with Testپرداختن به تعمیمانتزاع (Abstraction)گروهی از تکنیک های خود را دارد ، که در درجه اول با قابلیت حرکت در طول سلسله مراتب وراثت کلاس ، ایجاد کلاس ها و رابط های جدید و جایگزینی وراثت با تفویض و برعکس همراه است.Pull Up FieldPull Up MethodPull Up Constructor BodyPush Down FieldPush Down MethodExtract SubclassExtract SuperclassExtract InterfaceCollapse HierarchyForm Template MethodReplace Inheritance with DelegationReplace Delegation with Inheritanceمنبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Fri, 09 Oct 2020 21:31:53 +0330</pubDate>
            </item>
                    <item>
                <title>بوی بدِ کد – Bad Smells</title>
                <link>https://virgool.io/@m_khoshkesht/%D8%A8%D9%88%DB%8C-%D8%A8%D8%AF%D9%90-%DA%A9%D8%AF-bad-smells-lab5hgfn2o7t</link>
                <description>در ادامه مباحث ریفکتورینگ به بوی کدها می پردازیم.مگر کدها بو می دهند؟ اگر سعی کنید بوی آنها را حس می کنید.نشانه های بوی بد کد ها را بشناسیم تا آنها را پیدا کنیم.بزرگها!کلاسها و متدهایی که آنقدر بزرگ می شوند که کار کردن با آنها سخت می شود. البته اوایل بوی بد نمی دهند اما هرچه بگذرد بزرگتر می شوند و بوی بد تری میدهندمتدهای بزرگ (Long Methods)متدهایی که شامل خطوط زیادی هستند. معمولا متدهایی با بیش از 10 خط را متدهای بزرگ می دانیمکلاسهای بزرگ  (Large Classes)کلاسهایی که تعداد زیادی فیلد و پراپرتی و متد را شامل می شوندوسواس اولیه(Primitive Obsession)استفاده از کلاسها و آبجکتها به جای مقدارهای ساده اولیه (مثل bool  ,int,..)استفاده از مقادیر ثابت (const) برای رمز گذاری اطلاعات (مثل USER_ADMIN_ROLE = 1 برای اعطای دسترسی به کاربر ادمین)استفاده از مقادیر رشته ای ثابت برای نام فیلدها در آرایه هاپارامترهای زیاد(Long Parameter List)بیش از سه یا چهار پارامتر برای یک متد نشانه این اشتباه استتوده داده(Data Clumps)برخی اوقات قسمتهای مختلفی از کد شامل گروه هایی از گروههای یکسان از متغیرها (مانند پارامترهای اتصال به یک پایگاه داده) هستند. باید هر قطعه به کلاس مربوطه خودش منتقل شوداستفاده بد از شیء گرایی object orientationسوئیچ ها(Switch Statements)کد شامل تعداد زیادی switch یا if استفیلدهای موقت (Temporary Field)فیلدهای موقتی که فقط در بخش مورد استفاده کارایی دارند و در بقیه کد خالی هستندارث بری بدرد نخور (Refused Bequest)اگر یک کلاس فقط از تعدادی از متد ها و پراپرتی های کلاسی که از آن مشتق شده استفاده می کند، این ارث بری بدرد نخور است.متدهای نالازم به سادگی به متدهای بدون استفاده تبدیل می شوند یا دوباره تعریف می شوند و خطا ایجاد می کنندکلاس های جایگزین با رابط های مختلف (Alternative Classes with Different Interfaces)دو کلاس دارای توابعی هستند که کار یکسانی را انجام می دهند اما نام متدهای متفاوتی دارند.تغییر ناپذیریاین بو به این معنی است که اگر شما نیاز به تغییر چیزی در یک مکان در کد خود دارید ، باید در مکان های دیگر نیز تغییرات زیادی ایجاد کنید. در نتیجه توسعه برنامه بسیار پیچیده تر و گران تر می شود.تغییرات واگرا (Divergent Change)هنگام ایجاد تغییر در یک کلاس ، مجبور می شوید بسیاری از متد های نامربوط را تغییر دهید. به عنوان مثال ، هنگام افزودن یک نوع محصول جدید ، باید متدهای یافتن ، نمایش و سفارش محصولات را تغییر دهید.تشریح انفجاری (Shotgun Surgery)ایجاد هرگونه تغییر ، مستلزم ایجاد تغییرات کوچک در بسیاری از کلاسهای مختلف است.سلسله های وراثت موازی (Parallel Inheritance Hierarchies)هر وقت یک زیرکلاس (sub class) برای یک کلاس ایجاد می کنید ، میبینید که لازم یک زیر کلاس برای یک کلاس دیگر هم بسازید.اضافاتبه هرچیزی گفته می شود که نبودش بهتر از بودنش است و نبودنش کد را ساده تر می کندکامنتها(Comments)متدی که با کامنت ها پر شده استکد کپی(Duplicate Codes)دو قطعه کد تقریباً یکسان به نظر می رسند.کلاس تنبل(Lazy Class)فهم و حفظ کلاس ها همیشه به وقت و هزینه نیاز دارد. بنابراین اگر یک کلاس به اندازه کافی توجه شما را جلب نکرد ، باید حذف شود.کلاس داده(Data Class)کلاس داده به یک کلاس اطلاق می شود که فقط فیلدها ها و متد های خام را برای دسترسی به آنها (getter  و  setter) دارد. این ها به سادگی توسط کلاسهای دیگر استفاده می شوند. این کلاس ها هیچ فانکشن اضافی ندارند و نمی توانند به طور مستقل روی داده هایی که در اختیار دارند کار کنند.کد مرده(Dead Code)متغیر ، پارامتر ، فیلد ، متد یا کلاسی که دیگر استفاده نمی شود (معمولاً به دلیل اینکه منسوخ است).کلیت اضافی(Speculative Generality)یک کلاس ، متد ، فیلد یا پارامتر استفاده نشده که نیازی به آن وجود ندارد.ارتباطات (Couples)این گروه شامل Coupling های زیادی بین کلاسها و یا استفاده بیش از حد از delegation استویژگی حسادت(Feature Envy)یک متد بیشتر از داده های خود به داده های یک شی دیگر دسترسی پیدا می کند.صمیمیت نامناسب(Inappropriate Intimacy)یک کلاس از فیلدها و متدهای داخلی کلاس دیگر استفاده می کند.زنجیرهای پیامها(Message Chains)در کد یک سری از فراخوانی ها را مشاهده می کنید که شبیه $a-&gt;b()-&gt;c()-&gt;d()هستندمردی در میانه(Middle Man)اگر یک کلاس فقط یک عمل را انجام دهد ، کار را به کلاس دیگری واگذار کند ، چرا اصلاً وجود دارد؟دیگر بو هاموارد زیر در هیچ دسته بندی جای نمی گیرندکلاس کتابخانه ناقص (Incomplete Library Class)دیر یا زود کتابخانه ها (libraries) دیگر پاسخگوی نیاز کاربر نخواهند بود. راه ایجاد تغییرات در کتابخانه ها است که چون عموما فقط خواندنی (read only) هستند امکانپذیر نیست.منبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Mon, 28 Sep 2020 14:41:10 +0330</pubDate>
            </item>
                    <item>
                <title>چطور ریفکتور کنیم؟</title>
                <link>https://virgool.io/coderlife/%DA%86%D8%B7%D9%88%D8%B1-%D8%B1%DB%8C%D9%81%DA%A9%D8%AA%D9%88%D8%B1-%DA%A9%D9%86%DB%8C%D9%85-gsvvzaznlg9o</link>
                <description>ریفکتور باید شامل یک سری تغییرات کوچک در راستای ساده تر و قابل فهم تر شدن کدها باشد.چک لیست ریفکتورینگ صحیحکد باید تمیز تر شوداگر بعد از ریفکتور باز هم کد کثیف دارید فقط وقتتان را هدر داده اید. باید سعی کنید که بفهمید چرا این اتفاق افتاده استالبته ممکن است این اتفاق در کدهای خیلی کثیف اتفاق بیفتد و می شود در چند  مرحله کم کم بهبود را ایجاد کرددر این حالت ممکن است مجبور باشید بخشهایی از کد را بازنویسی کنید، اما قبل از آن باید حتما تست نوشته باشید و برای اینار زمان اختصاص داده باشید. در غیر اینصورت با صرف این همه کار هم به نتیجه ای نخواهید رسیدعملکرد جدید نباید در خلال ریفکتور ایجاد شودهیچوقت ریفکتورینگ را با تولید قابلیت جدید قاطی نکنید. سعی کنید این موارد را حداقل در commit های جداگانه انجام شودهمه تستها باید بعد از ریفکتور پاس شوندبه دو دلیل ممکن است تستها بعد از ریفکتور کار نکنند:در خلال ریفکتور(بازسازی) کد ها خطا ایجاد کرده باشید» مهم نیست می توانید به پیش بروید و اشکالات را رفع کنیدتستها خیلی سطح پایین باشند» به عنوان مثال شما متدهای کلاسهای private را تست کرده ایددر این حالت خود تستها اشکال دارند. می توانید خود تستها را ریفکتور کنید یا تستهای در سطح بالاتر بنویسید. بهترین راه برای جلوگیری از این مشکل نوشتن تستها به سبک BDD است.منبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Wed, 02 Sep 2020 22:34:26 +0430</pubDate>
            </item>
                    <item>
                <title>چه زمانی باید ریفکتور کنیم؟</title>
                <link>https://virgool.io/@m_khoshkesht/%DA%86%D9%87-%D8%B2%D9%85%D8%A7%D9%86%DB%8C-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%B1%DB%8C%D9%81%DA%A9%D8%AA%D9%88%D8%B1-%DA%A9%D9%86%DB%8C%D9%85-z7bje7p7cq1v</link>
                <description>در نوشته های قبلی فهمیدیم که لازم است ریفکتور(بازسازی یا اصلاح کد) داشته باشیم. و اما یک قانون:قانون 3وقتی کاری برای بار اول انجام می شود، فقط انجام می دهیموقتی کار مشابهی را برای بار دوم انجام می دهیم، یواشکی! انجام می دهیماگر برای برای سوم شد حتما باید ریفکتور کنیم و کدها را اصلاح کنیم!چه زمانی باید ریفکتور کرد؟زمانی که یک فیچر جدید تولید می کنیم.وقتی که فیچر جدیدی اضافه میکینم خیلی وقتها مجبور میشویم اول کدهای کثیف قبلی را تمیز کنیم تا بفهمیم چه کار می کنیم. تمیز کردن کد کار را برای نفرات بعدی هم ساده تر می کندزمان رفع باگهاحالا که برای رفع یک باگ تا اینجای کد آمده ایم! حیف نیست که کد آن را تمیز نکنیم و رد شویم. با این کار یک تیر و دو نشان زده ایم. هم باگ رفع شده و هم قسمتی از کد تمیز شده است.در زمان Code Reviewشاید این مرحله آخرین مرحله از خداحافظی شما با آن کد باشد و به این زودی ها به آن برنگردید. در این زمان هم می شود ریفکتور را در نظر گرفت. در این مرحله اشکالات ساده را برطرف می کنیم و زمان برای رفع اشکالات بزرگتر را برآورد می کنیم.ریفکتورینگ باعث ساده سازی و قابل فهم شدن کد می شود اما باید تاثیرات پرفورمنسی آن در نظر گرفته شود و ضمنا نباید باعث ایجاد functionality جدید بشود.نفس ریفکتور در جلسات بازبینی کد نباید باعث جلوگیری از merge یا check-in کد شود.منبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Tue, 01 Sep 2020 23:54:18 +0430</pubDate>
            </item>
                    <item>
                <title>بدهی فنی – Technical debt</title>
                <link>https://virgool.io/coderlife/%D8%A8%D8%AF%D9%87%DB%8C-%D9%81%D9%86%DB%8C-technical-debt-zbpvzdqa5cpe</link>
                <description>هر کسی تمام تلاش خود را می کند تا بهترین کد را از ابتدا بنویسد. احتمالاً هیچ برنامه نویسی نیست که عمداً کد ناخوشایند و به ضرر پروژه بنویسد. اما در چه مرحله ای کد تمیز، کثیف می شود؟استعاره “بدهی فنی” در مورد کد بد در ابتدا توسط Ward Cunningham پیشنهاد شده.اگر از یک بانک وام دریافت کنید، به شما این امکان را می دهد که سریعتر خرید خود را انجام دهید. در این حالت شما باید مبلغ بیشتری را به عنوان سود پرداخت کنید. نیازی به گفتن نیست ، حتی می توانید آنقدر این کار را ادامه دهید که میزان بهره بیش از درآمد کل شما باشد و بازپرداخت کامل را غیرممکن می کند.همین اتفاق می تواند با کد رخ دهد. شما می توانید به طور موقت بدون نوشتن تست برای ویژگی های جدید، به کار سرعت بخشید ، اما این کار به تدریج هر روز پیشرفت شما را کند می کند تا اینکه در نهایت با نوشتن تست ها بدهی خود را پرداخت کنید.علل بروز بدهی فنیفشار بیزنسبعضی اوقات شرایط تجاری ممکن است شما را وادار کند فیچر های خود را قبل از اتمام کار ارائه کنید. در این حالت تکه های ناجوری در کد ظاهر می شوند تا اتمام پروژه مخفی می شود.عدم درک عواقب بدهی فنیصرف نظر از درک بدهی فنی، گاهی اوقات کارفرمای شما ممکن است درک نکند که بدهی فنی باعث کاهش بهره وری می شود. این  موضوع می تواند اختصاص دادن زمان تیم را به refactoring بسیار دشوار کند زیرا مدیریت ارزش آن را نمی بیند.عدم موفقیت در برابر انسجام دقیق اجزاءدر شرایطی این پروژه به جای ماژولهای انفرادی شبیه به یک تکه سنگ یکپارچه باشد، هرگونه تغییر در یک قسمت از پروژه ، بخش های دیگر را تحت تأثیر قرار می دهد. در این حالت کار بسیار دشوار تر است زیرا جدا کردن این اجزاء از هم خیلی سخت است.نبود تستفقدان بازخورد فوری ، پیدا کردن راه حلهای سریع را از بین برده و ایجاد ریسک می کند. در بدترین حالت ، این تغییرات بدون تست های قبلی به مرحله تولید منتقل می شوند و عواقب آن می تواند فاجعه بار باشد. به عنوان مثال ، ممکن است یک حلقه ثابت به دنبال یک ایمیل آزمایشی عجیب به هزاران مشتری ارسال شود یا حتی بدتر از آن ، یک بانک اطلاعاتی کامل را افشاء کند.نبود مستند سازیاین امر باعث بروز مشکل در معرفی افراد جدید به پروژه می شود و در صورت ترک افراد اصلی پروژه توسعه متوقف خواهد شد.عدم تعامل بین اعضای تیماگر پایگاه دانش در سراسر شرکت توزیع نشود ، افراد در نهایت با درک قدیمی از روندها و اطلاعات مربوط به پروژه کار می کنند. این وضعیت زمانی می تواند تشدید شود که توسعه دهندگان جدید به طور نادرست توسط مربیان خود آموزش ببینند.توسعه همزمان و طولانی مدت در برنچ های(Branches) مختلفاین امر می تواند به انباشت بدهی فنی منجر شود ، که در هنگام ادغام تغییرات(Merge) افزایش می یابد. هرچه تغییرات بیشتر توسط اعضای تیم بصورت منفرد (Isolated) انجام شود کل بدهی فنی بیشتر می شود.تأخیر در اصلاح کد(Refactoring ریفکتور)الزامات پروژه به طور مداوم در حال تغییر است و ممکن است در بعضی مواقع مشخص شود که قسمت هایی از کد منسوخ و دست و پا گیر شده اند و برای برآورده کردن نیازهای جدید باید دوباره طراحی شوند.از طرف دیگر ، برنامه نویسان پروژه هر روز کدهای جدید می نویسند که با قسمتهای منسوخ کار می کند. بنابراین ، هرچه تأخیر بیشتر به تأخیر بیفتد ، در آینده کدهای وابسته تری داریم که نیاز به ریفکتور (اصلاح) دارند.نبود نظارت بر تطابقوقتی که هر کسی بر روی پروژه بر طبق روش خودش کد نویسی را ادامه دهد این اتفاق خواهد افتاد و کدها یکدست نخواهند شد.بی کفایتیدر شرایطی که توسعه دهنده واقعا نمی داند چگونه کد مناسبی را بنویسد و در واقع توان فنی لازم را ندارد.منبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Mon, 31 Aug 2020 23:33:17 +0430</pubDate>
            </item>
                    <item>
                <title>کد نویسی تمیز را شروع کنیم</title>
                <link>https://virgool.io/coderlife/%DA%A9%D8%AF-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%AA%D9%85%DB%8C%D8%B2-%D8%B1%D8%A7-%D8%B4%D8%B1%D9%88%D8%B9-%DA%A9%D9%86%DB%8C%D9%85-gij4cjzjigav</link>
                <description>بیایید شروع کنیم .هدف اصلی اصلاح کد(Refactoring) مبارزه با بدهی های فنی است.پس باید از اصول اولیه شروع کنیم.حالا کد تمیز چیست؟ در اینجا برخی از ویژگی های آن آورده شده است:کد نویسی تمیز به معنی واضح کردن کد برای سایر برنامه نویسان است.فعلا در مورد الگوریتم های فوق العاده پیشرفته صحبت نمی کنیم. نامگذاری ضعیف متغیر ها، کلاس ها و کلاسهای چاق ، اعداد و نامهای جادویی – که فقط شما از آن اطلاع دارید – همه این موارد باعث می شود که کد کثیف و درک آن دشوار شود.در کد تمیز ، کد تکراری وجود نداردهر بار که بخواهید تغییری درچنین کدهایی بدهید باید به خاطر داشته باشید که یک نمونه دیگر از آن هم وجود دارد که باید اصلاح شود. این کار باعث بروز خطا و کندی پیشرفت کار می شود.کد تمیز شامل حداقلِ تعداد کلاس و متد و … استکد کمتر نیاز به نگهداری چیزهای کمتری را در ذهن ایجاد می کند. کد کمتر نگهداری کمتری می خواهد. کد کمتر اشکالات کمتری دارد. کد مسئولیت می آورد پس آن را کوتاه و ساده نگه دارید.کد تمیز تمام تستها را می گذراند.می دانید وقتی فقط 95٪ از تست های شما پاس می شود، کد شما کثیف است. می دانید وقتی تستهای شما 0 درصد پوشش دارند، یعنی فاجعه پیش آمده است؟ کد تمیز کدی است که تمام تستها را پاس کند.نگهداری کد تمیز ساده تر و ارزان تر است.کد تمیز کد ساده است، پیچیدگی کمتر و رعایت اوصل کد تمیز (Clean Code) باعث می شود در آینده نگداری و رفع باگ کد ساده تر و ارزان تر باشد.معروف ترین کتاب در این زمینه کتاب Clean Code – Robert C Martin است که البته ترجمه آن به فارسی هم وجود دارد.منبع</description>
                <category>محمد خوش کشت</category>
                <author>محمد خوش کشت</author>
                <pubDate>Tue, 25 Aug 2020 00:45:26 +0430</pubDate>
            </item>
            </channel>
</rss>