نظرات مطالب
اهمیت code review
سلام.
من به برخی از مشکلات کد شما اشاره می کنم:

1. ترکیب کدهای DAL و کد UI.
2. عدم جداسازی Business Object ها.
3. ایجاد کلاسی به اسم SqlHelper و قرار دادن N تا متود static در این کلاس، نشون میده که برنامه از هیچ یک از معیارهای موجود پیروی نمیکنه. مطلقا دلیلی نداره که متودها static تعریف بشن و ... حتی اگر قرار باشه چنین کلاسی تعریف کنیم، (که من کاملا باهاش مخالفم)، باید متودهای اونو بر اساس Property ی Singleton ای از کلاس به بیرون Expose کنیم. نه اینکه همه متودهاشو static بذاریم و کلاس رو هم sealed کنیم و ... چنین کلاسی هرگز قابل توسعه نیست.
4. وقتی همه متودهای کلاس static هستش، چرا Constructor ای private برای اون کلاس تعریف کرده اید؟ تازه بهتر بود جای اینکه کلاس رو sealed تعریف می کردید، اونو static تعریف می کردید (اگر مجاب میشدیم که تعریف چنین کلاسی صحیح هستش).
5. catch کردن کلیه SqlException ها در متود CloseCnt.
6. عدم استفاده از Parametric Command ها (و در نتیجه فراهم اومدن امکان SQL Injection).
7. عدم اجرای StyleCop روی کد (و در نتیجه، نوشتن Comment های مربوط به هر تابع بر اساس Style ای من در آوردی، عدم رعایت Spacing، نوشتن if ها در یک خط و ...)
8. و ...

موفق باشید.
نظرات مطالب
PHP سریعتر از ASP.NET! افسانه یا واقعیت؟
فناوری-زبان PHP بسیار محترم است و بسیار قابل توصیه اما برای آن زمانی که در رقابت با ASP کلاسیک بود و پدیده ای به نام دات نت ظهور نکرده بود حال آنکه پدیده یاد شده در زمان حال به پختگی و پیشرفت چشمگیری دست یافته است.
دنیای دات نت و مباحث مربوط به آن گسترده‌تر و پیچیده‌تر از آن است که برای توجیه استفاده از دات نت سرعت مقایسه شود. ده‌ها ویژگی منحصر به دات نت وجود دارد که برای انتخاب فناوری سمت سرور مجالی برای تفکر درباره سرعت باقی نمی‌گذارد و آنان که اهل تفکر باشند را جذب خود می‌کند و نه گمراهان (کسانی که یا تعصب دارند یا خسته‌تر از آن هستند که دنیای جدیدی را تجربه نمایند.)
در مورد سرعت کافی است نکات ساده ای که چند دقیقه بیشتر زمان نمی‌برند رعایت شود تا وب سایت‌های دات نتی چندین برابر سریعتر عمل کنند.
فراموش نکنید دنیای دات نت تا حد بیشتری با اصول مهندسی نرم افزار گره خورده است و باب میل همگان نیست.
عموماً سرویس دهنده بر حسب فناوری انتخاب می‌شود و نه برعکس! در مقالاتی که مقایسه انجام می‌دهند صحبت از رایگان بودن لینوکس و آپاچی و ... چندان ضرورتی ندارد.
بسیاری از آن‌ها که Open Source بودن PHP را با آب و تاب و به عنوان برتری مطرح می‌کردند هرگز در عمر خود به کدهای سورس آن نگاهی نکرده اند. البته اگر بداند از کجا باید دانلود کنند. توصیه می‌کنم در مورد رویکرد و سیاست‌های چند سال اخیر مایکروسافت در رابطه با Open Source تحقیق بیشتری صورت گیرد.
مثال هایی از سایت‌های موفق و یا تعداد سایت‌ها در یک فناوری هرگز دلیلی برای انتخاب فناوری نیست. ضمناً زمان ظهور این دو فناوری یکسان نبوده است که تعداد وب سایت‌ها معیار مقایسه باشد.
فناوری-زبان PHP هنوز وجود دارد. هنوز قدرت خود را دارد. و هنوز هر کجا به هر دلیلی امکان استفاده از دات نت نبود، با کمال افتخار و خوشحالی از این که چند سال عمری که برای آن گذاشته ام هدر نرفته است به آن باز می‌گردم و آن را مورد استفاده قرار می‌دهم.
مطالب
بار کردن ساعت و تاریخ فعلی سرور با JQuery Ajax
در این مطلب می‌خواهم شما را با نحوه بار گزاری ساعت و تاریخ سیستم سرور با استفاده از JQuery Ajax آشنا کنم.
در بعضی از سایتها با استفاده از جاوا اسکریپت تاریخ و ساعت جاری سیستم کلاینت به او نشان داه می‌شود.
این روش یک مزیت دارد: اول اینکه این کدها سمت کلاینت اجرا میشن و برای سرور بار اضافی ایجاد نمیکنن.
و یک عیب هم دارد: در صورتی که ساعت و تاریخ روی سیستم کلاینت تنظیم نباشد، همین ساعت و تاریخ نادرست برای او نمایش داده می‌شود. همین عیب می‌تواند باعث افت کیفیت وب سایت شود.

