تحلیل و مستندسازی معماری ابزار HSC بر اساس arc42

در ادامه‌ی مسیرمان برای یادگیری و تمرین عملی الگوی مستندسازی arc42، حالا زمان آن رسیده که از یک سیستم واقعی کمک بگیریم؛ سیستمی که به اندازه‌ی کافی کوچک باشد تا بتوانیم تمام بخش‌های معماری‌اش را تحلیل کنیم، اما به‌قدری کاربردی باشد که مثال‌ها و تصمیم‌های معماری‌ آن واقعی و قابل لمس باشند.

در میان مثال‌های موجود، ابزار HTML Sanity Check (HSC) یکی از بهترین گزینه‌هاست.
HSC یک ابزار متن‌باز کوچک است که روی فایل‌های HTML «سلامت‌سنجی» انجام می‌دهد—یعنی لینک‌های خراب، تصاویر گم‌شده، منابع محلی وجود‌نداشته، alt-tagهای ناقص و ده‌ها اشکال رایج دیگر را شناسایی می‌کند.

این ابزار معمولاً زمانی استفاده می‌شود که صفحات HTML از ابزارهایی مانند Asciidoctor یا Markdown تولید می‌شوند؛ جایی که تبدیل‌کننده‌ها مسئولیت بررسی کیفیت خروجی را برعهده نمی‌گیرند و این خطاها معمولاً تا زمان انتشار پنهان می‌مانند.

اما دلیل ما برای انتخاب این ابزار فقط کارکردش نیست.
HSC در کتاب "arc42 by Example" به‌عنوان یک نمونه‌ی رسمی برای مستندسازی معماری استفاده شده است.
این یعنی ساختار، تصمیم‌های فنی، زیرسیستم‌ها، آداپتورها، کیفیت‌ها و ریسک‌هایش به‌خوبی قابل تحلیل و تبدیل به یک سند arc42 هستند.

در این مقاله، ابتدا این سیستم را معرفی می‌کنیم تا مشخص شود HSC دقیقاً چه می‌کند، از چه بخش‌هایی تشکیل شده، و چه نوع چک‌هایی انجام می‌دهد. پس از آن، در بخش‌های بعدی وارد دنیای arc42 می‌شویم و گام‌به‌گام سند معماری این ابزار را مطابق با سرفصل‌های arc42 بازسازی و تحلیل می‌کنیم.

اگر قصد داری معماری نرم‌افزار را به‌صورت حرفه‌ای یاد بگیری یا می‌خواهی بفهمی مستندات arc42 در عمل چه شکلی دارند، HSC بهترین نقطه‌ی شروع است.

II.1 مقدمه و اهداف سیستم (HTML Sanity Check – HSC)

در این بخش از مستند arc42، معمولاً توضیح داده می‌شود که چرا این سیستم ساخته شده و چه نیازهایی آن را شکل می‌دهند. هدف اصلی این قسمت، این است که ذینفعان بتوانند قبل از ورود به جزئیات فنی معماری، تصویر روشنی از مسئله، هدف و ارزش سیستم به‌دست آورند.

برای مثال HTML Sanity Check (HSC)، این بخش نقش مهم‌تری دارد؛ چون HSC یک ابزار کوچک اما چندمنظوره است که در سناریوهای متفاوتی (CLI، Gradle، Maven، کتابخانه) استفاده می‌شود و لازم است پیش از بررسی معماری‌اش بفهمیم قرار است چه مسئله‌ای را حل کند.

محتوا و انگیزه ساخت سیستم

نقطه‌ی آغاز HSC، چالش رایجی است که نویسندگان و مستندسازان دیجیتال با آن مواجه می‌شوند:
وقتی خروجی HTML از ابزارهایی مثل Asciidoctor یا Markdown تولید می‌شود، اغلب هیچ تضمینی درباره‌ی صحت و کیفیت لینک‌ها، تصاویر، IDها و منابع وجود ندارد.

بنابراین HSC با هدف اصلی زیر طراحی شد:

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

این ابزار یک sanity checker است؛ یعنی کاری می‌کند که HTML تولید شده از نظر معنا و ساختار (Semantic Integrity) بررسی شود، نه فقط از نظر شکل ظاهری.


۱.۱ نمای کلی نیازمندی‌ها

پیش از ورود به معماری، لازم است فهم دقیقی از کارکردهای اصلی سیستم داشته باشیم.
این بخش به خواننده کمک می‌کند «وظیفه اصلی HSC چیست» را بفهمد.

هدف کلیدی سیستم

تولید گزارش‌های دقیق، تمیز و قابل‌فهم از خطاهای HTML.

این گزارش‌ها می‌توانند مشابه گزارش‌های تست واحد (unit test reports) باشند و شامل:

  • لینک‌های شکسته

  • تصاویر گم‌شده

  • منابع محلی ناپیدا

  • تکرار IDها

  • لینک‌های خارجی خراب

  • مشکلات syntax و ساختار

برای مثال، نویسندگان معمولاً این مسیر را طی می‌کنند:

  1. نوشتن متن در AsciiDoc یا Markdown

  2. دریافت HTML نهایی توسط ابزارهای تبدیل

  3. استفاده از HSC برای بررسی خروجی HTML

  4. دریافت گزارش مشکلاتsemantic

این جریان، فلسفه‌ی وجودی HSC را تعریف می‌کند.


سناریوهای پایه‌ی استفاده

برای درک بهتر سیستم، رفتار HSC را در ابتدایی‌ترین حالت مرور کنیم:

  1. کاربر مسیر چند فایل HTML یا پوشه مربوطه را تنظیم می‌کند.

  2. ابزار مجموعه‌ای از چک‌ها را روی فایل‌ها اجرا می‌کند.

  3. نتیجه را یا در کنسول نمایش می‌دهد یا یک گزارش HTML تولید می‌کند.

HSC می‌تواند از طریق CLI یا Gradle اجرا شود، و این تنوع در روش استفاده، بعدها روی ساختار معماری سیستم نیز تأثیر می‌گذارد.


