لینک کوتاه مطلب : https://hsgar.com/?p=6242

درس‌هایی از شیوه نوشتن کتابخانه

برخی از آموخته ها در مورد نوشتن کتابخانه، N سال بعد.

X. افراد فقط کد نمونه شما را کپی پیست می کنند.

این واضح است اما چیزی است که باید در نظر داشت. کد نمونه هرگز نباید طرحی باشد. باید آماده تولید باشد. مردم کامنت‌ها را نمی خوانند. من نقاط زیادی در کد نمونه داشتم که در آنها کامنتی مانند “این فقط یک طرح است و آماده تولید نیست؛ کد تولید باید خطاها را بررسی کند و خرابی ها را کنترل کند و مستقل از endian باشد” و غیره می نوشتم و البته مردم فقط آن را کپی پیست کرد و تغییر نداد. این تقصیر آنها نیست، تقصیر من است. کد، مثال یکی از راه های اصلی ورود افراد به کتابخانه شما است.

X. مردم اسناد را نخواهند خواند.

اسناد تقریباً بی فایده هستند. کسی آنها را نمی خواند. آنها شروع سریع یک صفحه ای را می خوانند، و سپس می خواهند شروع به کندوکاو در نوشتن کد کنند. مقدمه ها را بسیار کم نگه دارید و روی به کار انداختن کارها تمرکز کنید.

همچنین توجه داشته باشید که اگر احساس می کنید باید اسناد زیادی در مورد چیزی بنویسید، این نشانه آن است که شاید همه چیز خیلی پیچیده باشد.

X. ویژگی های کمکی جانبی باید قطع شود.

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

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

اما واقعا فقط آنها را قطع کنید. گسترده بودن خوب نیست. شما می خواهید خیلی باریک باشید. یک مشکل واضح را حل کنید و آن را به خوبی حل کنید. هیچ کس کتابخانه سینک آشپزخانه نمی خواهد.

X. سادگی بهتر است.

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

به عنوان مثال، برای وصل کردن یک تخصیص دهنده برای Oodle به ۷ نشانگر تابع نیاز داشت: { Malloc، Free، MallocAligned، FreeSized، MallocPage، FreePage، PageSize }. (FreeSized برای کارایی، و موارد Page زیرا async IO نیاز به تراز صفحه دارد). اکنون فقط 2 کاهش یافته است: { MallocAligned, Free }. بله کمی کندتر است اما چه کسی اهمیت می دهد. (و زمان اجرا می تواند بدون هیچ تخصیص دهنده ای کار کند)

X. راندمان ریز مهم نیست.

بله، سریع و لاغر بودن خوب است، اما نه زمانی که کار را خیلی پیچیده یا سخت کند. خطر نوعی خودارضایی ذهنی وجود دارد که ما بچه‌های نوع RAD می‌توانیم گرفتار آن شویم. بله، پردازش جریان بزرگ شما باید رقابتی باشد (مثلاً فشرده‌سازی LZ Oodle، یا زمان رمزگشایی فریم Bink). اما اینکه تماس Init() شما به جای 10000 ساعت، 100 ساعت بگیرد، برای همه غیر از شما مهم نیست. و اگر نیاز به مزخرفات خنده دار از کاربر داشته باشد، در واقع اوضاع را بدتر می کند، نه بهتر. اینکه چیزها به طور قابل اعتماد، ایمن و آسان کار کنند مهمتر از کارایی خرد است.

به عنوان مثال، یک اشتباه من در Oodle این است که جریان های فشرده بدون هدر هستند. آنها دارای اندازه فشرده یا غیرفشرده نیستند. دلیلی که من این کار را انجام دادم این بود که اغلب بازی قبلاً آن اطلاعات را از سربرگ های خود دارد، بنابراین اگر دوباره آن را ذخیره کنم اضافی است و چند بایت هزینه دارد. اما این احمقانه بود – برای صرفه جویی در چند بایت از اندازه فشرده، بررسی خطا، استحکام و راحتی را فدای افرادی می کنم که نمی خواهند هدر خود را بنویسند. این میکرو بازدهی است که هزینه زیادی دارد.