اما راهی هست که تاریخ و ساعت سیستم سرور برای کاربر نشان داده شود و آن هم استفاده از JQuery Ajax هست. به صورتی که هر ثانیه درخواستی برای یک handler فرستاده می‌شود و آن handler نیز ساعت و تاریخ روی سرور را باز می‌گرداند و این مقدار بازگشته شده را می‌توان در تگی از صفحه وب نمایش داد.

مثال: ابتدا یک صفحه aspx می‌سازیم و تگ زیر را در آن قرار می‌دهیم:
<p id="datetime"></p>
ساعت و تاریخ بار شده از سرور در این تگ باید نشان داده شود.

سپس کدهای اسکریپت زیر را می‌نویسیم:
var auto_referesh = setInterval
 (
     function()
    {
         $.post
         (
            "GetDateTime.ashx",
             function (result) 
            {
                $('#datetime').html(result);
            }
        );
     }, 1000
 );
با نوشتن این کدها هر ثانیه یک بار، بوسیله Ajax درخواستی برای یک handler به اسم GetDateTime.ashx فرستاده می‌شود. وظیفه این handler برگرداندن تاریخ و ساعت فعلی سیستم سرور است. بعد از دریافت مقدار این مقدار از این handler، آنرا در تگ با شناسه datetime قرار می‌دهیم.

کد استفاده شده در handler هم به این صورت است:
<%@ WebHandler Language="C#" Class="GetDateTime" %>

using System;
using System.Web;

public class GetDateTime : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        context.Response.Write(DateTime.Now.ToString());
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}
در انتها فایل ضمیمه این مثال را از این لینک دریافت کنید:
AjaxDateTime.zip

مطالب
شروع کار با Apache Cordova در ویژوال استودیو #4
در قسمت قبل یک مثال ساده را کار کردیم. در این قسمت با jQuery Mobile آشنا شده و در پروژه‌ی خود استفاده خواهیم کرد.

توضیح تکمیلی در مورد ساختار فایل‌های پروژه
همان طور که در قسمتها قبل گفته شد، تگ اسکریپت زیر 
<script src="cordova.js"></script>
از استاندارد‌های Cordova است؛ وجود خارجی ندارد و بخشی از فرآیند ساخت برنامه است.
اگر توجه کنید فایلی با نام platformOverrides.js در فولدر scripts موجود در ریشه، خالی است اما در فولدر merges موجود در ریشه‌ی پروژه مربوط به هر پلتفرم و همنام آن پلتفرم قرار دارد. برای مثال برای android، یک چنین دایرکتوری merges/android/scripts وجود دارد که درون آن فایلی به‌نام  platformOverrides.js دیده می‌شود و اگر دقت کنید، همنام فایل موجود در فولدر scripts موجود در ریشه پروژه است که درون خود فایلی بنام  android2.3-jscompat.js را فراخوانی می‌کند. (برای کمک به سازگاری کتابخانه‌های ثالث)
در زمان build ، تمام فایل‌های موجود در "merges/"platformname ، در فولدر‌های هم نامی در شاخه‌ی ریشه‌ی پروژه کپی شده و جایگزین فایل‌های قبلی خواهند شد.

 مثال برای اندروید 
در زمان ساخت (build) فایل scripts/platformOverrides.js با فایل merges/windows/scripts/platformoverrides.js جایگزین خواهد شد. این امکان برای فلدر‌های css, images و بقیه‌ی آنها نیز امکان پذیر است.
توجه داشته باشید این ادغام در سطح فایل‌ها و نه در سطح محتوای فایل‌ها انجام می‌شود.

نکته 
برای محتوای موجود در فولدر res، قضیه فرق می‌کند. زیرا محتوای این resource‌ها برای اپلیکیشن پکیچ ضروریست؛ پیش از آن که کد‌های ما درون WebView یا host رندر شوند. باید توجه کرد که این فولدر به جهت اینکه منابع اصلی را (با توجه به پلتفرم باید از فایل‌های مشخص آن برای تشخیص ساختار فولدر‌های اپلیکیشن پکیچ استفاده کند) در بر دارد و این منابع باید در زمان ساخت پروژه تشخیص داده شوند.