نیازمندی‌های اصلی سیستم (Goals)

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

۱) بررسی خطاهای معنایی HTML

هسته‌ی اصلی HSC این است که فایل‌های HTML را از نظر semantic integrity بررسی کند؛ یعنی بتواند مشکلاتی مثل لینک‌های داخلی شکسته، تصاویر گم‌شده یا منابع ناپیدا را شناسایی کند.

۲) قابل اجرا بودن به‌عنوان پلاگین Gradle و Maven

HSC باید قابلیت یکپارچه‌سازی در فرآیند ساخت پروژه را داشته باشد. بنابراین لازم است به‌عنوان پلاگین Gradle و پلاگین Maven قابل اجرا باشد تا تیم‌های مختلف بتوانند آن را در ساختار CI/CD خود قرار دهند.

۳) پشتیبانی از چندین فایل ورودی در یک اجرا

کاربر باید بتواند به‌جای یک فایل HTML، مجموعه‌ای از فایل‌ها یا یک پوشه کامل را به ابزار بدهد. HSC باید همه آن‌ها را در یک مرحله پردازش و یک گزارش واحد و تجمیع‌شده تولید کند.

۴) ارائه پیشنهاد برای رفع خطاها

وقتی HSC خطایی را پیدا می‌کند، فقط گزارش آن کافی نیست؛ باید بتواند پیشنهاد یا سرنخی برای رفع خطا ارائه دهد. مثلاً اگر لینک شکسته است، مقادیر مشابه یا اشتباه تایپی ممکن را پیشنهاد کند.

۵) پیکربندی‌پذیری بالا

رفتار سیستم باید قابل تنظیم باشد.
کاربر باید بتواند:

  • مسیر فایل‌ها

  • مسیر خروجی گزارش

  • timeout چک لینک‌ها

  • نحوه برخورد با status codeهای لینک‌های بیرونی

را تغییر دهد.


چک‌های مورد نیاز (Functional Requirements – Checks)

HSC باید مجموعه‌ای از sanity checks زیر را فراهم کند:

  • چک ✔ Missing Images

آیا فایل تصویری که در img src آمده واقعاً وجود دارد؟

  • چک ✔ Broken Internal Links

آیا href="#XYZ" واقعاً به یک id تعریف‌شده اشاره می‌کند؟

  • چک ✔ Missing Local Resources

مانند css، js، pdf و سایر منابعی که لینک شده‌اند اما وجود ندارند.

  • چک ✔ Duplicate IDs

آیا یک id دوبار تعریف شده؟

  • چک ✔ Malformed Links

اشکالات syntax در href یا ساختار لینک‌ها.

  • چک ✔ Illegal Link Targets

اهداف لینک ناسازگار یا نادرست.

  • چک ✔ Broken External Links

بررسی status code لینک‌های HTTP.

  • چک ✔ Broken ImageMaps

بررسی ابتدایی صحت ImageMap.

این چک‌ها بخش عمده‌ی دامنه عملکردی سیستم را تشکیل می‌دهند و بعداً در Building Block View تبدیل به ماژول‌ها و CheckerClassهای جداگانه خواهند شد.

۱.۲ اهداف کیفی (Quality Goals)

برای اینکه معماری HSC بتواند نیازهای واقعی کاربران را پوشش دهد، باید بدانیم این سیستم در بلندمدت به چه کیفیت‌هایی متعهد است. این اهداف کیفی، تصمیمات معماری را شکل می‌دهند و مشخص می‌کنند سیستم چه چیزی را باید همیشه تضمین کند.

در HSC، کیفیت‌ها در سه محور اصلی خلاصه می‌شوند:

۱) صحت (Correctness)

مهم‌ترین هدف کیفیتی HSC، درست‌بودن نتایج است.
سیستم باید:

  • هر لینک داخلی شکسته را پیدا کند.

  • هرگونه خطای معنایی احتمالی را گزارش دهد حتی در موارد مشکوک یا مبهم.

به‌عبارتی، HSC باید «وسواسی» عمل کند؛ اگر در صحت لینک تردید دارد، باید گزارش دهد و تصمیم نهایی را به کاربر بسپارد.

۲) ایمنی (Safety)

یک اصل غیرقابل‌مذاکره:
HSC هرگز نباید محتوای فایل‌های HTML را تغییر دهد.
کارش فقط تحلیل است، نه بازنویسی، اصلاح یا اعمال تغییرات.

۳) انعطاف‌پذیری (Flexibility)

HSC باید بتواند:

  • چندین الگوریتم بررسی مختلف را پشتیبانی کند،

  • فرمت‌های متنوع گزارش تولید نماید،

  • و در کلاینت‌های مختلف اجرا شود: Gradle، CLI و غیره.

این انعطاف‌پذیری جزو اهداف کیفیتی سطح دوم است، اما برای معماری اهمیت عملی دارد.

۴) تست‌پذیری و صحت درونی سیستم

هر چکر (checker) باید هم برای موارد مثبت و هم موارد منفی تست شود.
این موضوع کیفیت «درونی» سیستم را تضمین می‌کند و اجرای خودکار تست‌ها بخشی از معماری سیستم است.

۵) کارایی (Performance)

چک کردن یک فایل HTML حدود ۱۰۰ کیلوبایت باید زیر ۱۰ ثانیه انجام شود—البته بدون احتساب زمان راه‌اندازی Gradle.
این هدف نشان می‌دهد کارایی مهم است، اما بعد از صحت و ایمنی قرار می‌گیرد.


۱.۳ ذینفعان (Stakeholders)

HSC یک سیستم کوچک است و ذینفعان محدودی دارد؛ اما همین تعداد کم نیز خواسته‌های متفاوتی دارند که در معماری اثر می‌گذارد.

نویسندگان مستندات

کسانی که محتوا را با ابزارهای تولید HTML (مثل Asciidoctor) ایجاد می‌کنند.
هدف‌شان این است که مطمئن شوند لینک‌ها، تصاویر و منابع HTML درست کار می‌کنند.

کاربران arc42

