حتما خودتان بهتر می‌دانید که ما برنامه‌نویسان فراموشکار، جزئیات و آرگومان‌های دستورات را به راحتی یادمان می‌رود. برای این منظور خیلی اوقات صفحات manual دستورها یا همان man page ها را چک می‌کنیم. برای مثال با وارد کردن دستور man ls می‌توانیم مستندات رسمی ابزار ls را در صفحه‌ی دوست داشتنی ترمینالمان بخوانیم.

متاسفانه به جز فراموشکار، گاهی کم‌حوصله هم هستیم و دنبال کردن یک مستند رسمی طولانی می‌تواند جانفرسا باشد. مثلا man bash که توضیحات پوسته‌ی bash را به ما نشان می‌دهد بسیار طولانی است و حدود پنج هزار خط است! برای حل این مشکل، مستندات غیر رسمی‌ای تحت نام «طولانی بود نخوندم» یا "too long didn't read» یا به طور مخفف TLDR توسط کاربران ایجاد شد که نسخه‌ی خلاصه‌ شده و کاربردی از مستندات است و با مثال‌ها و توضیحات و ... می‌تواند بسیار در زمان صرفه‌جویی کند. برای آشنایی اولیه با این مستندات می‌توانید از این لینک استفاده کنید.

اما استفاده از سایت شاید برای همه‌ی کاربران گزینه‌ی اول نباشد و بسیاری از ما دوست داریم یک برنامه‌ی سمت کاربر داشته باشیم که به این شکل از آن استفاده کنیم:‌ tldr bash و خودش از صفحات آنلاین خوانده و اطلاعات را در اختیار ما بگذارد. البته تنها مشکل ما این نیست. به جز این مورد، با توجه به سرعت محدود اینترنت، ما دوست داریم با استفاده از حافظه‌ی نهان (کش) در زمان و مصرف اینترنت نیز صرفه‌جویی کند، به این ترتیب صفحاتی که تا کنون بازدید شده‌اند را در خود ذخیره کند و در زمان استفاده، صفحه‌ی ذخیره شده را بازگرداند.

کلاینت اصلی این نرم‌افزار با زبان Javascript و در محیط Node.js توسعه داده شده اما کلاینت‌های دیگری نیز برای آن وجود دارد که می‌توانید لیستی از آن‌ها را اینجا ملاحظه کنید. توصیه می‌شود یکی از آن‌ها را نصب کنید و با آن کار کنید.

جزئیات پروژه

پروژه‌ی اولیه را از این لینک دانلود کنید. ساختار فایل‌های پروژه به صورت زیر است:

.
├── go.mod
├── go.sum
├── tldr.go
├── db.go
├── main.go
└── main_sample_test.go
Plain text

در فایل main.go چند تابع و متد وجود دارد که شما باید آن‌ها را کامل کنید.

آن‌چه باید پیاده‌سازی کنید

در فایل tldr.go‍ یک اینترفیس وجود دارد که باید آن را پیاده‌سازی کنید. این اینترفیس دو متد دارد که در ادامه توضیح داده می‌شود.

type TLDRProvider interface {
	Retrieve(string) string
	List() []string
}
Go
tldr.go

در فایل main.go، یک استراکت وجود دارد که قرار است اینترفیس گفته شده را پیاده‌سازی کند. همچنین یک تابع سازنده داریم

type TLDRDBCached struct {
}

func (t *TLDRDBCached) Retrieve(key string) string {
}

func (t *TLDRDBCached) List() []string {
}

func NewTLDRDBCached(nonCachedProvider TLDRProvider) TLDRProvider {
	return nil
}

Go
main.go

متد Retrieve

در متد Retrieve، یک کلید که اسم همان ابزاری است که توضیحات بیشترش را می‌خواهیم به ما داده می‌شود و انتظار می‌رود توضیح و راهنمای کار با آن را به شکل یک رشته برگردانیم.

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

متد List

این متد باید لیست تمام مطالبی که در provider وجود دارند را برگرداند. به بیان دیگر این لیست یک رشته برمی‌گرداند شامل اسم تمام ابزارهایی که در tldr داکیومنت مربوط به آن وجود دارد. برای دسترسی به این لیست به سادگی می‌توانید متد List را در تامین‌‌کننده فراخوانی کنید.