رویداد‌های بومی
در زیر تعدادی از رخدادهایی که در Cordova گنجانده شده‌اند تا اپلیکیشن ما از رخداد‌های دستگاه با خبر شوند، نشان داده شده است. برای تست آنها به راحتی بعد از اجرای برنامه توسط شبیه ساز Ripple می‌توانید از قسمت Events، رخداد مورد نظر را شبیه سازی کنید:
(function () {
    "use strict";

    document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );

    function onDeviceReady() {
        // Handle the Cordova pause and resume events
        document.addEventListener( 'pause', onPause.bind( this ), false );
        document.addEventListener('resume', onResume.bind(this), false);
        document.addEventListener('menubutton', onMenuButton.bind(this), false);
        document.addEventListener('backbutton', onBackButton.bind(this), false);
        //document.addEventListener('searchbutton', onResume.bind(this), false);
        //document.addEventListener('endcallbutton', onResume.bind(this), false);
        //document.addEventListener('offline', onResume.bind(this), false);
        //document.addEventListener('online', onResume.bind(this), false);
        //document.addEventListener('startcallbutton', onResume.bind(this), false);
        //document.addEventListener('volumedownbutton', onResume.bind(this), false);
        //document.addEventListener('volumeupbutton', onResume.bind(this), false);
        
        // TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
    };

    function onPause() {
        // TODO: This application has been suspended. Save application state here.
        alert("paused");
    };

    function onResume() {
        alert("resume");
    };
    function onMenuButton() {
        alert("menu");
    };

    function onBackButton() {
        alert("back button");
    };
   

} )();

.در مقالات آینده از افزونه‌های موجود، برای مدیریت رخداد‌های باتری سیستم استفاده خواهیم کرد



jQuery Mobile
جی کوئری موبایل، یک فریمورک (UI Framework) جدید با قابلیت استفاده‌ی آسان برای ساخت اپلیکیشن‌های چند سکویی موبایل است. با استفاده از این فریمورک شما قادر خواهید بود اپلیکیشن‌های موبایل بهینه شده برای اجرا بر روی تمام تلفن‌ها، دسکتاپ و تبلت‌ها را بسازید. علاوه بر این، جی کوئری موبایل می‌تواند یک فریمورک ایده آل برای توسعه دهند گان و طراحان وب که قصد ساخت اپلیکیشن‌های غنی وب برای موبایل را دارند، باشد.

 Supported Devices

  Phones/Tablets 
  Android 1.6+ 
  BlackBerry 5+ 
  iOS 3+ 
  Windows Phone 7 
  WebOS 1.4+ 
  Symbian (Nokia S60) 
  Firefox Mobile Opera Mobile 11+ 
  Opera Mini 5+ 
  Desktop browsers 
  Chrome 11+ 
  Firefox 3.6+ 
  Internet Explorer 7+ 
  Safari   


برای نصب jQuery Mobile کافی است دستورات  زیر را در package manager console ویژوال استودیو استفاده کنید:

PM>install-package jquery

PM>install-package jquery.mobile.rtl

بعد از دانلود فایل‌های مورد نظر خود، فولدری بنام jquery.mobile.rtl در ریشه پروژه ایجاد خواهد شد. به ترتیب فایل های rtl.jquery.mobile-1.4.0.css و rtl.jquery.mobile-1.4.0.js موجود در زیر شاخه‌های فلدر مذکور را به head و آخر body فایل index.html اضافه کنید.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>CordovaApp01</title>

    <!-- CordovaApp01 references -->
    <link href="css/index.css" rel="stylesheet" />
    <link href="jquery.mobile.rtl/css/themes/default/rtl.jquery.mobile-1.4.0.css" rel="stylesheet" />
</head>
<body>
    <div data-role="page" id="page1">
        <div data-role="header">
            <h1>اولین برنامه</h1>
        </div>
        <div data-role="content">
            <p>سلام من محتوای اولین برنامه هستم</p>
        </div>
        <div data-role="footer">
            <h1>من فوتر هستم</h1>
        </div>
    </div>
<!-- Cordova reference, this is added to your app when it's built. -->
<script src="scripts/jquery-2.1.3.min.js"></script>
    <script src="cordova.js"></script>
    <script src="scripts/platformOverrides.js"></script>
    <script src="scripts/index.js"></script>

    <script src="jquery.mobile.rtl/js/rtl.jquery.mobile-1.4.0.js"></script>
</body>
</html>
در تکه کد بالا ما یکی از ویجت‌های jQuery Mobile را استفاده کردیم و با استفاده از ویژگی data-role که برای div اصلی با page مقدار دهی شده است، یک  کانتینر (page container) برای ویجت page جی کوئری موبایل تعریف شده‌است.

نتیجه‌ی نهایی به شکل زیر خواهد بود:

در مقاله‌ی بعد به استفاده از plugin‌ها خواهیم پرداخت.

ادامه دارد...

مطالب
آموزش (jQuery) جی کوئری 6#
در ادامه مطلب قبلی  آموزش (jQuery) جی کوئری 5#  به ادامه بحث  می‌پردازیم.
در پست‌های قبلی مروری بر jQuery داشته و در چند پست انواع روش‌های انتخاب عناصر صفحه وب را توسط jQuery بررسی کردیم. در پست‌های آینده با مباحث پیشرفته‌تری همچون انجام عملیاتی روی المانهای انتخاب شده، خواهیم پرداخت؛ امید است مفید واقع شود.