افرادی که می‌خواهند یک نمونهٔ ساده و واقعی از مستندسازی معماری مشاهده کنند.
HSC برای این گروه نقش یک مثال آموزشی را دارد.

توسعه‌دهندگان نرم‌افزار

کسانی که می‌خواهند:

  • کیفیت لینک‌ها و تصاویر داخل مستندات را بررسی کنند،

  • HSC را در خط build خود ادغام کنند،

  • و یک مثال عملی از معماری کوچک اما تمیز ببینند.

این سه گروه، خواسته‌های معماری سیستم را تعریف می‌کنند.


II.2 محدودیت‌ها (Constraints)

در طراحی HSC، مجموعه‌ای از محدودیت‌ها وجود دارد که آزادی عمل معماری را تعیین می‌کنند و تصمیم‌ها را شکل می‌دهند.

۱) باید روی پلتفرم‌های مختلف اجرا شود

HSC باید مستقل از پلتفرم باشد و روی Windows، Linux و MacOS قابل اجرا باشد.

۲) پیاده‌سازی مبتنی بر JVM

زبان پیاده‌سازی باید Java یا Groovy باشد.
این موضوع انتخاب runtime و سازگاری ابزار را مشخص می‌کند.

۳) ادغام با Gradle

سیستم باید به‌صورت پلاگین Gradle قابل استفاده باشد.
این محدودیت تأثیر مستقیم بر ساختار پروژه و نحوهٔ بسته‌بندی ماژول‌ها دارد.

۴) قابلیت اجرا از خط فرمان

CLI باید مستقل از ابزار ساخت باشد؛ یعنی کاربر بتواند تنها با نصب ابزار، آن را اجرا کند.

۵) حداقل وابستگی‌ها

HSC باید سبک باشد. فقط به یک Java Runtime نیاز دارد و نباید کتابخانه‌های سنگین یا پیچیده داشته باشد.

۶) لایسنس متن‌باز و سازگار

کد باید تحت Apache-2.0 منتشر شود و دیگر کتابخانه‌های استفاده‌شده باید با Creative Commons سازگار باشند.

این محدودیت‌ها مسیر طراحی را مشخص می‌کنند و در بخش‌های بعدی معماری منعکس خواهند شد.


II.3 محدوده و کانتکست سیستم (System Scope & Context)

۳.۱ کانتکست کسب‌وکاری (Business Context)

برای فهم محدوده سیستم، باید بدانیم HSC با چه موجودیت‌هایی در محیط خود تعامل دارد.

Business context
Business context

کاربر (User)

کسی که مستندات می‌نویسد یا خروجی HTML تولید می‌کند.
هدف او این است که مطمئن شود فایل HTML خروجی سالم، بدون لینک شکسته و بدون تصویر گم‌شده باشد.

سیستم Build (اغلب Gradle)

HSC معمولاً بخشی از pipeline تولید مستندات است.
در این نقش:

  • Gradle HSC را اجرا می‌کند،

  • HSC HTMLها را بررسی،

  • و گزارش تولید می‌کند.

فایل‌های HTML محلی

ورودی اصلی سیستم هستند.
HSC این فایل‌ها را parse و بررسی می‌کند.

تصاویر و فایل‌های محلی

سیستم باید بررسی کند که فایل‌هایی که HTML به آن‌ها لینک داده، واقعاً وجود داشته باشند.

منابع خارجی (external web resources)

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

  • کندتر است،

  • ممکن است به دلیل مشکلات شبکه نتایج نادرست بدهد.

بنابراین یک سناریوی اختیاری است که محدودیت‌های خاص خود را دارد.

II.4 استراتژی راه‌حل (Solution Strategy)

برای اینکه معماری HTML Sanity Check (HSC) بتواند اهداف کیفی تعریف‌شده—مثل صحت، ایمنی، انعطاف‌پذیری و کارایی—را پاسخ دهد، مجموعه‌ای از تصمیم‌ها و راهبردهای بنیادی در طراحی این سیستم اتخاذ شده است. این بخش خلاصه‌ای از ایده‌های کلیدی پشت معماری HSC را بیان می‌کند؛ ایده‌هایی که همهٔ افراد درگیر در توسعه، تست و نگهداری سیستم باید با آن‌ها آشنا باشند.

۱) انتخاب Groovy و Java با کمترین وابستگی خارجی

هستهٔ اصلی HSC عمدتاً با Groovy و بخشی از آن با Java پیاده‌سازی شده است.
این انتخاب چند دلیل معماری مهم دارد:

  • نیاز به حداقل وابستگی‌ها برای اجرای سریع و سبک

  • امکان سازگاری کامل با JVM و ابزارهای مرتبط

  • قابلیت نوشتن چکرها و منطق تحلیل HTML به‌صورت ساده، مختصر و خوانا

این تصمیم مستقیماً کیفیت‌های ایمنی، قابلیت نگهداری و کارایی را تقویت می‌کند.

۲) تبدیل سیستم به یک پلاگین Gradle برای اجرای خودکار

برای اینکه HSC بتواند بخشی طبیعی از فرآیند ساخت (build pipeline) باشد، پیاده‌سازی آن در قالب یک Gradle Plugin انجام شده است.

نتیجهٔ این تصمیم:

  • امکان استفادهٔ خودکار در CI/CD

  • سازگاری با تیم‌هایی که اسنادشان را با Asciidoctor و Gradle تولید می‌کنند

  • اجرای کاملاً بدون دخالت انسان

پلاگین Maven نیز در حال توسعه است تا این سناریو در محیط‌های گسترده‌تر هم برقرار شود.

این استراتژی پاسخ مستقیمی به نیاز انعطاف‌پذیری و سهولت ادغام است.

۳) استفاده از Template Method Pattern برای پشتیبانی از چندین الگوریتم بررسی

برای اینکه HSC بتواند:

  • چکرهای مختلف داشته باشد،

  • خروجی‌ها را در چند قالب تولید کند (مثل HTML و Console)،

  • و قابلیت گسترش‌پذیری داشته باشد،

