Come learn the top 7 reasons to use Visual Studio 2017 if you are a C++ developer. Whether you are using the product and are looking to upgrade, or you never used it before but you are considering it now, join us to discover how Visual Studio 2017 raises the bar in terms of C++ productivity. From C++ standards conformance to coding productivity, cross-platform development for Windows, Linux, Android, and iOS and CMake support, these are only a few of the topics we discuss in this demo-packed session.
نوشتن اپ های Native برای موبایل
In the February 2016 issue of MSDN Magazine, I showed how to create a custom scripting language based on the Split-And-Merge algorithm for parsing mathematical expressions in C# (msdn.com/magazine/mt632273). I called my language Customizable Scripting in C#, or CSCS. Recently, I published an E-book that provided more details about creating a custom language (bit.ly/2yijCod). Creating your own scripting language might not initially seem to be particularly useful, even though there are some interesting applications of it (for example, game cheating). I also found some applications in Unity programming.
You might think, as a developer, that nothing but the best is good enough as a development database. You might be mistaken. There is a lot to be said for LocalDB, but Ed Elliott argues that every edition has its pros and cons, and you need to consider Cloud-based resources, VMs and Containerised databases too. There is a whole range of alternatives and how you choose depends on the type of database you are developing, but for Ed, LocalDB gets the five-star accolade
PdfRpt-2.1.zip
- Started VectorCharts and added the PieChart class. See Samples/PdfReportSamples/VectorPieChart/VectorPieChartPdfReport.cs for more info. - Added VerticalBarChart. - Added HorizontalBarChart. - See Samples/PdfReportSamples/VectorBarChart/VectorBarChartPdfReport.cs for more info. - Fixed HeaderCell's HorizontalAlignment value. Thnx to Punker76 for the patch. - Added a new CustomHrHTMLTagProcessor to fix null reference exceptions of iTextSharp's HtmlWorker during processing of HR tags. - Now HeaderCell's caption has a higher priority than DataAnnotations (column display name attributes). - Updated the ASP.NET Web forms sample to demonstrate how to create an in memory PDF file inside an update panel
مدیریت تغییرات گریدی از اطلاعات به کمک استفاده از الگوی واحد کار مشترک بین ViewModel و لایه سرویس
در این صفحه با کلیک بر روی دکمه به علاوه، یک ردیف به ردیفهای موجود اضافه شده و در اینجا میتوان اطلاعات کاربر جدیدی به همراه سطح دسترسی او را وارد و ذخیره کرد و یا حتی اطلاعات کاربران موجود را ویرایش نمود. اگر بخواهیم مانند مراحلی که در قسمت قبل در مورد تعریف یک صفحه جدید در برنامه توضیح داده شد، عمل کنیم، به صورت خلاصه به ترتیب ذیل عمل شده است:
1) ایجاد صفحه تغییر مشخصات کاربر
ابتدا صفحه Views\Admin\AddNewUser.xaml به پروژه ریشه که Viewهای برنامه در آن تعریف میشوند، اضافه شده است. به همراه دو دکمه و یک ListView که تطابق بهتری با قالب متروی مورد استفاده دارد.
2) تنظیم اعتبارسنجی صفحه اضافه شده
مرحله بعد تعریف هر صفحهای در سیستم، مشخص سازی وضعیت دسترسی به آن است:
/// <summary> /// افزودن و مدیریت کاربران سیستم /// </summary> [PageAuthorization(AuthorizationType.ApplyRequiredRoles, "IsAdmin, CanAddNewUser")]
3) تغییر منوی برنامه جهت اشاره به صفحه جدید
در ادامه در فایل منوی برنامه Views\MainMenu.xaml تعریف دسترسی به صفحه Views\Admin\AddNewUser.xaml قید شده است:
<Button Style="{DynamicResource MetroCircleButtonStyle}" Height="55" Width="55" Command="{Binding DoNavigate}" CommandParameter="\Views\Admin\AddNewUser.xaml" Margin="2"> <Rectangle Width="28" Height="17.25"> <Rectangle.Fill> <VisualBrush Stretch="Fill" Visual="{StaticResource appbar_user_add}" /> </Rectangle.Fill> </Rectangle> </Button>
4) ایجاد ViewModel متناظر با صفحه
مرحله نهایی تعریف صفحه AddNewUser، افزودن ViewModel متناظر با آن است که سورس کامل آنرا در فایل ViewModels\Admin\AddNewUserViewModel.cs پروژه Infrastructure میتوانید ملاحظه کنید.
نکته مهم این ViewModel، ارائه خاصیت لیست کاربران از نوع ObservableCollection به View و گرید برنامه است:
public ObservableCollection<User> UsersList { set; get; }
/// <summary> /// جهت مقاصد انقیاد دادهها در دبلیو پی اف طراحی شده است /// لیستی از کاربران سیستم را باز میگرداند /// </summary> /// <param name="count">تعداد کاربر مد نظر</param> /// <returns>لیستی از کاربران</returns> public ObservableCollection<User> GetSyncedUsersList(int count = 1000) { _users.OrderBy(x => x.FriendlyName).Take(count) .Load(); // For Databinding with WPF. // Before calling this method you need to fill the context by using `Load()` method. return _users.Local; }
در اینجا از قابلیت خاصیتی به نام Local که یک ObservableCollection تحت نظر EF را بازگشت میدهد، استفاده شده است. برای استفاده از این خاصیت، ابتدا باید کوئری خود را تهیه و سپس متد Load را بر روی آن فراخوانی کرد. سپس خاصیت Local بر اساس اطلاعات کوئری قبلی پر و مقدار دهی خواهد شد.
علت انتخاب نام Synced برای این متد، تحت نظر بودن اطلاعات خاصیت Local است تا زمانیکه Context تعریف شده زنده نگه داشته شود. به همین جهت در برنامه جاری از روش زنده نگه داشتن Context به ازای یک ViewModel استفاده شده است.
به Context، توسط اینترفیس IUnitOfWork تزریق شده در سازنده کلاس ViewModel میتوان دسترسی یافت. چون در اینجا از تزریق وابستگیها استفاده شده است، وهلهای که IUnitOfWork کلاس AddNewUserViewModel را تشکیل میدهد، دقیقا همان وهلهای است که در کلاس UsersService لایه سرویس استفاده شده است. در نتیجه، در گرید برنامه هر تغییری اعمال شود، تحت نظر IUnitOfWork خواهد بود و صرفا با فراخوانی متد uow.ApplyAllChanges آن، کلیه تغییرات تمام ردیفهای تحت نظر EF به صورت خودکار در بانک اطلاعاتی درج و یا به روز خواهند شد.
همچنین در مورد ViewModelContextHasChanges نیز در قسمت قبل بحث شد. در اینجا پیاده سازی کننده آن صرفا خاصیت uow.ContextHasChanges است. به این ترتیب اگر کاربر، تغییری را در صفحه داده باشد و بخواهد به صفحه دیگری رجوع کند، با پیام زیر مواجه خواهد شد:
از همین خاصیت برای فعال و غیرفعال کردن دکمه ذخیره سازی اطلاعات نیز استفاده شده است:
/// <summary> /// فعال و غیرفعال سازی خودکار دکمه ثبت /// این متد به صورت خودکار توسط RelayCommand کنترل میشود /// </summary> private bool canDoSave() { // آیا در حین نمایش صفحهای دیگر باید به کاربر پیغام داد که اطلاعات ذخیره نشدهای وجود دارد؟ return ViewModelContextHasChanges; }
/// <summary> /// رخداد ذخیره سازی اطلاعات را دریافت میکند /// </summary> public RelayCommand DoSave { set; get; }
DoSave = new RelayCommand(doSave, canDoSave);
این بررسی نیز بسیار سبک و سریع است. از این جهت که تغییرات Context در حافظه نگهداری میشوند و مراجعه به آن مساوی مراجعه به بانک اطلاعاتی نیست.
- جاوا اسکریپت توانایی خواندن، نوشتن، کپی و اجرای فایلها را بر روی هارد دیسک ندارد و همچنین دسترسی مستقیمی به سیستم عامل ندارد.
- مرورگرهای مدرن اجازه کار با فایلها را به جاوا اسکریپت میدهند؛ بشرطی که آن فایل از طریق input درون صفحه وب و با اجازه کاربر انتخاب شود و فقط محدود به دسترسی به همان فایل است.
- وقتی یک تَب جدید را در مرورگر باز میکنید، جاوااسکریپتِ این دو تَب (دو صفحهی جداگانه) هیچ دسترسی و اطلاعاتی بهم ندارند.
- جاوااسکریپت به کوکیها دسترسی دارد (کوکی، فایلهای متنی کوچکی برای ذخیره اطلاعات کاربر از یک سایت است؛ مانند نام کاربری و کلمه عبور). از کوکیها برای ذخیرهی توکن نشستها استفاده میشود. لذا اگه هکر بتواند کوکی نشست یک کاربر را بدست بیاورد، میتواند از هویت او استفاده کند و خود را بجای کاربر مورد نظر قرار دهد.
- جاوااسکریپت امکان تغییرات در DOM مرورگر را دارد (داخل صفحهای که جاوااسکریپت در آن اجرا شده است).
- جاوا اسکریپت با استفاده از شیء XMLHttpRequest میتواند درخواستهای HTTP را با محتوای دلخواه، به مقصد مورد نظر ارسال نماید.
- در مرورگرهای مدرن امروزی امکان دسترسی به دوربین، میکروفن، GPS وفایلهای خاصی از طریق APIهای HTML5 امکانپذیر هست.
انواع روشهای XSS
- روش بازتابی Reflected XSS Attack
- روش ذخیره شده Stored XSS Attack
- روش مبتنی بر DOM-based XSS
روش بازتابی Reflected XSS Attack
معرفی سرویسهای ارائه شده توسط شرکتهای گوگل، آمازون و مایکروسافت در قالب رایانش ابری - قسمت دوم
سرویسها و اجزای وب سرویس آمازون:
وب سرویسهای آمازون دارای اجزای زیادی میباشند. تعدادی از این سرویسها برای ارائه خدمات پردازشی و تعداد دیگری برای ارائه فضای ذخیرهسازی، عرضه شدهاند. در ادامه گروهی از این سرویسها معرفی میگردد:
- ابر محاسباتی توسعه پذیر آمازون (EC2)
- سرویس صف ساده آمازون(Simple Queue Service): یک صف پیام یا سیستم تراکنش برای برنامههای مبتنی بر اینترنت توزیع شده میباشد. این سرویس تضمین میکند که پیامها حتی در زمانی که مؤلفهای موجود نیست، گم نشود و برای انتقال پیام میان مؤلفههای مختلف که هرکدام کار جداگانهای را انجام میدهند، بسیار مناسب است.
- سرویس
آگاه سازی ساده آمازون(Simple Notification Service): ): وب سرویسی است که میتواند پیام
یک برنامه را منتشر کند و آنها را به برنامهها یا مشترکین دیگر منتقل کند. SNS متدی
را برای راهاندازی فعالیتها ارائه مینماید که برنامهها را قادر میسازد تا در
مورد اطلاعات جدید یا تغییر یافته از آنها نظرسنجی شود یا به روز رسانیها را
انجام دهند.
- سرویس
نظارت ابر آمازون(Amazon Cloud Watch): کنسولی
را فراهم میکند که در آن مصرف منابع، شاخصهای کلیدی عملکرد سایت و نشانگرهای
عملیاتی برای عواملی همچون تقاضای پردازشگر، مصرف دیسک و ورودی و خروجی شبکه را
ارائه میدهد. نتایج
معیارهایی که توسط آن کسب میشود برای فعالسازی قابلیتی به نام Auto Scaling مورد
استفاده قرار میگیرد که به صورت خودکار میتواند یک سایت EC2 را بر مبنای مجموعهای از قوانین
که توسعه دهنده ایجاد میکند، توسعه دهد.
- توازن بار منعطف(Elastic Load Balancing): نمونههای ماشین آمازون(Amazon Machine Image) با استفاده از این قابلیت، دارای امکان توازن بار ترافیکی میشوند. این قابلیت هنگامی که نمونهای دچار شکست میشود آن را کشف کرده و ترافیک را به یک نمونه سالم حتی نمونهای در محیطهای دیگر AWS مسیریابی مجدد میکند.
قیمت گذاری انواع مختلف نمونه ماشین آمازون به سه پارامتر وابسته است. اولین مورد سیستم عامل مورد استفاده است. دومین عامل مرکز دادهای است که در آن قرار گرفته و سومین عامل مدت زمانی است که اجرا میشود. نرخها بر مبنای ساعت محاسبه میشوند. علاوه بر آن مبالغ اضافی نیز بابت موارد زیر اخذ میشود:
- میزان داده
منتقل شده
- آدرسهای IP اختصاصی
- استفاده
سرور اختصاصی مجازی از فضای ذخیرهسازی بلوکی توسعه پذیر آمازون
- استفاده از توازن بار توسعه پذیر برای دو یا چند سرور
- سایر
ویژگیهای مورد نیاز
- نمونه
مبتنی بر تقاضا: نرخ
ساعتی بدون التزام طولانی مدت
-
نمونه رزرو شده: خرید قراردادی هر نمونه با هزینه به مراتب پایینتر به ازای هر ساعت بعد از رزرو اولیه
-
نمونه نقطهای: این متد برای قیمت گذاری بر روی ظرفیت استفاده نشده EC2 بر مبنای قیمت نقطه فعلی است. این قابلیت، قیمتهای بسیار پایین را به همراه خواهد داشت اما در زمانهای مختلف فرق میکند یا در زمانی که ظرفیت مازادی نباشد، در دسترس نخواهد بود.
نوع | موتور محاسبه | حافظه اصلی(GB) | ذخیره سازی(GB) | سکو |
ریز نمونه | تا دو واحد محاسباتی در انفجار بار | 0.613 | EBS | 32 یا 64 بیتی |
نمونه کوچک | یک واحد محاسباتی | 1.7 | 160 | 32 بیتی |
نمونه بزرگ | چهار واحد محاسباتی | 7.5 | 850 | 64 بیتی |
نمونه بسیار بزرگ | هشت واحد محاسباتی | 15 | 1690 | 64 بیتی |
ساخت ربات تلگرامی با #C
foreach (var update in updates) { try { offset = update.Id + 1; if (Text == "/start") { میره از دیتابیس دادهها رو میاره و نمایش میده که مثلا چند حرف و پیام میده که یک حرف را وارد کنید await bot.SendTextMessageAsync(update.Message.Chat.Id, "حرف را وارد کنید "+kalame); } else if (Text.length=1) { اگر حرف وارد شد اونوقت میره چک میکنه حرف درسته و میشونه محل مورد نظر در خونه خالی و پیام میده اگر موفقیت امیز بود که صحیح است به همراه جا خالی و حرف درست و اگر غلط بودش پیام مربوطه await bot.SendTextMessageAsync(update.Message.Chat.Id, "پیام فوق درست است"); } else { continue; } } catch (Exception ex) { continue; } } }
در NET Core 2.0. از یک اصطلاحا «compatibility shim» مخصوص استفاده میشود که امکان افزودن ارجاعات به full framework libraryها را بدون نیاز به تغییر target framework برنامه میسر میکند. یعنی در اینجا میتوان یک کتابخانهی قدیمی دات نتی را در برنامههای مبتنی بر NET Core. بر روی لینوکس نیز اجرا کرد و در این حالت نیازی به تبدیل اجباری این کتابخانه به نسخهی NET Core. آن نیست.
NET Core 2.0. پیاده سازی کنندهی NET Standard 2.0. است
NET Standard. در حقیقت یک قرار داد است که سکوهای کاری مختلف دات نتی مانند Full .NET Framework ، Xamarin ، Mono ، UWP و غیره میتوانند آنرا پیاده سازی کنند. یک نمونهی دیگر این پیاده سازیها نیز NET Core. است. برای مثال دات نت 4.6.1، استاندارد و قرار داد شمارهی 2 دات نت را پیاده سازی میکند. به همین صورت NET Core 2.0. نیز پیاده سازی کنندهی این استاندارد شماره 2 است.
با تغییرات اخیر، اکنون NuGet میتواند کتابخانههای مبتنی بر NET Standard 2. را در برنامههای مبتنی بر سکوهای کاری که آنرا پیاده سازی میکنند، بدون مشکل اضافه کند. برای مثال میتوان اسمبلیهای دات نت 4.6.1 را به برنامههای ASP.NET Core 2.0 اضافه کرد (کاری که در نگارش 1x آن به صورت مستقیم میسر نیست) و یا میتوان اسمبلیهای کامپایل شدهی برای دات نت استاندارد 2 را به برنامههای مبتنی بر دات نت 4.6.1 اضافه کرد.
آیا واقعا کتابخانههای قدیمی دات نتی توسط برنامههای NET Core 2.0. در لینوکس نیز اجرا خواهند شد؟
دات نت استاندارد، بیش از یک قرار داد چیزی نیست و پیاده سازی کنندگان آن میتوانند سطح بیشتری را نسبت به این قرار داد نیز لحاظ کنند. برای مثال دات نت 4.6.1 شامل سطح API بیشتری از دات نت استاندارد 2 است.
به همین جهت باید درنظر داشت که امکان اضافه کردن یک بستهی نیوگت از یک کتابخانهی نوشته شدهی برای دات نت کامل در برنامههای دات نت Core به معنای تضمینی برای کار کردن آن در زمان اجرا نخواهد بود. از این جهت که دات نت کامل، به همراه قسمتهایی است که در NET Standard. وجود خارجی ندارند. بنابراین اگر کتابخانهی استفاده شده صرفا این API مشترک را هدف قرار دادهاست، هم قابلیت اتصال و هم قابلیت اجرا را خواهد داشت؛ اما اگر برای مثال کسی بستهی NServiceBus را به پروژهی ASP.NET Core 2.0 اضافه کند، بدون مشکل کامپایل خواهد شد. اما از آنجائیکه این کتابخانه از MSMQ استفاده میکند که خارج از میدان دید این استاندارد است، در زمان اجرا با شکست مواجه خواهد شد.
«compatibility shim» در NET Standard 2.0. چگونه کار میکند؟
در NET Core.، پیاده سازی Object در System.Runtime قرار دارد و کد تولید شدهی توسط آن یک چنین ارجاعی را [System.Runtime]System.Object تولید میکند. اما در دات نت کلاسیک، System.Object در mscorlib قرار دارد. به همین جهت زمانیکه سعی کنید اسمبلیهای دات نت کلاسیک را در NET Core 1.x. استفاده کنید، پیام یافتن نشدن نوعها را دریافت خواهید کرد. اما در NET Core 2.0. یک پیاده سازی صوری (facade) از mscorlib وجود دارد که کار آن هدایت نوع درخواستی، به نوع واقعی پیاده سازی شدهی در NET Core. است.
در این تصویر استفادهی از یک کتابخانهی ثالث را مشاهده میکنید که ارجاعی را به [mscorlib]Microsoft.Win32.RegistryKey دارد (مبتنی بر دات نت کلاسیک است). همچنین یک mscorlib مشخص شدهی به صورت facade را نیز مشاهده میکنید. کار آن هدایت درخواست نوع واقع شدهی در mscorlib، به نوع موجود [Microsoft.Win32.Registry] Microsoft.Win32.RegistryKey است و تنها زمانی کار خواهد کرد که Microsoft.Win32.RegistryKey.dll وجود خارجی داشته باشد. به این معنا که رجیستری، یک مفهوم ویندوزی است و این کتابخانه بر روی ویندوز بدون مشکل کار میکند. اما تحت لینوکس، این قسمت خاص با پیام PlatformNotSupportedException خاتمه خواهد یافت. اما اگر قسمتهایی از این کتابخانه را استفاده کنید که در تمام سکوهای کاری وجود داشته باشند، بدون مشکل قادر به استفادهی از آن خواهید بود.
یک مثال: استفاده از کتابخانهی رمزنگاری اطلاعات Inferno
آخرین نگارش کتابخانهی رمزنگاری اطلاعات Inferno مربوط به NET 4.5.2. است. مراحل ذیل را پس از نصب SDK جدید NET Core 2.0. در خط فرمان طی میکنیم:
الف) ایجاد پوشهی UseNET452InNetCore2 و سپس ایجاد یک پروژهی کنسول جدید
dotnet new console
ب) افزودن بستهی نیوگت Inferno به پروژه
dotnet add package Inferno
log : Installing Inferno 1.4.0. warn : Package 'Inferno 1.4.0' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.0'. This package may not be fully compatible with your project. info : Package 'Inferno' is compatible with all the specified frameworks in project 'D:\UseNET452InNetCore2\UseNET452InNetCore2.csproj'. info : PackageReference for package 'Inferno' version '1.4.0' added to file 'D:\UseNET452InNetCore2\UseNET452InNetCore2.csproj'.
ج) استفاده از کتابخانهی Inferno جهت تولید یک عدد تصادفی thread safe
using System; using SecurityDriven.Inferno; namespace UseNET452InNetCore2 { class Program { static CryptoRandom random = new CryptoRandom(); static void Main(string[] args) { Console.WriteLine($"rnd: {random.NextLong()}"); } } }
د) اجرای برنامه
در ادامه اگر دستور dotnet run را صادر کنیم، ابتدا اخطاری را صادر میکند که این بسته ممکن است دارای قسمتهایی باشد که با NET core 2.0. سازگار نیست و سپس خروجی نهایی را بدون مشکل اجرا کرده و نمایش میدهد.
>dotnet run warning NU1701: This package may not be fully compatible with your project. rnd: 8167886599578111106
Dynamic Semantics
Objectها علاوه بر داده و رفتار به عنوان توصیفات ثابت، در زمان اجرا دارای یک Local State (a snapshot) از مقادیر داینامیک مربوط به اعضای دادهای خود، میباشند. مجموعه تمام حالاتی که وهلههای یک کلاس میتوانند بین آنها گذر (transition) داشته باشد، dynamic semantics مربوط به کلاس نامیده میشود و به وهلههای کلاس این امکان را میدهند تا به یک پیغام مشابه رسیده و در زمانهای مختلف از چرخه زندگی خود، به اشکال مختلف پاسخ دهند.
Method junk for the class X if (local state #1) then do something else if (local state #2) then do something different End Method
بخش اصلی هر طراحی شیء گرا، dynamic semantics وهلهها میباشد. dynamic semantics هر کلاسی باید در قالب یک دیاگرام state-transition مستند شود. شکل زیر dynamic semantics پروسههای موجود در یک سیستم عامل را در قابل یک دیاگرام حالت نمایش میدهد. این پروسهها توانایی این را دارند که در هر کدام از حالات: runnable، current process، blocked، sleeping و یا در حالت exited، قرار داشته باشند. همچنین به عنوان مثال، یک پروسه زمانی میتواند در حالت current process قرار گیرد که حتما قبلا در حالت runnable قرار داشته باشد. این اطلاعات برای ایجاد تست برای کلاسها و وهلههای آنها میتواند مفید واقع شود.
شکل 2.8 State-transition diagram notation
برخی از طراحان به طور تصادفی، dynamic semantics یک کلاس را به عنوان static semantics آن کلاس مدل میکنند. به عنوان مثال اگر color یکی از اعضای داده ای (data member) کلاس توپ باشد و بعد از وهله سازی از کلاس توپ، color آن بازهم قابل تغییر باشد، منظور اینکه توپ آبی به عنوان یک وهله از کلاس توپ در زمان حیات خود تغییر رنگ دهد، اصطلاحا میگویند: color جزء dynamic semantics کلاس توپ میباشد. با توجه به توضحیاتی که داده شد، حال اگر طراحی برای هر رنگ توپ یک کلاس جدا در نظر گرفته باشد، dynamic semantics را به عنوان static semantics مدل کرده و به احتمال زیاد ما را به سمت ایجاد مشکل Class Proliferation (ازدیاد کلاس ها) سوق خواهد داد.
Abstract Classes
به سوالات زیر توجه کنید:
- آیا هرگز میوه خوردهاید؟
- آیا هرگز پیش غذا خوردهاید؟
- آیا هرگز دسر خوردهاید؟
حال با توجه به سوالات «مزه غذا چطور بود؟ دسری که خوردید، چه تعداد کالری داشت؟ هزینه پیش غذایی که خوردید چقدر بود» پاسخ چه خواهد بود؟
من (نویسنده) ادعا میکنم که هیچ کسی تا به حال میوه نخورده است. بیشتر مردم، سیب، موز و پرتقال خوردهاند؛ میوهی قرمز رنگی به ارزش 3 پوند را نخوردهاند.
شبیه به این مسئله برای زمانی است که گارسون رستوران از شما سوال میکند: «برای شام چه چیزی میل دارید» و شما جواب میدهید: «یک پیش غذا، یک غذای اصلی و یک دسر». در این حالت چون شما دقیقا مشخص نکردهاید چه نوعی میخواهید، گارسون، مات و مبهوت خواهد ماند. همه میدانیم که چیزی تحت عنوان میوه، پیش غذا و یا وهله دسر در واقعیت وجود ندارد؛ بله این عبارات اطلاعات مفیدی را تسخیر میکنند. اگر من در دستم یک ساعت زنگی گرفته و از شما میپرسیدم: «نظرتان در مورد میوه من چیست؟»؛ بدون شک فکر میکردید من دیوانه شدهام. حال اگر در دستم سیبی گرفته و سوال قبلی را میپرسیدم، این بار از نظر شما من یک شخص عاقل بودم.
با وجود اینکه نمیتوان از میوه وهله سازی کرد، اما اطلاعات مفیدی را تسخیر میکند. در واقع میوه، یک کلاسی (concept) است که دانشی از نحوه وهله سازی وهله هایش به وسیله Type پیاده ساز خود، ندارد.
کلاسی که دانشی از نحوه وهله سازی وهلههای خود ندارد، abstract class (کلاس مجرد یا انتزاعی) نامیده میشود.
کلاسی که دانش نحوه وهله سازی وهلههای خود دارد، concrete class نامیده میشود.
در پارادایم شیء گرا، مهمترین استفاده از کلاسهای انتزاعی در مباحث ارث بری مطرح میشود.
Roles Versus Classes
مطمئن باشید انتزاع هایی را که مدل میکنید کلاس بوده و نه نقشهایی که وهلههای آنها بازی میکنند. (Be sure the abstractions that you model are classes and not simply the roles objects play)آیا مادر و پدر به عنوان یک کلاس هستند یا نقشهایی هستند که وهلههای کلاس شخص، بازی میکند؟ پاسخ این سوال وابسته به دامینی (domain) است که طراح در حال مدل سازی آن میباشد. اگر در دامین مورد نظر، مادر و پدر رفتارهای مختلفی دارند، احتمالا باید به عنوان کلاسهای جدا مدل شوند. اگر رفتارهای یکسانی دارند، در نتیجه نقشهای مختلفی هستند که وهلههای کلاس شخص بازی میکنند. به عنوان مثال، میتوان کلاس خانواده را متشکل از وهلهای از کلاس پدر، وهلهای از کلاس مادر و مجموعهای از وهلههای کلاس فرزند در نظر گرفت. در مقابل ممکن است کلاس خانواده را متشکل از وهلهای از کلاس شخص به عنوان پدر، وهلهای از کلاس شخص به عنوان مادر و آرایهای از وهلههای شخص به عنوان فرزندان، مدل کنید. قرار گرفتن در وضیعتی که هر نقش، بخشی از رفتاریهای شخص را مورد استفاده قرار میدهد، کافی نیست و باید مطمئن شوید که رفتارها واقعا متفاوت میباشند. همچنین باید به یاد داشته باشید که زمانیکه وهلهای از بخشی از رفتارهای کلاس خود استفاده میکند، نیز مشکلی وجود ندارد و لازم نیست کلاسهای دیگری را به خاطر این موضوع در طراحی خود در نظر بگیرید.
شکل 2.9 Two views of a family
برخی از طراحان به این شکل تست میکنند که اگر عضوی از واسط عمومی را نمیتوان برای نقش مورد نظر مورد استفاده قرار داد، این موضوع نشان از این دارد که باید برای نقش مورد نظر در طراحی خود کلاس جداگانهای را در نظر داشته باشند. اگر هم عضو مذکور قابل استفاده نباشد، کلاس یکسانی برای نقشهای مختلف استفاده خواهد شد. به عنوان مثال، اگر عملیات ()go_into_labor جزء عملیاتی میباشد که مادر انجام میدهد، در حالیکه پدر چنین عملیاتی را نمیتواند انجام دهد، در این حالت نیز لازم است مادر به عنوان کلاس جداگانهای در نظر گرفته شود. اگر در دامین دیگری، عوض کردن پوشاک را تنها مادر انجام میدهد، در این حالت مادر نقشی از کلاس شخص میباشد، چرا که پدر هم توانایی انجام این عملیات را دارد.
قواعد شهودی فصل دوم
همه دادهها باید در داخل کلاس خود پنهان شده باشند. (All data should be hidden within its class)
استفاده کنندگان از کلاس باید به واسط عمومی آن وابسته باشند، اما یک کلاس نباید به استفاده کنندگان خود، وابسته باشد. (Users of a class must be dependent on its public interface, but a class should not be dependent on its users)
تعداد پیغامهای موجود در قرارداد یک کلاس را کمینه سازید. (Minimize the number of messages in the protocol of a class)
پیاده سازی یک واسط عمومی یکسان کمینه برای همه کلاسها (Implement a minimal public interface that all classes understand [e.g., operations such as copy (deep versus shallow), equality testing, pretty printing, parsing from an ASCII description, etc.].)
جزئیات پیاده سازی، مانند توابع خصوصی common-code ( توابعی که کد مشترک سایر متدهای کلاس را در بدنه خود دارند) را در واسط عمومی یک کلاس قرار ندهید. (Do not put implementation details such as common-code private functions into the public interface of a class)
واسط عمومی کلاس را با اقلامی که یا استفاده کنندگان از کلاس توانایی استفاده از آن را نداشته و یا تمایلی به استفاده از آنها ندارند، آمیخته نکنید. (Do not clutter the public interface of a class with items that users of that class are not able to use or are not interested in using )
اتصال و پیوستگی مابین کلاسها باید از نوع Nil یا Export باشد؛ به این معنی که یک کلاس فقط از واسط عمومی کلاس دیگر استفاده کند یا کاری با آن نداشته باشد. (Classes should only exhibit nil or export coupling with other classes, that is, a class should only use operations in the public interface of another class or have nothing to do with that class.)
یک کلاس باید یک و تنها یک Key Abstraction را تسخیر نماید. (A class should capture one and only one key abstraction)
داده و رفتار مرتبط را در یک جا (کلاس) نگه دارید. (Keep related data and behavior in one place)
اطلاعات نامرتبط به هم را در کلاسهای جدا از هم قرار دهید. ((Spin off nonrelated information into another class (i.e., noncommunicating behavior)
مطمئن باشید انتزاع هایی را که مدل میکنید کلاس بوده و نه نقشهایی که وهلههای آنها بازی میکنند. (Be sure the abstractions that you model are classes and not simply the roles objects play)