٢ -٢ - ایجاد  عناصر HTML جدید
گاهی اوقات نیاز می‌شود که یک یا چند عنصر جدید به صفحه‌ی در حال اجرا اضافه شوند. این حالت می‌تواند به سادگی قرار گرفتن یک متن در جایی از صفحه و یا به پیچیدگی ایجاد و نمایش یک جدول حاوی اطلاعات دریافت شده از بانک اطلاعاتی باشد.
ایجاد عناصر به صورت پویا در یک صفحه در حال اجرا کار ساده ای برای jQuery می‌باشد، زیرا همانطور که در پست آموزش (jQuery) جی کوئری 1#  مشاهده کردیم ()$ با دریافت دستور ساخت یک عنصر HTML آن را در هر زمان ایجاد می‌کند، دستور زیر :
$("<div>Hello</div>")
یک عنصر div ایجاد می‌کند و آماده افزودن آن به صفحه در هر زمان می‌باشد.تمامی توابع و متدهایی را که تاکنون بررسی کردیم قابل اعمال بروی اینگونه اشیا نیز می‌باشند. شاید در ابتدا ایجاد عناصر به این شکل خیلی مفید به نظر نرسد، اما زمانی که بخواهیم کارهای حرفه ای‌تری انجام دهیم؛ برای مثال کار با AJAX، خواهیم دید که تا چه اندازه ایجاد عناصر به این روش می‌تواند مفید باشد.
دقت کنید که یک راه کوتاهتر نیز برای ایجاد یک عنصر <div> خالی وجود دارد که به شکل زیر است:
$("<div>")
//  همه اینها معادل هستند 
$("<div></div>")
$("<div/>")
اما برای ایجاد عناصری که خود می‌توانند حاوی عناصر دیگر باشند استفاده از راههای کوتاه توصیه نمی‌شود مانند نوشتن تگ <script> .اما راههای زیادی برای انجام اینکار وجود دارد.
برای اینکه مزه اینکار را بچشید بد نیست نگاهی به مثال زیر بیندازید (نگران قسمت‌های نامفهوم نباشید به مرور با آنها آشنا خواهیم شد):
$("<div class='foo'>I have foo!</div><div>I don't</div>")
     .filter(".foo").click(function() {
          alert("I'm foo!");
      }).end().appendTo("#someParentDiv");
در این مثال ابتدا ما یک المان div ایجاد کردیم که دارای کلاس foo می‌باشد، و خود شامل یک div دیگر است. در ادامه div که دارای کلاس foo بوده را انتخاب کرده و رویداد کلیک را به آن بایند کردیم. و در انتها این div را با محتویاتش به المانی با Id=someParentDiv در سلسله مراتب DOM اضافه می‌کند.
برای اجرا این کد می‌توانید کد آن را دانلود کرده و فایل chapter2/new.divs.htmlرا اجرا کنید خروجی مانند تصویر زیر خواهد بود:

جهت تکمیل مطلب فعلی یک مثال کاملتر از این سایت جهت بررسی انتخاب کردم:
$( "<div/>", {
    "class": "test",
     text: "Click me!",
     click: function() {
           $( this ).toggleClass( "test" );
     }
   }).appendTo( "body" );
در این مثال کمی پیشرفته‌تر یک div ایجاد شده کلاس test را برای آن قرار داده و عنوان ان را برابر text قرار میدهد و یک رویداد کلیک برای آن تعریف می‌کند و در نهایت آن را به body سایت اضافه می‌کند.

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

مطالب
JQuery Plugins #1
جی‌کوئری به عنوان مهم‌ترین و پرکاربردترین کتابخانه جاوا اسکریپتی، حالا در اکثر سایت‌های اینترنتی استفاده می‌شود و هر روز به قابلیت‌ها و امکانات آن اضافه می‌گردد. اما بیش از خود این کتابخانه، پلاگین‌های آن است که تحول عظیمی را در طراحی وب سایت‌ها ایجاد نموده است. از انواع اسلایدها، تصاویر، منو‌ها، Tooltip ها، نمودارها، انیمیشن، جداول و هزاران پلاگین دیگر، همه و همه کد‌های جاوا اسکریپتی است که با استفاده از جی کوئری به صورت پلاگین نوشته شده است و امکان استفاده مجدد را به ما می‌دهد.