در طراحی آن از الگوی Template Method استفاده شده است.

این الگو باعث می‌شود:

  • ساختار کلی الگوریتم ثابت بماند،

  • اما بخش‌های قابل تغییر (مثل نوع چک یا نوع گزارش) قابل جایگزینی باشند،

  • افزودن چکرهای جدید بدون دست‌زدن به ساختار کلی سیستم انجام شود.

این انتخاب معماری، کیفیت‌های درست‌کارکردن، انعطاف‌پذیری و قابلیت توسعه را تضمین می‌کند.

۴) اتکا به conventions استاندارد Gradle و Groovy برای تنظیمات

HSC یک فایل پیکربندی ساده دارد که مطابق conventions این اکوسیستم است.
این یعنی:

  • کاربر بدون نیاز به تنظیمات پیچیده می‌تواند ابزار را اجرا کند

  • رفتار سیستم به‌روشنی قابل انتظا‌رش است

  • خروجی‌ها، ورودی‌ها و مسیرها استاندارد و قابل پیش‌بینی‌اند

این تصمیم کیفیت استفاده‌پذیری و سادگی نگهداری را تقویت می‌کند.

البته، همین وابستگی به conventions ممکن است برای نسخهٔ Maven Plugin چالش‌هایی ایجاد کند، زیرا ساختار Maven با Gradle متفاوت است.

II.۵ نمای بلوک‌های سازنده یا Building Block View

در نمای سازه‌ای (Building Block View)، معماری سیستم از نگاه ایستا بررسی می‌شود:
سیستم از چه بخش‌هایی ساخته شده است؟ این بخش‌ها چگونه سازمان‌دهی شده‌اند؟ و هر بخش چه مسئولیتی دارد؟

در HSC، این ساختار به شکل عملکردهای تجزیه شده (Functional Decomposition) طراحی شده است: هستهٔ سیستم تمام منطق بررسی HTML را انجام می‌دهد، و بخش‌های دیگر فقط روش‌های مختلف استفاده از این هسته را فراهم می‌کنند.

این بخش در سه سطح توضیح داده می‌شود:

  • Level 1: ساختار کلی سیستم (Whitebox HtmlSC)

  • Level 2: اجزای داخلی هستهٔ سیستم (HSC Core)

  • Level 3: اجزای داخلی مدیریت نتایج (Results Collector)

بیایید قدم‌به‌قدم جلو برویم.

5.1 ساختار سطح ۱ – HtmlSanityChecker (Whitebox)

در بالاترین سطح، HSC از چند بلوک اصلی تشکیل شده است.
در این سطح هدف این است که «نقش‌های کلیدی سیستم» را مشخص کنیم، نه جزئیات پیاده‌سازی را.

چرا این ساختار؟

به‌جای اینکه همهٔ وظایف در یک پکیج یا کلاس قرار بگیرند، مسئولیت‌ها تفکیک شده‌اند:

  • هستهٔ HSC → مسئول تحلیل HTML و اجرای چک‌ها

  • پلاگین‌ها (مثل Gradle Plugin) → مسئول نحوه اجرا و ادغام HSC در ابزارهای خارجی

  • ابزارهای کمکی مثل NetUtil و FileUtil → برای بررسی شبکه و سیستم فایل

  • رابط کاربری گرافیکی (UI) → پیش‌بینی شده، ولی هنوز پیاده‌سازی نشده

مهم‌ترین بخش‌ها در سطح کلان:

۱) HSC Core

مرکز تمام منطق بررسی HTML؛ شامل پارس HTML، اجرای چک‌ها، تولید پیشنهاد و جمع‌آوری نتایج.

۲) Gradle Plugin

راهی برای استفاده از HSC در build pipeline پروژه‌ها.

۳) NetUtil

ابزار کمکی برای بررسی اتصال اینترنت و وضعیت لینک‌های HTTP.

۴) FileUtil

ابزار کمکی برای مدیریت فایل‌ها و مسیرها.

۵) Graphical UI (برنامه‌ریزی شده)

نسخهٔ گرافیکی احتمالی HSC برای کاربران غیرتکنیکال.


5.2 ساختار سطح ۲ – HSC Core (Whitebox)

در این سطح، وارد قلب سیستم می‌شویم؛ جایی که تمام منطق تحلیل HTML قرار دارد.

هستهٔ HSC بر اساس «تفکیک وظیفه‌ای» ساخته شده است. یعنی بخش‌های مختلف هر کدام یک وظیفهٔ روشن دارند و باهم برای رسیدن به هدف کنار می‌آیند.

الگوهای اصلی ساختار Core:

  • مدیریت پیکربندی

  • خواندن و پارس فایل‌های HTML

  • اجرای چک‌های مختلف

  • تولید پیشنهاد (Suggestions)

  • جمع‌آوری نتایج برای تولید گزارش

بلوک‌های اصلی Level 2:

۱) Checker (Blackbox)

مهم‌ترین بخش سیستم.

اینجا یک کلاس انتزاعی (abstract) وجود دارد به نام Checker.
تمام چکرها از آن ارث‌بری می‌کنند.

وظیفه آن:

  • تعریف یک رابط یکسان (check())

  • پیاده‌سازی الگوریتم چک با Template Method Pattern

این ساختار اجازه می‌دهد:

  • انواع چک‌ها (لینک شکسته، تصویر گم‌شده، ID تکراری و…) به‌سادگی افزوده شوند

  • رفتار مشترک در superclass تعریف شود

  • فقط بخش‌های متفاوت override شوند

این بخش دقیقاً پاسخ‌دهندهٔ کیفیت انعطاف‌پذیری و قابلیت توسعه است.

۲) AllChecksRunner

پردهٔ نمایشی (Facade) بین Core و دنیای بیرونی.

این بخش:

  • تمام چکرها را مدیریت می‌کند

  • براساس پیکربندی تعیین می‌کند چه چک‌هایی اجرا شوند

  • خروجی همهٔ چک‌ها را جمع‌آوری می‌کند