یکی دیگر از مواردی که متوجه شدم یک اشتباه است: برای انجام نوشتن async واقعی در ویندوز، باید SetFileValidData را در منطقه فایل تازه بزرگ شده فراخوانی کنید. که نیاز به امتیازات ادمین دارد. این خیلی دردسر است و هیچ کس واقعاً اهمیت نمی دهد. ارزش این آشفتگی را ندارد بنابراین در Oodle2 من این کار را انجام نمی دهم و نوشته ها دیگر ناهمگام نیستند. (هر کس دیگری که فکر می کند در حال نوشتن async است، در واقع اینطور نیست، و هیچ کس دیگری در واقع رشته خود را به روشی که من انجام می دهم بررسی نمی کند، بنابراین من را شبیه بقیه می کند).

X. فقط باید کار کند.

شکننده بد است. هر API که باید در یک دنباله پیچیده پیش برود، این کار را انجام دهید، سپس این، سپس این. این بد است. (به عنوان مثال JPEGlib و PNGlib). چیزها باید تا حد امکان ساده و بدون الزامات کار کنند. در صورت امکان، عملیات باید تک تابعی باشد. مثلاً اگر نشانگرها را به داخل و خارج می‌کنید، لازم نیست که آنها به روش خاصی در یک راستا قرار گیرند یا با تخصیص‌دهنده‌های خود پر شوند یا تخصیص داده شوند. آن را با هر بافری که کاربر ارائه می دهد کار کند. اگر گزینه‌هایی دارید، کارها را فقط با گزینه‌های پیش‌فرض معقولانه انجام دهید تا کاربر بتواند در صورت تمایل، تمام تنظیمات گزینه‌ها را نادیده بگیرد. قبل از عملیات خود نیازی به Init نداشته باشید.

در Oodle2، شما فقط Decompress (اشاره‌گر، اندازه، اشاره‌گر) را فراخوانی می‌کنید و باید فقط کار کند. مواردی مانند رسیدگی به خطا و تخصیص‌دهنده‌ها اکنون به پیش‌فرض‌های سبک معقول بازمی‌گردند، اگر چیزی را به صراحت تنظیم نکنید.

X. موارد خاص باید خارجی باشند (و تماس‌ها بد هستند).

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

به عنوان مثال. اگر می‌خواهند پس‌پردازش تدریجی داده‌ها را در محل انجام دهند، باید از طریق : { decode a bit, process some, decode a bit , process some } در سمت کلاینت امکان پذیر باشد. این کار را با یک callback انجام ندهید که decode_it_all (process_per_bit_callback ) را انجام می دهد.

مجموعه ویژگی های کتابخانه را که تلاش می کند همه را راضی نگه دارد خرد نکنید. برخی از این موارد می‌توانند در کدهای مثال یا در “کد جیب پشتی” شما که در صورت نیاز ارسال می‌کنید قرار گیرند.

X. شما در حال نوشتن کتابخانه برای ارزیابان و کاربران جدید هستید.

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

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

اما ارزیاب ها با شما صحبت نمی کنند. اگر همه چیز فقط برای آنها کارساز نباشد، ناامید خواهند شد. اگر کارها کارایی نداشته باشند یا مشکل داشته باشند، فکر می کنند که کتابخانه بد است. بنابراین کتابخانه باید بدون کمک شما برای آنها خوب کار کند. و آنها اغلب اسناد را نمی خوانند یا حتی از مثال های شما استفاده نمی کنند. بنابراین اگر آنها شروع به فراخوانی کورکورانه APIهای شما کنند، باید خوب پیش برود.

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

هنگامی که آنها به آن عادت کردند، بنابراین لازم نیست نگران آنها باشید.)

(* = تا زمانی که تاخیر کم، بدون حالت، بدون نژاد، قابل اعتماد، قابل پیش بینی باشد، که به نظر می رسد هیچ کس در این دنیای لعنتی دیگر آن را درک نمی کند. دنباله خاصی از اعمال فیزیکی که برای آن حافظه عضلانی ایجاد می کنید باید همیشه نتیجه یکسانی داشته باشد، صرف نظر از زمان، بدون اینکه به دستگاه یا صفحه نمایش نگاه کنید تا مطمئن شوید که درست است. همه کسانی که این کار را انجام نمی دهند (مثلاً همه) باید شلیک کنند و سپس شلیک کنند. اما این کمی دور از موضوع است.)

X. خطاهای ورود و بررسی پیش فرض را ایجاد کنید. اما پیش فرض را نسبتاً سریع انجام دهید.

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

X. کارهای آسان را آسان کنید. اگر چیزهای پیچیده سخت باشند، اشکالی ندارد.

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

لینک منبع

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.