از کجا شروع کنیم
برای نوشتن پلاگین یک تابع با نام خاصیتی جدید را به jQuery.fn اضافه می‌نماییم.
jQuery.fn.myPlugin = function() {
//محتویات پلاگین را اینجا می‌نویسیم
};
اما، برای اینکه بتوانیم از میانبر $ در پلاگین استفاده نماییم و تداخلی با سایر کتابخانه‌ها نداشته باشد، از الگوی (IIFE (Immediately Invoked Function Expression D به صورت زیر استفاده می‌نماییم:
(function( $ ) {
  $.fn.myPlugin = function() {
  //محتویات پلاگین را اینجا می‌نویسیم
    };
})( jQuery );

محتوای پلاگین
حال می‌توانیم در تابع، کدهای پلاگین خود را بنویسیم. برای دسترسی به شیء پاس داده شده به پلاگین، از کلمه کلیدی this استفاده کرده و لازم نیست از (this)$ استفاده نماییم. در زیر یک پلاگین ساده تهیه شده است که با رفتن ماوس بر روی یک متن، خطی زیر آن می‌کشد:
(function($){
    $.fn.underline= function() {
        this.hover(function(){
            $(this).css( { text-decoration : underline })
        }, function(){
            $(this).css( { text-decoration : none } )
        });
    };
})(jQuery);
 
$("p").underline();
پلاگین بالا مقدار یا شیء ایی را بر نمی‌گرداند؛ اما اگر بخواهیم مقداری را برگردانیم از return استفاده می‌نماییم:
(function( $ ){

  $.fn.maxHeight = function() {
  
    var max = 0;

    this.each(function() {
      max = Math.max( max, $(this).height() );
    });

    return max;
  };
})( jQuery );
var tallest = $('div').maxHeight(); // بیشترین ارتفاع عنصر را برمی گرداند

حفظ خاصیت زنجیره‌ای پلاگین ها
در مثال بالا یک مقدار عددی برگردانده شده است؛ اما برای اینکه بتوانیم بصورت زنجیر وار خروجی پلاگین را به تابع یا هر پالاگین دیگری پاس دهیم از تابع each بصورت زیر استفاده می‌نماییم:
(function( $ ){

  $.fn.lockDimensions = function( type ) {  

    return this.each(function() {

      var $this = $(this);

      if ( !type || type == 'width' ) {
        $this.width( $this.width() );
      }

      if ( !type || type == 'height' ) {
        $this.height( $this.height() );
      }

    });

  };
})( jQuery );
$('div').lockDimensions('width').css('color', 'red');
در پلاگین بالا با از تابع each برای روی this و برگرداندن آن با return برای حفظ خاصیت زنجیره‌ای پلاگین استفاده می‌نماییم. در تابع each می‌بایست از (this)$ برای انجام عملیات بر روی شیء پاس داده شده استفاده کنیم. بدین صورت بعد از صدا زدن پلاگین، دوباره می‌توانیم از هر پلاگین یا تابع جی کوئری دیگری بر روی خروجی استفاده نماییم.

پیش فرض‌ها و تنظیمات
در پلاگین‌های پیشرفته‌تر می‌توانیم تنظیمات پیش فرضی را برای پلاگین در نظر بگیریم و این تنظیمات را به عنوان پارامتر ورودی از کاربر دریافت نماییم. جی کوئری دارای تابعی به نام extend است که امکان گسترش و ترکیب دو شیء را امکان پذیر می‌سازد به مثال زیر توجه نمایید:
(function( $ ){

  $.fn.tooltip = function( options ) {  

    var settings = $.extend( {
      'location'         : 'top',
      'background-color' : 'blue'
    }, options);

    return this.each(function() {        

      // Tooltip plugin code here

    });

  };
})( jQuery );
$('div').tooltip({
  'location' : 'left'
});
در این مثال، شیء settings با دو خاصیت location و background-color تعریف شده که با شیء options که از ورودی پلاگین دریافت نموده‌ایم با استفاده از تابع extend ترکیب شده است. خاصیت‌های که تعیین نشده باشند با مقادیر پیش فرض آن‌ها تکمیل می‌گردد.
ادامه دارد...
مطالب
تبادل داده‌ها بین لایه‌ها؛ قسمت آخر

روش سوم: DTO (Data transfer objects) 

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

در این روش ما سعی می‌کنیم طراحی کلاس‌ها را به اصطلاح مسطح ( flatten) کنیم تا بر مشکل double loop که در قسمت قبل بحث کردیم غلبه کنیم. در کد ذیل مشاهده می‌کنید که چگونه کلاس CusomerDTO از CustomerEntity ،  مشتق می‌شود و کلاس Address را با CustomerEntity ادغام می‌کند؛ تا برای افزایش سرعت لود و نمایش داده‌ها، یک کلاس de-normalized شده ایجاد نماید. 

public class CustomerDTO : CustomerEntity 
{
    public AddressEntity _Address = new AddressEntity();
}

در کد ذیل می‌توانید مشاهده کنید که چگونه با استفاده از فقط یک loop یک کلاس de-normalized شده را پر می‌کنیم. 

foreach (DataRow o1 in oCustomers.Tables[0].Rows)
{
CustomerDTO o = new CustomerDTO();
o.CustomerCode = o1[0].ToString();
o.CustomerName = o1[1].ToString();
o._Address.Address1 =  o1[2].ToString();
o._Address.Address2 = o1[3].ToString();
obj.Add(o);
}

UI هم به راحتی می‌تواند DTO را فراخوانی کرده و دیتا را دریافت کند.


مزایا و معایب روش DTO 

یکی از بزرگترین مزایای این روش سرعت زیاد در بارگذاری اطلاعات، به دلیل استفاده کردن از ساختار de-normalized می‌باشد. اما همین مسئله خود یک عیب محسوب می‌شود؛ به این دلیل که اصول شئ گرایی را نقض می‌کند.


روش چهارم: Hybrid approach (Entity + DTO) 

از یک طرف کلاس‌های Entity که دنیای واقعی را مدل خواهند کرد و همچنین اصول شئ گرایی را رعایت می‌کنند و از یک طرف دیگر DTO نیز یک ساختار flatten را برای رسیدن به اهداف  کارآیی دنبال خواهند کرد. خوب، به نظر می‌رسد که بهترین کار استفاده از هر دو روش و مزایای آن روش‌ها باشد. 

زمانیکه سیستم، اهدافی مانند انجام اعمال CRUD را دنبال می‌کند و شما می‌خواهید مطمئن شوید که اطلاعات، دارای integrity می‌باشند و یا اینکه می‌خواهید این ساختار را مستقیما به کاربر نهایی ارائه دهید، استفاده کردن از روش (Entity) به عنوان یک روش normalized می‌تواند بهترین روش باشد. اما اگر می‌خواهید حجم بزرگی از دیتا را نمایش دهید، مانند گزارشات طولانی، بنابراین استفاده از  روش DTO با توجه به اینکه یک روش de-normalized به شمار می‌رود بهترین روش می‌باشد.


کدام روش بهتر است؟

Non-uniform : این روش برای حالتی است که متد‌های مربوط به data access تغییرات زیادی را تجربه نخواهند کرد. به عبارت دیگر، اگر پروژه‌ی شما در آینده دیتابیس‌های مختلفی را مبتنی بر تکنولوژی‌های متفاوت، لازم نیست پشتیبانی کند، این روش می‌تواند بهترین روش باشد.

Uniform : Entity, DTO, or hybrid : اگر امکان دارد که پروژه‌ی شما با انواع مختلف دیتابیس‌ها مانند Oracle و Postgres ارتباط برقرار کند، استفاده کردن از این روش پیشنهاد می‌شود.   
نظرات مطالب
اهمیت code review
سلام.
اگر کدی آزمایش شده، مرور شده و "کار میکنه"، دیگه نیازی به تغییر اون وجود نداره. برنامه نویس ها عموما در دوران حرفه ای خودشون، حداقل یک بار با "وسوسه بازنویسی همه چیز از نو" روبرو میشن، وسوسه ای که در ابتدا، افق های روشنی رو برامون ترسیم میکنه، اما در انتها، منجر به داشتن کدی به مراتب بدتر از اون چیزی که در ابتدا داشتیم، میشه.

وقتی کدی قدیمی (که بدون مشکل کار میکنه) رو دور میندازیم، در حقیقت داریم زمانی رو که صرف رفع ایرادهای موجود در اون کرده بودیم (که میتونه روزها، هفته ها یا ماه ها باشه) رو هدر میدیم. گذشته از این، چون احتمالا به تمام بخش های کد و عملکرد اون اشراف نداریم، چیزهایی ممکنه در کد ببینیم که به نظرمون احمقانه بیاد و حذف اونها، باز موجب از کار افتادن بخش هایی از سیستم بشه که Debug کردن اون، مستلزم صرف زمانی هستش که تیم قبلی اون زمان رو یکبار صرف این کار کرده بوده. بنابراین، نمی تونیم به عنوان یه اصل کلی عبارت "کدی که کار میکنه رو نباید تغییر داد" رو رد کنیم! این مساله، باید بازای Case های مختلف، بدقت بررسی بشه و بعد در مورد اون Case خاص، نظر داده بشه.

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

موفق باشید.
اشتراک‌ها
jQuery نسخه های 1.9 و 2.0 بتا، با تغییرات گسترده منتشر شدند

jQuery نسخه‌ی 1.9 و 2.0 بتا منتشر شدند. در این نسخه ها، تغییرات گسترده ای رخ داده که اگر به اونها دقت نشه، کدهای زیادی رو از کار میندازن. jQuery 1.9 همچنان بر روی IE 6,7,8 اجرا میشه اما در jQuery 2.0، این پشتیبانی حذف شده.
تیم توسعه‌ی jQuery، امروز همزمان با ارائه‌ی نسخه‌های 1.9 و 2.0 بتا، پلاگینی با نام jQuery Migrate رو هم منتشر کرد که حاوی متدهای حذف شده در نسخه‌های 1.9 و 2.0 هست تا مهاجرت به نسخه‌های جدید، باعث از کار افتادن کدهای قدیمی نشه و پس از مهاجرت کامل کدها، می‌تونید jQuery Migrate رو حذف کنید. کار خوبی که انجام شده این هست که jQuery Migrate از طریق Console بهتون اطلاع میده که در کدها از فلان متد منسوخ یا حذف شده استفاده شده. 
jQuery نسخه های 1.9 و 2.0 بتا، با تغییرات گسترده منتشر شدند
مطالب
بررسی تفاوت بین DTO و POCO
در ابتدا اجازه بدهید تعریف درستی از این دو واژه، ارائه کنیم.

DTO (Data Transfer Object)
به بیان خیلی ساده، DTO‌ها برای انتقال اطلاعات استفاده می‌شوند؛ پس هیچ منطق و رفتاری در این اشیاء تعریف نمی‌شود .اگر در DTO منطقی پیاده سازی شود، دیگر به آن DTO گفته نمی‌شود. اجازه بدید منظورمان را از منطق یا رفتار مشخص کنیم. منطق یا رفتار، همان متدهایی هستند که در نوع داده خود تعریف میکنیم. در #C، یک DTO تنها از خصوصیت‌ها (Properties) که از بلوک‌های Get و Set تشکیل شده‌اند، ساخته می‌شود. البته بدون کدهایی جهت اعتبار سنجی (Validation) مقادیر.

سؤال: وضعیت attribute ‌ها و Metadata‌ها چه می‌شود؟
خیلی غیر معمول نیست که از metadata‌ها در DTO، به‌منظور اعتبار سنجی یا اهداف خاص، استفاده کنیم. بعضی از attribute‌ها هیچ رفتاری را به DTO‌ها اضافه نمی‌کنند؛ ولی استفاده از DTO‌ها را در بخش‌های دیگر سیستم، ساده‌تر می‌کنند. در نتیجه هیچکدام از attribute ‌ها و metadata‌ها، شرایط DTO بودن را نقض نمی‌کنند.

مدل‌های دیگری مثل ViewModels‌ها و API Model‌ها چه می‌شوند؟
واژه DTO خیلی مبهم است. تنها چیزی که بیان می‌کند این است که شیء است و فقط و فقط شامل اطلاعات است و رفتاری ندارد. در این تعریف درباره‌ی کاربرد مورد نظر یک DTO چیزی گفته نشده. در بسیاری از معماری‌ها، DTO نقش خاصی را ایفا می‌کند. بطور مثال در معماری MVC، از DTO‌ها برای انقیاد داده (Binding) و ارسال اطلاعات به یک View استفاده میکنند. به همین خاطر این DTO‌ها بعنوان ViewModel، در معماری MVC شناخته می‌شوند که رفتاری را در خود تعریف نمی‌کنند و تنها فرمت اطلاعات مورد انتظار یک View را مهیا می‌کنند.
پس در این سناریوی خاص، ViewModel نوعی DTO می‌باشد. اما باید دقت داشته باشید، همه ViewModel‌‌ها را نمی‌توان DTO محسوب کرد؛ مثلا در معماری MVVM، ویوو مدل‌های تعریف شده، شامل رفتار هم می‌باشند. حتی در معماری MVC نیز گاهی اوقات منطقی به  ViewModel‌‌ها اضافه می‌شود که دیگر به آنها DTO نمی‌گوییم.

 
در صورت امکان، نام DTO‌ها را بر اساس استفاده‌ی آنها تعیین کنید. بطور مثال کلاسی با نام FoodDTO، مشخص نمی‌کند که این نوع، کجا و چگونه قرار است در معماری برنامه شما مورد استفاده قرار  بگیرید؛ برعکس نامگذاری به صورت FoodViewModels کاربرد آن را صراحتا بیان می‌کند.
مثالی از DTO در زبان سی شارپ :
public class ProductViewModel
{
  public int ProductId { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
  public string ImageUrl { get; set; }
  public decimal UnitPrice { get; set; }
}

کپسوله سازی و DTO ها 
کپسوله سازی، یکی از اصول برنامه نویسی شیءگرا می‌باشد. اما این کپسوله سازی به DTO‌ها اعمال نمی‌شوند. به این علت که هدف کپسوله سازی، پنهان کردن فرآیند پشت صحنه‌ی ذخیره سازی اطلاعات است؛ اما در DTO هیچ فرآیندی پیاده سازی نشده و نباید هیچ State پنهانی وجود داشته باشد. پس بحث Encapsulation در DTO منتفی است. پس کار را برای خودتان سخت نکنید؛ با تعریف private setter ‌ها یا تبدیل کردن DTO به یک شیء غیرقابل تغییر (immutable). شما باید به‌راحتی بتوانید عملیات ایجاد، نوشتن و خواندن DTO‌‌ها را انجام دهید؛ همچنین باید بتوانید عملیات سریالایز کردن بر روی DTO‌‌ها را بدون فرآیند سفارشی اضافه‌ای، انجام دهید.

Field ها  یا Property ها 
سؤالی که مطرح می‌شود این است که وقتی کپسوله سازی در DTO مفهومی ندارد، چرا باید همیشه از property ‌ها استفاده کنیم؟ چرا از فیلد‌ها استفاده نکنیم (فیلد‌های public )؟
ما می‌توانیم هم از property استفاده کنیم و هم از field‌ها؛ اما بعضی از فریم ورک‌ها که کار Serialization را انجام می‌دهند، فقط با property ‌ها کار می‌کنند. بنابراین بسته به نیاز خودتان، از field‌های عمومی یا property‌ها استفاده کنید. اما عموما از Property استفاده میکنند. البته در این پیوند، پرسش و پاسخ مفصلی در این رابطه وجود دارد.

غیرقابل تغییر بودن (Immutability) و نوع رکورد ( Record Type )
غیرقابل تغییر بودن، یکی از مزیت‌های مهم در توسعه نرم افزار است. اما همانطور که در مثل بالا بیان شد، نیازی به غیرقابل تغییر کردن DTO‌‌ها نیست. با ارائه رکورد در سی شارپ 9  شرایط کمی تغییر کرد. شاید عبارت مخفف دیگری که اضافه شده Data transfer Records یا (DTRs) است. یکی از روش‌های تعریف DTR در سی شارپ 9، به شکل زیر است:
public record ProductDTO(int Id, string Name, string Description);

البته روش دیگری هم وجود دارد که شما property‌ها را تعریف کنید و از طریق سازنده، مقدار دهی شوند. ویژگی جدید init-only این امکان را فراهم می‌کند که فقط در زمان مقدار دهی اولیه (initialization)، خصوصیات مقداردهی شوند و در ادامه‌ی چرخه حیات شیء، property ‌ها فقط خواندنی هستند. این ویژگی، record‌ها را غیر قابل تغییر می‌کند.
مثال:
public record ProductDTO
{
  public int Id { get; init; }
  public string Name { get; init; }
}
var dto = new ProductDTO { Id = 1, Name = "some name" };

کلاس‌های POCO یا همان Plain Old CLR/C# Object
شی Plain Old چیست؟ هر شیءای که Plain Old باشد، می‌تواند در هر جایی از برنامه‌ی ما مورد استفاده قرار بگیرد؛ حتی در کلاس‌های Test برنامه. این اشیاء هیچگونه وابستگی برای اجرا وظایف خود، به بانک‌های اطلاعاتی و کتابخانه‌های ثالت ندارند.
برای درک بهتر این نوع کلاس‌ها، به مثال زیر دقت کنید:
public class Product : DataObject<Product>
{
  public Product(int id)
  {
    Id = id;
    InitializeFromDatabase();
  }
  private void InitializeFromDatabase()
  {
    DataHelpers.LoadFromDatabase(this);
  }
  public int Id { get; private set; }
  // other properties and methods
}
همانطور که مشاهده میکنید، این کلاس به متد استاتیکی برای کار با دیتابیس وابسته است؛ در نتیجه باعث میشود که کل کلاس، به وجود بانک اطلاعاتی وابسته شود. همچنین با ارث بری از کلاس پایه‌ی دیگری، وابستگی به یک کتابخانه‌ی ثالث ایجاد شده‌است. اجرای آزمون واحد برای چنین کلاسی، سبب fail شدن عملیات می‌شود. به این علت که ارتباط با بانک اطلاعاتی مورد نیاز متد DataHelpers، تامین نشده‌است. این شرایط، مثالی از الگوی Active Record Pattern می‌باشند. همچنین این کلاس دسترسی به منبع داده را در درون خود گنجانده است که این به معنای نقض اصل Persistence Ignorant (اصل Persistence Ignorance به طور خلاصه بیان می‌کند که در تحلیل و طراحی Business Logic به موضوع ذخیره‌سازی (Persistence) فکر نکنید (تا جای ممکن) یا به عبارت دیگر، ذهن خود را درگیر پیچیدگی‌های ذخیره سازی نکنید. برگرفته شده از breakpoint.blog.ir : روح الله دلپاک)می باشد. یکی از ویژگی‌های POCO عدم نقض الگوی فوق است.

مثالی از POCO : 
public class Product
{
  public Product(int id)
  {
    Id = id;
  }

  private Product()
  {
    // required for EF
  }

  public int Id { get; private set; }
  // other properties and methods
}
این کلاس یک POCO است:
  • برای اجرای وظایف خود به فریم ورک ثالثی وابسته نیست.
  • به کلاس پایه‌ای ( Base class) نیاز ندارد.
  • وابستگی به متد استاتیکی ندارد.
  • می تواند در هر جایی از پروژه، نمونه سازی شود.
  • اصل Persistence Ignorant را بیشتر رعایت کرده، نه بطور کامل؛ چون یک سازنده دارد که به کتابخانه‌ی ثالثی نیازمند است (سازنده‌ی بدون پارامتر که مورد نیاز EF می‌باشد).

POCO و DTO :

شاید این دو مفهموم گیج کننده باشند، ولی DTO همان POCO هست. اگر یک کلاس، DTO باشد، حتما POCO نیز هست. (مرور ویژگی‌های دو مورد در بخش‌های قبلی) ولی برعکس این وضعیت ممکن است صادق نباشد؛ مثال قبلی که در آن وابستگی به کتابخانه‌ی ثالثی در سازنده‌ی بدون پارامتر وجود داشت، DTO بودن را نقض می‌کرد. پس اگر هر دو حالت صادق بود، میتوان گفت این دو مفهوم یکی است.