پلاگین Gradle مستقیماً این بخش را فراخوانی می‌کند.

۳) Configuration

همه‌چیز در HSC قابل پیکربندی است:

  • مسیر فایل‌ها

  • مسیر گزارش خروجی

  • timeout بررسی لینک‌ها

  • وضعیت‌هایی که باید خطا یا هشدار محسوب شوند

  • انواع چک‌هایی که باید فعال باشند

این بخش یکی از پایه‌های کیفیت انعطاف‌پذیری (Flexibility) است.

۴) Reporter

نتایج چک‌ها باید:

  • یا در کنسول چاپ شوند

  • یا به صورت فایل HTML یا متن ذخیره شوند

Reporter این مسئولیت را بر عهده دارد.
این طراحی اجازه می‌دهد در آینده Report Formatهای جدید هم اضافه شوند.

۵) Suggester (Blackbox)

بخش جذاب سیستم!

وقتی یک خطا پیدا می‌شود، HSC سعی می‌کند نزدیک‌ترین گزینهٔ صحیح را پیشنهاد دهد.

مثلاً اگر نویسنده نوشته باشد:

<img src="logo.pgn">

و تصویر واقعی logo.png باشد، Suggester باید بتواند این پیشنهاد را ارائه دهد.

این بخش با الگوریتم Jaro-Winkler Distance کار می‌کند تا شباهت رشته‌ها را پیدا کند.

کاربردهایش:

  • تصویر گم‌شده → پیشنهاد تصویر مشابه

  • لینک داخلی خراب → پیشنهاد id نزدیک

5.3 ساختار سطح ۳ – Results Collector (Whitebox)

این بخش مسئول سازمان‌دهی نتایج چک‌هاست و ساختاری کاملاً سلسله‌مراتبی دارد.

سه سطح نتیجه وجود دارد:

۱) PerRunResults

نتیجهٔ کلی برای یک اجرای کامل HSC
(ممکن است شامل چندین فایل HTML باشد)

۲) SinglePageResults

نتایج چک‌های یک فایل HTML مشخص

۳) SingleCheckResults

خروجی یک چکر خاص؛ مانند:

  • چک MissingImages

  • چک BrokenLinks

  • چک DuplicateIDs

۴) Finding

هر خطا یا هشدار یک Finding است.
می‌تواند شامل توضیح و حتی پیشنهاد از Suggester باشد.

این ساختار چند مزیت دارد:

  • گزارش‌ها تمیز و قابل فهم می‌شوند

  • افزودن چک‌های جدید ساده است

  • ساختار گزارش‌دهی با نیازهای مختلف (CLI، HTML، IDE) هماهنگ می‌ماند

II.۶ رفتار سیستم در زمان اجرا یا Runtime View

معماری ایستا به ما می‌گوید سیستم از چه بخش‌هایی تشکیل شده است؛
اما Runtime View توضیح می‌دهد که این بخش‌ها هنگام اجرا چگونه با یکدیگر تعامل می‌کنند.

در HSC دو سناریوی اصلی وجود دارد:

II.۶.۱ سناریو اول: اجرای همهٔ چک‌ها

این سناریو رایج‌ترین حالت استفاده از HSC است—زمانی که کاربر یا سیستم Build می‌خواهد مجموعه‌ای از فایل‌های HTML را بررسی کند.

فرایند اجرای چک‌ها به صورت زیر پیش می‌رود:

۱) اجرای هدف (Task) توسط کاربر یا سیستم Build

کاربر معمولاً دستور htmlSanityCheck را اجرا می‌کند
یا Gradle در طی یک Build آن را فراخوانی می‌کند.

۲) Gradle کنترل را به HSC منتقل می‌کند

Gradle تسک sanityCheckHtml را اجرا می‌کند که مستقیماً به HSC متصل است.

۳) HSC پیکربندی را بارگذاری می‌کند

این شامل موارد زیر است:

  • مسیر HTMLهای ورودی

  • مسیر خروجی گزارش

  • timeout لینک‌ها

  • فعال یا غیرفعال بودن چک‌های مختلف

۴) ایجاد AllChecksRunner

این بخش «موتور اجرای چک‌ها»ست.
AllChecksRunner مسئول است:

  • چکرها را آماده کند

  • فایل‌های ورودی را جمع کند

  • و اجرای چک‌ها را مدیریت کند

۵) جمع‌آوری فایل‌ها

HSC تمام فایل‌هایی را که باید بررسی شوند در یک مجموعه (allFiles) جمع می‌کند.

۶) (برنامه‌ریزی‌شده) کشف خودکار Checkerها

در نسخهٔ آینده، HSC قرار است به‌وسیلهٔ Annotationها چکرهای موجود را کشف کند تا توسعهٔ آن آسان‌تر شود.

۷) اجرای چک‌ها و جمع‌کردن نتایج

هر Checker روی HTML اجرا می‌شود و یافته‌ها (Findings) در ساختار سلسله‌مراتبی نتایج ذخیره می‌شود.

II.6.2 سناریو دوم: تولید گزارش چک‌ها

بعد از اجرا، HSC باید نتایج را با ساختاری قابل درک و هماهنگ ارائه دهد.
این ساختار مطابق با سلسله‌مراتب ResultsCollector است:

۱) نتایج سطح اجرا (PerRunResults)

شامل:

  • تاریخ و زمان اجرا

  • تعداد فایل‌های بررسی‌شده

  • پیکربندی اعمال‌شده

  • خلاصهٔ کلی نتایج

۲) نتایج سطح صفحه (SinglePageResults)

برای هر فایل HTML یک بخش جداگانه ایجاد می‌شود.

در این مرحله:

  • عنوان صفحه

  • تعداد خطاها

  • نوع خطاها

نمایش داده می‌شود.

۳) نتایج سطح چک (SingleCheckResults)

برای هر چک—مثل بررسی لینک‌های داخلی یا تصاویر—یک بخش مستقل ایجاد می‌شود که شامل:

  • فهرست یافته‌ها

  • پیشنهادهای احتمالی برای اصلاح خطا

