واجهة CLI للمسؤول
جزء من قسم Object Oriented Programming في رحلة GO على Coddy — الدرس 103 من 107.
التحدي
سهللنقم ببناء واجهة سطر أوامر (CLI) لنظام إدارة المكتبة الخاص بنا باستخدام نمط الأمر (Command Pattern)! ستقوم بإنشاء CLI يعالج أوامر المسؤول مثل إضافة الكتب، وتسجيل المستخدمين، وإدارة عمليات الاستعارة — كل ذلك من خلال بنية نظيفة وقابلة للتوسع.
ستقوم بتنظيم الكود الخاص بك عبر ستة ملفات:
book.go: هيكلBookالخاص بك مع وسوم JSON لكل منID، وTitle، وAuthor، وISBN، وAvailable. قم بتضمين منشئNewBook.user.go: هيكلUserالخاص بك مع وسوم JSON لكل منID، وName، وEmail، وBorrowedBooks. قم بتضمين منشئNewUser.library.go: هيكلLibraryالخاص بك مع خرائط (maps) للكتب والمستخدمين، بالإضافة إلى دوالAddBook، وAddUser، وBorrow، وReturnمن الدروس السابقة.commands.go: هنا ينبض نمط الأمر بالحياة! قم بتعريف واجهةCommandمع دالةExecuteتأخذ*Libraryووسائط[]string، وتعيد نتيجة نصية (string). ثم قم بتنفيذ هياكل الأوامر التالية:AddBookCommand— يتوقع 4 وسائط: id، title، author، isbn. يضيف الكتاب ويعيدBook added: [title]AddUserCommand— يتوقع 3 وسائط: id، name، email. يضيف المستخدم ويعيدUser added: [name]BorrowCommand— يتوقع وسيطين: userID، bookID. يعيدBorrowed: [bookID]عند النجاح، أوError: [message]عند الفشلReturnCommand— يتوقع وسيطين: userID، bookID. يعيدReturned: [bookID]عند النجاح، أوError: [message]عند الفشلListBooksCommand— لا يأخذ وسائط. يعيد معرف (ID) وعنوان كل كتاب في أسطر منفصلة بتنسيق[id]: [title]، أوNo booksإذا كانت القائمة فارغة (يجب عرض الكتب مرتبة حسب ID)
إذا تلقى الأمر وسائط غير كافية، فقم بإرجاع
Error: insufficient argumentscli.go: أنشئ هيكلCLIيحتوي على مؤشر إلىLibraryوخريطة (map) لأسماء الأوامر مع تنفيذاتCommandالخاصة بها. قم ببناء:- منشئ
NewCLIيقوم بتهيئة CLI مع مكتبة وتسجيل جميع الأوامر:addbook، وadduser، وborrow، وreturn، وlistbooks - دالة
Runتأخذ سلسلة نصية كمدخل، وتقوم بتحليلها باستخدامstrings.Fields، وتبحث عن الأمر، وتنفذه. أعدNo command providedللمدخلات الفارغة، أوUnknown command: [name]للأوامر غير المعروفة
- منشئ
main.go: أنشئ مكتبة و CLI، ثم قم بمعالجة الأوامر من المدخلات. اقرأ عدد الأوامر، ثم اقرأ كل سلسلة نصية للأمر في سطر منفصل. لكل أمر، استدعِRunواطبع النتيجة.
سيتم توفير المدخلات التالية:
- عدد الأوامر
- كل أمر كسلسلة نصية كاملة في سطر خاص به
على سبيل المثال، إذا كان المدخل:
6
addbook B001 Go-Programming Alan-Donovan 978-0134190440
addbook B002 Clean-Code Robert-Martin 978-0132350884
adduser U001 Alice alice@test.com
borrow U001 B001
listbooks
borrow U001 B001يجب أن يكون مخرجك:
Book added: Go-Programming
Book added: Clean-Code
User added: Alice
Borrowed: B001
B001: Go-Programming
B002: Clean-Code
Error: book not availableوإذا كان المدخل:
4
listbooks
addbook B100 Design-Patterns Gang-of-Four 978-0201633610
listbooks
invalidcmd testيجب أن يكون مخرجك:
No books
Book added: Design-Patterns
B100: Design-Patterns
Unknown command: invalidcmdوإذا كان المدخل:
5
adduser U001 Bob bob@email.com
borrow U001 B001
addbook B001 Golang-Guide John-Smith 123-456
borrow U001 B001
return U001 B001يجب أن يكون مخرجك:
User added: Bob
Error: book not found
Book added: Golang-Guide
Borrowed: B001
Returned: B001لاحظ كيف أن CLI لا يحتاج إلى معرفة تفاصيل كل عملية — فهو ببساطة يبحث عن الأمر ويفوض التنفيذ. هذا يجعل إضافة أوامر جديدة أمراً بسيطاً مثل إنشاء هيكل جديد ينفذ واجهة Command وتسجيله في CLI!
جرّب بنفسك
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// قراءة عدد الأوامر
var n int
fmt.Scanln(&n)
// إنشاء scanner لقراءة الأسطر الكاملة
scanner := bufio.NewScanner(os.Stdin)
// TODO: إنشاء Library جديدة
// TODO: إنشاء CLI جديد مع الـ library
// TODO: معالجة كل أمر
// لكل أمر من الـ n أوامر:
// - قراءة سطر الأوامر باستخدام scanner.Scan() و scanner.Text()
// - تشغيل الأمر من خلال الـ CLI
// - طباعة النتيجة
_ = scanner // قم بإزالة هذا السطر عند استخدام scanner
}
جميع دروس Object Oriented Programming
1أساسيات الـ OOP في Go
الملفات الخارجيةمساحة العمل والـ Modules في Goالـ Packages والـ Importsالأسماء المصدرة مقابل غير المصدرةمقدمة إلى الـ OOP في Goالـ Structs كـ Classesتعريف الـ Methods في الـ Structsالـ Pointer Receivers مقابل الـ Value Receiversتهيئة الـ Structدوال الـ Constructorمراجعة - آلة حاسبة بسيطة4الواجهات
مقدمة في الواجهاتالتنفيذ الضمنيالواجهة كعقدالواجهة الفارغة (any)تأكيد النوع (Type Assertion)تبديل النوع (Type Switch)تركيب الواجهاتواجهات Stringer و Errorمراجعة - حاسبة الأشكال7التغليف
الحقول المصدرة وغير المصدرةالتغليف على مستوى الحزمةدوال الـ Getter والـ Setterإخفاء المعلومات في Goملخص - سجلات الطلاب10الأنواع العامة (Go 1.18+)
مقدمة في الأنواع العامةمعاملات الأنواعقيود الأنواعالـ Structs العامةحل بديل للـ Methods العامةملخص - المجموعات العامة13أنماط التصميم - الجزء الأول
مقدمة في أنماط التصميمنمط Singletonنمط Factoryنمط Abstract Factoryنمط Observerنمط Strategy2تعمق في الأنواع و Structs
الأنواع الأساسية والمركبةتعريفات الأنواع المخصصةStruct TagsStructs مجهولةStructs متداخلةالقيم الصفرية والافتراضيةمراجعة - دفتر العناوين5التركيب بدلاً من الوراثة
لماذا لا تدعم Go الوراثةأساسيات تضمين الـ Structترقية الـ Methodتضمين عدة Structsالتضمين مقابل التجميعحجب الـ Methods المضمنةملخص - الهيكل الهرمي للموظفين8معالجة الأخطاء و OOP
واجهة errorأنواع الأخطاء المخصصةتغليف الأخطاء (fmt.Errorf)أخطاء Sentinelerrors.Is() و errors.As()Panic و Defer و Recoverملخص - File Parser11المكتبة القياسية والبرمجة كائنية التوجه (OOP)
io.Reader و io.Writerواجهة sort.Interfaceواجهة fmt.Stringerencoding/json مع Structsواجهة http.Handlerمراجعة - نماذج REST API14أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبMiddleware كنمط مزين3المؤشرات والذاكرة
أساسيات المؤشرات في Goالمؤشرات إلى الـ Structsالتمرير بالقيمة مقابل التمرير بالمرجعدالة ()newGarbage Collection في Goملخص - بناء Linked List6تعدد الأشكال في Go
تعدد الأشكال عبر InterfacesDuck Typing في Goقواعد استيفاء الـ Interfaceمجموعات متعددة الأشكالحقن التبعيةمراجعة - معالج الدفع9التزامن والبرمجة كائنية التوجه (OOP)
أساسيات الـ Goroutinesالقنوات (Channels) والاتصالالقنوات المخزنة (Buffered) مقابل غير المخزنةجملة Selectsync.Mutex و sync.RWMutexsync.WaitGroupتصميم الـ Structs الآمنة للخيوط (Thread-Safe)مراجعة - Worker Pool12مفاهيم OOP المتقدمة
نمط Functional Optionsنمط Builder في Goتسلسل الدوال (Method Chaining)الأسماء المستعارة للأنواع مقابل التعريفاتأساسيات الـ Reflectionنظرة عامة على Code Generation15مشروع: إدارة المكتبة
نظرة عامة وهيكل المشروعهياكل Structs الكتاب والمستخدم