پروژه bootstrap-datepaginator
LINQ to Sharepoint Class
- تمرکز اصلی پروژه، باید صرف فائق آمدن بر مشکلات و پیچیدگیهای موجود در دامین شود.
- پیچیدگیهای موجود در دامین پس از شناسایی به یک مدل تبدیل شوند.
- برقراری یک رابطهی خلاق بین متخصصان دامین و افراد تیم توسعه برای بهبود مستمر مدل ارائه شده که نهایتا راه حل مشکلات دامین است بسیار مهم میباشد.
Eric Evans is a specialist in domain modeling and design in large business systems. Since the early 1990s, he has worked on many projects developing large business systems with objects and has been deeply involved in applying Agile processes on real projects. Eric is the author of "Domain-Driven Design" (Addison-Wesley, 2003) and he leads the consulting group Domain Language, Inc.
- دامین ساده و سر راست نباشد.
- افراد تیم توسعه با طراحی / برنامه نویسی شی گرا آشنا باشند.
- دسترسی به افراد متخصص در مسائل مرتبط با دامین آسان باشد.
- فرآیند تولید نرم افزار، یک فرآیند چابک باشد.
در ادامه میپردازم به اینکه ابزار DDD برای شکستن پیچیدگیهای دامین و تبدیل آنها به مدل کدامند؟
- Entity
- Value Object
- Aggregate
- Service
- Repository
- Factory
قبلا توضیح داده بودم که طراحی متاثر از حوزهی کاری (Domain Driven Design) منجر به کاهش، درک و نهایتا قابل مدیریت کردن پیچیدگیهای موجود در حوزه عملیاتی نرم افزار (Domain) میشود. توجه کنیم که تحلیل و مدلسازی، فعالیتهای رایج در حوزه هایی مانند حمل و نقل، اکتشافات، هوا فضا، شبکههای اجتماعی و ... میتواند بسیار دشوار باشد.
برای مثال فرض کنید که میخواهید به مدلسازی نرم افزاری بپردازید که هدف تولید آن پیش بینی وضع آب و هوا است. این حوزه کاری (پیش بینی وضع آب و هوا) بویژه همواره یکی از حوزه (Domain)های پیچیده برای طراحان مدل محسوب میشود. DDD روشی است که با بکار گیری آن میتوانید این پیچیدگیها را بسیار کاهش دهید. توسعه سیستمهای پیچیده بدون رعایت قواعدی همه فهم، نهایتا نرم افزار را به مجموعه ای از کدهای غیر خوانا و دیرفهم تبدیل میکند که احتمالا نسل بعدی توسعه دهندگانش را تشویق به بازنویسی آن خواهد کرد.
DDD در واقع روشی است برای دقیقتر فکر کردن در مورد نحوه ارتباط و تعامل اجزای مدل با یکدیگر. این سبک طراحی (DDD) به تولید مدلی از اشیاء میانجامد که نهایتا تصویری قابل درک (Model) از مسائل مطرح در حوزهی کاری ارائه میدهند. این مدل ارزشمند است وقتی که:
1- نمایی آشکار و در عین حال در نهایت سادگی و وضوح از همهی مفاهیمی باشد که در حوزه عملیاتی نرم افزار(Domain) وجود دارد.
2- به تناسب درک کاملتری که از حوزه کاری کسب میشود بتوان این مدل را بهبود و توسعه داد(Refactoring).
در DDD کوشش میشود که با برقراری ارتباطی منطقی بین اشیاء، و رعایت سطوحی از انتزاع یک مشکل بزرگتر را به مشکلات کوچکتر شکست و سپس به حل این مشکلات کوچکتر پرداخت.
توجه کنیم که DDD به چگونگی سازماندهی اشیاء توجه ویژه ای دارد ولی DDD چیزی درباره برنامه نویسی شی گرا نیست. DDD متدولوژیی است که با بهره گیری از مفاهیم شی گرایی و مجموعه ای از تجارب ممتاز توسعه نرم افزار (Best Practice) پیچیدگیها را و قابلیت توسعه و نگهداری نرم افزار را بهبود میدهد.
ایده مستتر در DDD ساده است. اگر در حوزه کاری مفهوم (Concept) ارزشمندی وجود دارد باید بتوان آن را به وضوح در مدل مشاهده کرد. برای مثال صحیح نیست که یک شرط ارزشمند حوزه کسب و کار را با مجموعهی سخت فهمی از If / Else ها، در مدل نشان داد. این شرط مهم را میتوان با Specification pattern پیاده سازی کرد تا تصویری خواناتر از Domain در مدل بوجود بیاید.
مدلی که دستیبابی به آن در DDD دنبال میشود مدلی است سر راست و گویا با در نظر گرفتن همه جوانب و قواعد حوزهی عمل نرم افزار. در این مدل مطلوب و ایده آل به مسائل ذخیره سازی (persistence) پرداخته نمیشود. (رعایت اصل PI). این مدل نگران چگونگی نمایش دادهها در واسط کاربری نیست. این مدل نگران داستانهای Ajax نیست. این مدل یک مدل Pureاست که دوست داریم حتی المقدور POCO باشد. این مدلی است برای بیان قواعد و منطق موجود در حوزه عمل نرم افزار. این قواعد همیشه تغییر میکنند و مدلی که از آموزههای DDDالهام گرفته باشد، راحتتر پذیرای این تغییرات خواهد بود. به همین دلیل DDD با روشهای توسعه به سبک اجایل نیز قرابت بیشتری دارد.
git log --oneline
Install-Module -Name Microsoft.PowerShell.Crescendo
$Configuration = @{ '$schema' = "https://aka.ms/PowerShell/Crescendo/Schemas/2021-11" Commands = @() } $parameters = @{ Verb = "Get" Noun = "GitLog" OriginalName = "git" } $Configuration.Commands += New-CrescendoCommand @parameters $Configuration | ConvertTo-Json -Depth 3 | Out-File ./git-ps.json
{ "Commands": [ { "Verb": "Get", "Noun": "GitLog", "OriginalName": "git", "OriginalCommandElements": null, "Platform": [ "Windows", "Linux", "MacOS" ], "Elevation": null, "Aliases": null, "DefaultParameterSetName": null, "SupportsShouldProcess": false, "ConfirmImpact": null, "SupportsTransactions": false, "NoInvocation": false, "Description": null, "Usage": null, "Parameters": [], "Examples": [], "OriginalText": null, "HelpLinks": null, "OutputHandlers": null } ], "$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2021-11" }
"": "https://aka.ms/PowerShell/Crescendo/Schemas/2021-11",
اکنون باید این فایل Configuration را به Crescendo معرفی کنیم تا cmdlet را برایمان تولید کند. اینکار را توسط Export-CrescendoModule انجام خواهیم داد:
Export-CrescendoModule -Configuration ./git-ps.json -ModuleName ./git-ps.psm1
با اجرای دستور فوق، فایلهای git.psm1 و همچنین git.psd1 تولید خواهند شد. نیاز به بررسی فایلهای جنریت شده نیست؛ چون تنها جایی که با آن باید در ارتباط باشیم، همان فایل JSON ابتدای بحث است که در ادامه آن را بررسی خواهیم کرد. اما قبل از آن اجازه دهید ماژول تولید شده را Import کنیم و دستور Get-GitLog را وارد کنیم:
PP /> Import-Module ./git-ps.psd1 PS /> Get-GitLog usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] [--super-prefix=<path>] [--config-env=<name>=<envvar>] <command> [<args>] These are common Git commands used in various situations: start a working area (see also: git help tutorial) clone Clone a repository into a new directory init Create an empty Git repository or reinitialize an existing one work on the current change (see also: git help everyday) add Add file contents to the index mv Move or rename a file, a directory, or a symlink restore Restore working tree files rm Remove files from the working tree and from the index examine the history and state (see also: git help revisions) bisect Use binary search to find the commit that introduced a bug diff Show changes between commits, commit and working tree, etc grep Print lines matching a pattern log Show commit logs show Show various types of objects status Show the working tree status grow, mark and tweak your common history branch List, create, or delete branches commit Record changes to the repository merge Join two or more development histories together rebase Reapply commits on top of another base tip reset Reset current HEAD to the specified state switch Switch branches tag Create, list, delete or verify a tag object signed with GPG collaborate (see also: git help workflows) fetch Download objects and refs from another repository pull Fetch from and integrate with another repository or a local branch push Update remote refs along with associated objects 'git help -a' and 'git help -g' list available subcommands and some concept guides. See 'git help <command>' or 'git help <concept>' to read about a specific subcommand or concept. See 'git help git' for an overview of the system.
همانطور که مشاهده میکنید، خروجی دستور git، نمایش داده شدهاست. دلیل آن نیز این است که در فایل configuration، هیچ آرگومانی را به عنوان ورودی آن تعیین نکردهایم. برای اضافه کردن آرگومانهای موردنظر باید پراپرتی OrginalCommandElements را مقدار دهی کنیم:
"OriginalCommandElements": ["log", "--oneline"],
بنابراین با فراخوانی دستور Get-GitLog، در اصل دستور git log —oneline فراخوانی خواهد شد:
PS /> Get-GitLog e9590e8 init
اما تا اینجا نیز خروجی به صورت رشتهایی است. برای داشتن یک خروجی Object، باید پراپرتی OutputHandlers را از Configuration، تغییر دهیم:
"OutputHandlers": [ { "ParameterSetName": "Default", "Handler": "$args[0] | ForEach-Object { $hash, $message = $_.Split(' ', 2) ; [PSCustomObject]@{ Hash = $hash; Message = $message } }" } ]
در اینجا توسط args$ به خروجی کامند اصلی دسترسی خواهیم داشت. این خروجی را سپس با کمک ForEach-Object، به یک شیء با پراپرتیهای Hash و Message تبدیل کردهایم. در اینجا فقط میخواستم روال تهیه یک آبجکت را از کامندهایی که خروجی JSON ندارند، نشان دهم؛ اما خوشبختانه توسط پرچم pretty در git log، امکان تهیهی خروجی JSON را نیز داریم:
git log --pretty=format:'{"commit": "%h", "author": "%an", "date": "%ad", "message": "%s"}'
در نتیجه عملاً نیازی به split کردن نیست و بجای آن میتوانیم به صورت مستقیم، خروجی را توسط ConvertFrom-Json پارز کنیم:
"OutputHandlers": [ { "ParameterSetName": "Default", "Handler": "$args[0] | ConvertFrom-Json" } ]
همچنین درون فایل schema با کمک پراپرتی Parameters، امکان تعریف پارامتر را نیز برای کامند Get-GitLog خواهیم داشت. به عنوان مثال میتوانیم فلگ reverse را نیز به کامند اصلی از طریق PowerShell ارسال کنیم:
"Parameters": [ { "Name": "reverse", "OriginalName": "--reverse", "ParameterType": "switch", "Description": "Reverse the order of the commits in the output." } ],
دقت داشته باشیم که با هربار تغییر فایل schema باید توسط دستور Export-CrescendoModule ماژول موردنظر را تولید کنید:
Export-CrescendoModule -Configuration ./git-ps.json -ModuleName ./git-ps.psm1 Import-Module ./git-ps.psd1
در نهایت cmdletمان به این صورت قابل استفاده خواهد بود:
معادل Storybook برای Blazor
The clone of "Storybook" for Blazor, a frontend workshop for building UI components and pages in isolation.