این روش گزارش‌دهی باعث می‌شود خروجی HSC بسیار تمیز، قابل جستجو و قابل تحلیل باشد—درست مانند گزارش تست‌های واحد.

II.۷ معماری استقرار یا HSC Deployment View

در Deployment View، معماری سیستم از نگاه محیط اجرا و نحوه استقرار آن بررسی می‌شود.
با اینکه HSC ابزاری کوچک است، اما در معماری استقرار آن سه بازیگر اصلی نقش دارند:

۱) سیستم توسعهٔ HSC (Development Environment)

اینجا جایی است که خود HSC توسعه و کامپایل می‌شود.
پیش‌نیازهای محیط توسعه:

  • JDK

  • Groovy

  • Gradle

  • کتابخانهٔ Jsoup برای تحلیل HTML

در این محیط خروجی باینری نهایی تولید و برای انتشار آماده می‌شود.

۲) مخزن عمومی (Artifact Repository)

بعد از Build، نسخهٔ کامپایل‌شده HSC (به‌صورت Plugin) در یک مخزن عمومی نظیر:

  • Maven Central

  • Gradle Plugin Portal

منتشر می‌شود.

کاربران HSC باینری‌ها را مستقیماً از این مخازن دریافت می‌کنند.

۳) سیستم کاربر (User Machine)

کاربر نهایی HSC را روی سیستم خودش اجرا می‌کند؛ معمولاً در یکی از این سناریوها:

  • در خط فرمان (CLI)

  • به‌عنوان پلاگین Gradle داخل build.gradle

  • همراه با تولید مستندات AsciiDoc

پیش‌نیازهای کاربر:

  • Java Runtime (نسخه ۱.۶ یا بالاتر)

  • فایل build.gradle که پلاگین HSC در آن پیکربندی شده باشد

در این سیستم است که:

  • فایل‌های HTML ساخته می‌شوند

  • HTML Sanity Check اجرا می‌شود

  • و گزارش نهایی تولید می‌شود

II.8 مفاهیم فراگیر (Cross-cutting Concepts)

در هر سیستم نرم‌افزاری مجموعه‌ای از قواعد، الگوها و مفاهیم وجود دارد که فقط مربوط به یک بخش خاص نیستند؛ بلکه در سراسر معماری دیده می‌شوند. در HSC این مفاهیم شامل الگوهای طراحی، مدل دامنه، ساختار لینک‌های HTML، الگوریتم‌های بررسی، و نحوهٔ گزارش‌دهی است.

در ادامه، چهار مفهوم مهم HSC را به زبان ساده و معمارانه بررسی می‌کنیم.

8.1 مدل دامنه (Domain Model)

برای اینکه HSC بتواند HTML را تحلیل کند، ابتدا باید مفاهیم اصلی مرتبط با ساختار HTML را در قالب یک «مدل دامنه» تعریف کند. این مدل تعیین می‌کند که سیستم چه چیزهایی را می‌شناسد و با چه مفاهیمی کار می‌کند.

در ادامه مهم‌ترین مفاهیم دامنه را توضیح می‌دهیم:

مفهوم Anchor

همان تگ <a href="..."> که لینک ایجاد می‌کند.
Anchor همیشه شامل یک link target است.

Cross Reference (لینک داخلی)

لینکی که به بخشی دیگر از همان صفحه یا همان سند اشاره می‌کند.
این همان چیزی است که HSC باید بررسی کند تا ببیند آیا id مقصد واقعاً وجود دارد یا نه.

External Link (لینک بیرونی)

لینکی که به یک صفحهٔ وب یا دامنهٔ دیگر اشاره می‌کند.
بررسی این لینک‌ها حساس است، چون ممکن است مشکلات شبکه باعث خطاهای ظاهری شود.

Finding در HSC

هر مشکلی که یکی از Checkerها پیدا می‌کند—مثلاً «تصویر logo.png پیدا نشد».
گاهی همراه با پیشنهاد برای رفع خطا است.

HTML Element در HSC

واحدهای سازندهٔ صفحه، مثل <a>, <img>, <h2>.
برای تحلیل ساختاری HTML، HSC باید این عناصر را به‌درستی استخراج کند.

HTML Page / Document در HSC

یک فایل HTML کامل که شامل مجموعه‌ای از HTML elements است.
حداقل شرط آن این است که parser بتواند آن را به‌درستی پردازش کند.

id در HSC

شناسهٔ یک عنصر در HTML، معمولاً هدف لینک‌های داخلی (href="#id").

Internal Link / Local Link در HSC

لینکی که به بخش دیگری از همین صفحه یا همین پروژه اشاره می‌کند.

Link و Link Target

هر چیزی که از یک نقطه به نقطهٔ دیگر ارجاع می‌دهد.
Link Target می‌تواند:

  • یک id داخل همان صفحه

  • یک فایل HTML دیگر

  • یا یک منبع خارجی باشد

Local Resource در HSC

فایل‌هایی مثل PDF، CSS یا JS که صفحهٔ HTML به آن‌ها ارجاع می‌دهد.

8.2 ساختار لینک‌های HTML

HSC بخش زیادی از کار خود را روی لینک‌ها انجام می‌دهد، بنابراین باید ساختار URI را عمیقاً بشناسد.