تنها نکته‌ای که وجود دارد این است که ترتیب این لیست باید تا حدی عوض شود. تفاوت به این صورت است که بین تمام مواردی که در لیست قرار می‌گیرند، در لیست خروجی شما باید اول اسم ابزارهایی که صفحه‌ی آن‌ها در کش موجود است آورده شود و در ادامه باقی ابزارها بیایند. مثلا اگر ابزار zsh تا کنون فراخوانی شده و در کش موجود است، اول این لیست zsh وجود داشته باشد و باقی ابزارها مثل bash قرار گیرند. ترتیب اعضایی که در کش هستند اهمیتی ندارد و ترتیب اعضایی که در کش نیستند نیز اهمیتی ندارد.

سازنده‌ی NewTLDRDBCached

این سازنده یک شی تامین کننده از جنس همین اینترفیس می‌گیرد و یک شی از نوع TLDRDBCached که به درستی مقداردهی کرده است برمیگرداند.

روش ذخیره‌سازی در حافظه‌ی نهان

از آنجا که به فصل گرم سال نزدیک می‌شویم و ممکن است برق سیستم برود، نیاز داریم که این اطلاعات در یک پایگاه‌داده ذخیره شوند تا با خاموش و روشن شدن سیستم، همچنان دسترسی به اطلاعات از طریق دیتابیس موجود باشد. برای این منظور یک DBMS از نوع postgres تدارک دیده‌ایم که می‌توانید از آن استفاده کنید. همچنین یک رابطه شی-ارتباط به نام Gorm هم برای شما تدارک دیده شده که می توانید برای سهولت بیشتر از آن استفاده کنید.

در فایل db.go یک تابع به نام GetConnection وجود دارد که یک شی از نوع *gorm.DB می‌دهد و می‌توانید با آن به دیتابیس و امکانات Gorm دسترسی داشته باشید. در سیستم خودتان می‌توانید اطلاعات اتصال به دیتابیس را مطابق سیستم خودتان بروز کنید ولی آن فایل را آپلود نخواهید کرد و سمت سرور فایل db.go‍ مطابق کانفیگ سمت سرور موجود است.

در فایل tldr.go‍ که قبلا بخشی از آن را دیده‌ایم، یک موجودیت نیز برای شما آورده شده است به نام TLDREntity:

type TLDREntity struct {
	gorm.Model
	Key string `gorm:"primaryKey;size:100"`
	Val string `gorm:"size:1000"`
}
Go
tldr.go

شما برای حل این سوال باید اطلاعات خود را در قالب شی‌ای از این نوع در دیتابیس ذخیره کنید و حق تغییر در این شی را نیز ندارید.

پس دقت کنید که فقط اجازه دارید کش کردن داده را با استفاده از Gorm انجام دهید.

توجه کنید که در تست‌ها بررسی می‌شود که جدول متناظر با این شی به طور مناسب پر شده باشد.

تضمین‌ها

  • تضمین می‌شود به متد Retrieve هیچگاه کلیدی که سمت سرور وجود ندارد پاس داده نمی‌شود.
  • تضمین می‌شود که اسم ابزار همواره زیر ۱۰۰ کارکتر طول دارد و تماما از کارکترهای انگلیسی تشکیل شده است.
  • تضمین می‌شود که متن توضیح ابزار همواره زیر ۱۰۰۰ کارکتر طول دارد و تماما از کارکترهای انگلیسی تشکیل شده است.
  • تضمین می‌شود که قبل از اجرای هر تست دیتابیس خالی است و فقط یک جدول خالی متناظر با TLDREntity وجود دارد.
  • تضمین می‌شود زمان اجرای تست‌ها، فراخوانی GetConnection یک پوینتر به یک شی معتبر از نوع gorm.DBخواهد بود و با آن به شکل مناسب به دیتابیس دسترسی خواهید داشت.
  • تضمین می‌شود در provider حداقل داکیومنت مربوط به یک ابزار وجود دارد.

آن‌چه باید آپلود کنید

پس از پیاده‌سازی توابع خواسته شده، فایل main.go را آپلود کنید.


ارسال پاسخ برای این سؤال
فایلی انتخاب نشده است.