یک URI معمولاً شامل این بخش‌هاست:

  • پروتکل (http/https)

  • آدرس میزبان (Host)

  • شماره پورت

  • مسیر فایل

  • Query string

  • Fragment یا همان anchor (#someLabel)

HSC با بررسی این ساختار می‌تواند تشخیص دهد:

  • آیا لینک معتبر است؟

  • آیا ساختار لینک درست نوشته شده؟

  • آیا مقصد لینک وجود دارد؟

این دانش در تمام Checkerها استفاده می‌شود.

8.3 الگوریتم‌های بررسی (Checking Algorithms)

یکی از تصمیم‌های طراحی مهم در HSC استفاده از Template Method Pattern برای تعریف الگوریتم‌های چک است.

چرا این الگو انتخاب شد؟

چون HSC چندین نوع چک مختلف دارد:

  • چک لینک‌های داخلی

  • چک فایل‌های تصویری

  • چک تکراری بودن idها

  • چک لینک‌های بیرونی

  • چک منابع محلی

همهٔ این چک‌ها ساختار کلی مشابهی دارند اما در جزئیات متفاوت هستند.
Template Method این امکان را می‌دهد:

  • اسکلت الگوریتم در یک کلاس پایه نوشته شود

  • فقط بخش‌های متغیر در subclassها override شوند

  • افزودن چک‌های جدید بسیار ساده باشد

ساختار کار این الگو در HSC:

۱) چکر ساخته می‌شود
۲) مقدمات اجرا (initResults) انجام می‌شود
۳) متد performCheck() فراخوانی می‌شود
۴) الگوریتم خاص چکر در متد check() اجرا می‌شود
۵) نتایج جمع‌آوری و بازگردانده می‌شود

با این ساختار، توسعه‌دهندگان می‌توانند هر نوع چک جدیدی را بدون تغییر در هستهٔ سیستم اضافه کنند—این موضوع کیفیت انعطاف‌پذیری را تضمین می‌کند.

8.4 سیستم گزارش‌دهی (Reporting)

گزارش‌دهی نیز مانند چکرها از Template Method Pattern استفاده می‌کند.
در HSC دو نوع خروجی گزارش وجود دارد:

  • گزارش HTML

  • گزارش متنی (Console)

اما در هر دو حالت، ساختار گزارش یکسان است:

  1. ایجاد بخش ابتدایی گزارش (initReport)

  2. نمایش خلاصهٔ کلی (صفحات بررسی‌شده، میزان موفقیت، تعداد خطاها)

  3. گزارش نتایج هر صفحه

  4. گزارش نتایج هر چک برای آن صفحه

  5. ایجاد بخش انتهایی گزارش (footer)

این ساختار یکپارچه باعث می‌شود:

  • اضافه کردن فرمت‌های جدید گزارش بسیار ساده باشد

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

  • برنامه‌های دیگر بتوانند گزارش را به‌راحتی پردازش کنند

این سیستم گزارش‌دهی، کیفیت قابلیت استفاده و قابلیت گسترش را افزایش می‌دهد.

II.۹ تصمیمات معماری (Architecture Decisions)

در این بخش، مهم‌ترین تصمیمات معماری که مسیر طراحی HSC را مشخص کردند توضیح داده می‌شود. این تصمیم‌ها معمولاً مواردی هستند که یا پرهزینه‌اند، یا ریسک دارند، یا نقش مهمی در کیفیت نهایی سیستم بازی می‌کنند. ثبت این تصمیمات به تیم توسعه کمک می‌کند منطق پشت انتخاب‌ها را درک کند.

۹.۱ تعویق بررسی لینک‌های خارجی

در نسخه فعلی HSC، بررسی لینک‌های خارجی انجام نمی‌شود. این قابلیت عمداً به نسخه‌های آینده موکول شده است.
چرا؟

  • بررسی منابع بیرونی به شبکه وابسته است

  • سرعت و پایداری آن قابل تضمین نیست

  • ممکن است نتایج نادرست بدهد (به‌دلیل timeout، مشکلات DNS، محدودیت سرور مقصد)

بنابراین تیم توسعه تصمیم گرفته ابتدا روی قابلیت‌های داخلی و مطمئن تمرکز کند و سپس در نسخه‌های آینده سراغ لینک‌های خارجی برود.

۹.۲ انتخاب Jsoup برای پارس HTML

HSC برای تحلیل ساختار HTML و استخراج لینک‌ها و تصاویر، نیاز به یک parser داشت. از میان گزینه‌های موجود، Jsoup انتخاب شد.

دلایل این انتخاب:

۱) بدون وابستگی خارجی

Jsoup یک کتابخانه سبک است و خودش به چیز دیگری وابسته نیست.
این موضوع باعث می‌شود اندازه نهایی ابزار کوچک بماند و نصب آن آسان باشد.

۲) API ساده و قدرتمند

Jsoup ترکیبی از:

  • DOM

  • CSS selectors

  • و سبک jQuery

را ارائه می‌دهد؛ یعنی با چند خط کد می‌توان:

  • همهٔ لینک‌ها را پیدا کرد

  • همهٔ تصاویر را استخراج کرد

  • همهٔ idها را جمع کرد

۳) انعطاف‌پذیری بالا

Jsoup می‌تواند ورودی را از فایل، رشته، stream یا منابع دیگر دریافت کند.

جایگزین‌ها و دلیل رد شدنشان

  • HTTPUnit → جهت تست وب‌سایت‌ها ساخته شده، وابستگی‌های زیاد دارد

  • HtmlCleaner → گزینه‌ای مناسب اما API محدودتر

  • Jsoup در نهایت بهترین توازن را داشت: سبک، پرقدرت، ساده

این تصمیم قلب معماری سیستم را شکل می‌دهد، چون تمام چکرها به این ساختار DOM متکی هستند.


II.10 نیازمندی‌های کیفی (Quality Requirements)

کیفیت در HSC فقط یک مبحث تئوریک نیست؛ نیازمندی‌های کیفی این سیستم کاملاً قابل اندازه‌گیری و عملیاتی هستند. بخشی از این نیازها در ابتدای سند معرفی شدند و در این قسمت همان اهداف را به‌صورت دقیق‌تر و سناریومحور می‌بینیم.

صحت (Correctness)

HSC باید تضمین کند که:

  • هر لینک داخلی شکسته شناسایی شود

  • هر تصویر گم‌شده تشخیص داده شود

  • تمام چکرها با تست مثبت و منفی اعتبارسنجی شوند

این یعنی هیچ خطا یا هشدار نباید از چشم سیستم پنهان بماند.

کامل بودن گزارش (Completeness)

گزارش خروجی باید شامل تمام یافته‌ها باشد—حتی موارد جزئی.

انعطاف‌پذیری (Flexibility)

سیستم باید به‌گونه‌ای طراحی شود که:

  • چکر جدید به آن اضافه شود

  • گزارش‌دهی در قالب‌های جدید توسعه یابد

  • از سیستم‌های build دیگر (غیر از Gradle) هم قابل استفاده باشد

ایمنی (Safety)

HSC باید همیشه تمام فایل‌ها را بدون تغییر باقی بگذارد.
این یک اصل غیرقابل‌مذاکره است:
هیچ تغییری در HTML ورودی نباید ایجاد شود.

کارایی (Performance)

برای یک فایل HTML به اندازه ۱۰۰ کیلوبایت، تمام چک‌ها باید در کمتر از ۱۰ ثانیه انجام شوند.
(بدون احتساب زمان startup Gradle)


II.11 ریسک‌ها و بدهی فنی (Risks & Technical Debt)

HSC پروژه کوچکی است، اما همچنان شامل چند ریسک فنی و تجاری است که باید به آن‌ها توجه شود.

۱۱.۱ ریسک‌های فنی

۱) وابستگی به یک توسعه‌دهنده

در حال حاضر فقط یک نفر دسترسی انتشار نسخه‌های جدید پلاگین را دارد.
در صورت غیبت او، انتشار نسخه‌های جدید یا رفع اشکال ممکن است متوقف شود.

۲) حساسیت نسبت به تغییرات Gradle

به‌روزرسانی Gradle در گذشته نیازمند تغییرات دستی در HSC بوده.
هر ارتقای API ممکن است دوباره وقت‌گیر شود.

این دو ریسک ممکن است در آینده هزینه‌زا باشند.

۱۱.۲ ریسک‌های تجاری / دامنه‌ای

احتمال از رده خارج شدن سیستم

اگر AsciiDoc یا Markdown در آینده قابلیت بررسی لینک و تصویر را به‌صورت داخلی اضافه کنند:

  • HSC ممکن است کارکرد اصلی خود را از دست بدهد

  • نیاز به مدل کسب‌وکار جدید یا ارزش افزوده جدید خواهد بود

این ریسک استراتژیک است و به روند توسعه ابزارهای تولید مستندات بستگی دارد.

II.12 واژه‌نامه (Glossary)

برای اینکه ارتباط بین کاربران و توسعه‌دهندگان شفاف باشد، لازم است مفاهیم کلیدی دامنهٔ HSC معنی مشخصی داشته باشند.

Link

هر ارجاعی در فایل HTML که کاربر را به بخشی دیگر یا منبع دیگری هدایت می‌کند.

Cross Reference

نوعی لینک داخلی که به یک id داخل همان صفحه اشاره می‌کند.

External Hyperlink

لینکی که خارج از دامنهٔ فعلی (مثلاً به یک وب‌سایت دیگر) اشاره می‌کند.

Run Result

نتیجهٔ کامل یک اجرای HSC روی چندین فایل.

SinglePageResults

خروجی تمام چکرها برای یک فایل HTML مشخص.

بخش پایانی

در نهایت، مثال HTML Sanity Check نشان می‌دهد که حتی یک ابزار کوچک و مینیمال هم می‌تواند معماری شفاف، قابل‌توسعه و حرفه‌ای داشته باشد—به‌شرط آنکه از یک الگوی مستند‌سازی استاندارد مانند arc42 استفاده شود. این مثال ثابت می‌کند که معماری فقط مخصوص سیستم‌های عظیم و سازمانی نیست؛ حتی پروژه‌های کوچک نیز با داشتن یک ساختار معماری اصولی، درک‌پذیرتر، پایدارتر و قابل نگه‌داری‌تر می‌شوند.

مستندسازی HSC نشان داد چگونه:

  • تصمیمات کوچک مثل انتخاب Jsoup

  • الگوهای طراحی مانند Template Method

  • و مفاهیم دامنه‌ای واضح مانند Link، Finding و HTML Element

می‌توانند در کنار هم یک سیستم ساده را به یک نمونهٔ عالی از معماری تمیز و قابل توسعه تبدیل کنند.

این مقاله همچنین گام‌به‌گام نشان داد که arc42 چگونه کمک می‌کند:

  • بخش‌های کلیدی یک سیستم را شناسایی کنیم

  • تعامل اجزا را درک کنیم

  • کیفیت‌ها را قابل اندازه‌گیری کنیم

  • و ریسک‌های احتمالی را از ابتدا شفاف کنیم

بدون داشتن چنین چارچوبی، تحلیل و توسعهٔ سیستم—even اگر کوچک باشد—در بلندمدت هزینه‌بر و گیج‌کننده خواهد شد.

با رشد ابزارهای خودکار، سیستم‌های توزیع‌شده، و توسعهٔ محصول مبتنی بر هوش مصنوعی، اهمیت داشتن مستند معماری استاندارد روزبه‌روز بیشتر می‌شود. arc42 یکی از روش‌هایی است که هم برای سیستم‌های بزرگ کاربردی است، هم برای ابزارهای کوچک مثل HSC؛ و همین موضوع، ارزش آن را در چرخهٔ عمر محصول دوچندان می‌کند.

اگر نیاز دارید معماری پروژه‌های خود را استاندارد کنید، مستند arc42 بسازید، یا معماری فعلی‌تان را بازطراحی و عملیاتی کنید، تیم معماری و توسعه‌ی نرم‌افزار شرکت راهکار نگار هوشمند (آرکان) همراه شماست—از تحلیل اولیه تا مستندسازی و پیاده‌سازی کامل.

این مقاله با هدف آگاهی‌بخشی توسط تیم توسعه‌ی نرم‌افزار شرکت راهکار نگار هوشمند (آرکان) تهیه شده است.


#معماری_نرم‌افزار
#arc42
#مستندسازی_معماری
#تحلیل_سامانه
#طراحی_سیستم
#معماری_فنی
#HTMLSanityCheck
#Software_Architecture
#architecture_documentation
#design_patterns
#clean_architecture
#devtools
#quality_engineering
#technical_writing
#شرکت_راهکار_نگار_هوشمند
#arcanco