اصل ماجرا

مقاله به مفهوم دو کانال سیگنالینگ (درون‌خطی و بیرون‌خطی) در طراحی رابط‌های برنامه‌نویسی می‌پردازد و نشان می‌دهد چگونه انتخاب صحیح بین این دو می‌تواند از بروز باگ‌های پنهان جلوگیری کند. با مثال‌های مختلف از استثناهای جاوااسکریپت تا Result در رست، اصولی برای تصمیم‌گیری دربارهٔ نمایش یا مخفی‌سازی نگرانی‌ها ارائه می‌شود.

متن کامل ترجمه‌شده

این کد به راحتی یک نظرسنجی را می گذارد: واکنش کنس = منتظر فرستادن (##############################################################################################################################################################################این سیگنال تعیین می کند که چگونه رابط شکست می یابد: با تصمیم گیری یا تصادفی. هنگامی که شما از این طریق رابط ها را می بینید، بسیاری از سوالات طراحی شناخته شده به همان شکل می شوند. یک ارزش خطا را هدایت کنید یا برگردانید؟ پارامتر مورد نیاز یا استاندارد؟ هدف یا نوع اتحادیه؟ هر کدام از شما می پرسند که چگونه به شدت رابط باید یک نگرانی را نشان دهد. به زودی شما اصول را برای پاسخ دادن خواهید داشت. سیگنال نگرانی من از ارتباطات تلفن همراه به عنوان یک صداقت سیگنال قرض می کنم. سیگنال بین باند به معنای اطلاعات کنترل در همان کانال به عنوان داده ها سفر می کند. سیگنال خارج از باند از یک کانال جداگانه برای اطلاعات کنترل استفاده می کند. تفاوت نقشه به صورت روشن به نگرانی های رابط. هر رابط دارای دو کانال مشابه است و هر یک از نگربه عنوان مثال، بازگرداندن نتیجه Rust’s Result URL_0 می تواند به طور صریح از این اشتباه استفاده کند: fn parse_config(raw: &str) -> Result\URL_1&#123; … } // تلاش برای استفاده از نتیجه بدون باز کردن باعث ایجاد یک خطا نوع می شود. // اگر خواننده تصمیم می گیرد خطا را نادیده بگیرد، آنگاه آن را قصد دارد. let result = parse_config(raw); match result {Ok(config) => start_server(config), Err(e) => eprintln!(“{e} }”),در این صورت خطا در band است.در این صورت، خطا از بین می رود. در این صورت، خطا از بین می رود. در مقایسه با آن نیاز به رشته ای است، و یک خواننده می تواند بدون اینکه بدانند که وجود دارد، از آن عبور کند. یک عملکرد که یک استثنا چک می کند، خطا را به عقب می کشد. در این صورت، خواننده مجبور می شود که خطا را به طور صریح دریافت کند یا گسترش دهد. به عنوان مثال، کلمه کلیدی ژاوی را می کشد، کارهای اشتباه را در گروه انجام می دهد: Config parseConfig(String raw) ParseException { // //} ParseException { //} را می کشد. // این کار باعث می شود که استثنا چک شود. This will compil // without either catching or declaring throws ParseException. void start(String raw) throws ParseExبرنامه نویسان جاوا به طور ناشناخته است که از استثناها استفاده می کنند که با استفاده از بلوک های کشی خالی، ردیابی های ناشناخته، یا استثنا های استثنا استفاده می کنند. این بدتر از استثناها است. کد فقط به نظر می رسد که با مشکل مواجه شده است. موفقیت Rust نشان می دهد که شکست جاوا ergonomics بود، نه مقابله است. نتیجه نیز به همین دلیل است: داده های در باند به معنای نگرانی های بین باند نیستند، اما لذت بخش است که با آن روبرو شوند. استثناها نیز نشان می دهد که کانال که داده ها را حمل می کند، همان است که کانال است که نگرانی را حمل می کند. استثناها چک شده خارج از ارزش بازگشت می رود، اما نگرانی در باند است. اشتباهات برعکس نیز وجود دارد: داده ها در باند بهjson، O_RDONLY); // اگر fd == -1، این در زمان اجرا با EBADF ناکام می شود. read(fd, buf, sizeof(buf));Naming Names می تواند نگرانی ها را در باند یا خارج از باند حرکت دهد. به عنوان مثال، HashSet از جاوا هیچ نظم بارگذاری تضمین نمی کند، اما نام فقط برنامه ریزی را توصیف می کند، نه ویژگی بارگذاری. سفارش بارگذاری می تواند تصادفی برای مجموعه های کوچک متصل شود، بنابراین یک کاربر می تواند از آن پرهیز کند بدون اینکه متوجه شود: // می تواند برای مجموعه های کوچک در ترتیب بارگذاری چاپ کند، باعث می شود که کاربر از // یک نظم که تضمین نشده است پرهیز کند. HashSet URL0 set = HashSet جدید<(List.of 1, 4, 1, 5)); برای (int value setاز(3, 1, 4, 1, 5)); برای (Int value : set) {System.out.println(value); }Union types Union are the usual tool for making illegal states unrepresentable, and that moves concerns in-band as a byproduct because each variant is a case the user must consider. But legality and signaling are independent. A union can move a concern in-band even when every state is already legal. For example, every combination of property values on JavaScript’s KeyboardEvent type is valid, yet it hides a concern: interface KeyboardEvent extends UIEvent { // Which primary key is pressed. key: // string Secondary modifier key flags. All value combinations are valid.AltKey: boolean ctrlKey: boolean metaKey: boolean shiftKey: boolean // Otherپرچم ها داده های اولیه این رویداد نیستند، بنابراین آنها به طور قابل اعتماد توجه کاربر را به دست نمی آورند. یک نمایش بیشتر در باند از موضوع اصلاح کننده ممکن است به این شکل باشد: typ KeyboardEvent = { kind: ‘single-key’ key: string } { kind: ‘modified-key’ primaryKey: string altKey: boolean ctrlKey: boolean metaKey: boolean shiftKey: boolean }در TypeScript، کاربر نمی تواند به هیچ اطلاعاتی در این نوع از نوع دیگر دسترسی داشته باشد. آنها مجبور خواهند شد که هر دو مورد کلیدی واحد و اصلاح شده را به صورت جداگانه در نظر بگیرند. هیچ وضعیت غیرقانونی برای حذف وجود ندارد، اما تغییر به یک سیگنال یونانی هنوز تحت تاثیر قرار می گیرد.2 مهم است که کلید و primaryKeyپارامترهای مورد نیاز پارامترهای مورد نیاز می توانند نگرانی ها را در باند تغییر دهند با حذف فرضیه ها. به عنوان مثال، ساختار String(byte[، Charset]) Java دارای یک پارامتر Charset اختیاری است. هنگامی که از دست داده می شود، چارسیت استاندارد پلت فرم، معمولا UTF-8 استفاده می شود. اگر کاربر فراموش کند یک چارسیت را مشخص کند، پس فرضیه ممکن است داده ها را در هنگام رمزگذاری از بین ببرد. چارسیت نگران است بدون اینکه یک چارسیت را مشخص کند: String = text ByteSource.wrap (wrapes) // می تواند داده ها را در هنگام رمزگذاری خراب کند. String text = new String(bytes); از سوی دیگر, Guava، یک کتابخانه Java محبوب، امکان تولید چارسیت از یک BySource را بدونRandomization Randomization می تواند یک نگرانی در باند را تغییر دهد با جلوگیری از کاربران از به طور نامحدود بستگی به رفتار تشخیصی قابل مشاهده است. به عنوان مثال، مانند HashSet، HashMap از جاوا دارای یک نظم تکراری نامحدود است که کاربران ممکن است به طور تصادفی از آن بستگی داشته باشند. مهندسان گوگل این نگرانی در باند را تغییر می دهند با تغییر JDK خود را به صورت تصادفی برای تکرار hash. کاربران تغییراتی در نظم بین اجرا کد خود را مشاهده می کنند و نمی توانند به طور ناشناخته به آن بستگی کنند. Go همان قدم را برای نقشه های خود انجام داده است، سفارش تکراری تصادفی شروع به Go 1.3 UI نگرانی نیز به UIs اعمال می شود. خط Slack از بین باند است. هنگامی که یک پیام جدید سطح بالا در یک کانال وارد می شود، UI شما را مجبورصفحه اصلی UI شما را مجبور به تصمیم گیری بین کلیک کردن یک دکمه برای شروع یک thread جدید و پاسخ دادن به واردات متن از یک thread موجود وجود نداشت در هر زمان در دسترس در سطح بالا واردات متن وجود داشت تا Google “تغییر” به رویکرد Slack. من هرگز دیده ام کاربران به طور تصادفی شروع یک thread جدید با طراحی اصلی. طراحی اصلی Google Chat با گروه بندی با موضوع گفتگو: و طراحی جدید خود را مطابق با Slack inline threading: اصول نشان دادن در این نقطه شما ممکن است فکر می کنید هر نگرانی باید در band باشد، اما این غیر قابل اجرا است. یک رابط دارای بسیاری از نگرانی ها و آنها به طور یکسان قابل توجه و یا نتیجه ای نیست. انتخاب بین signaling در band و out-of-band هنر بیش از علم4 است، اما برخی از اصول کمک: - استانداردهای حساس: اگر یک استاندارد برای اکثر موارد کار می کند،indexOf(searchElement, fromIndex)فکر پیش فرض برای جستجوی از اول index iffromIndexis ناشناخته است. این تقریبا همیشه چیزی است که کاربر می خواهد. - یک عملکرد که یک نقطه پایانی paginated خودکار می تواند به اندازه صفحه قابل توجهی پیش فرض شود. ممکن است بهترین انتخاب برای همه استفاده ها نیست، اما نتیجه همیشه درست خواهد بود. - جاوا اسکرپت - پیش فرض امن: نگرانی های مربوط به تابعیت داده ها، حفظ حریم خصوصی، یا مسائل امنیتی دیگر باید در باند باشد، مگر اینکه پیش فرض غیر نابود کننده، حفظ حریم خصوصی و ایمن است. - مثال: Python’s - Openfunction پیش فرض به حالت خواندن، که امن است زیرا نمی تواند داده ها را نابود کند. - اقدام: یک نگرانی باید فقط در باند باشد اگر کاربر معمولا می تواند به طور قابل توجهی در نقطه- آندروید ابتدا از کاربر خواست تا لیست تمام اجازه یک برنامه را در زمان نصب تایید کند، هنگامی که آنها هیچ زمینه ای برای ارزیابی آن نداشتند، بنابراین آنها به صورت تفکرانه از آن استفاده کردند. آندروید 6.0 هشدارها را به زمان اجرا منتقل کرد، با استفاده از کاربران در لحظه ای که برنامه نیاز به هر اجازه دارد، هنگامی که آنها می توانند به طور قابل توجهی پاسخ دهند. - خودکشی: اگر یک نگرانی تنها در موارد مهم است که کاربر به طور طبیعی آن را کشف می کند، پس احتمالا باید از بین بماند. - مثال ها: - مشتریان HTTP به طور پیش فرض هدایت ها را دنبال می کنند. اگر هدایت ها یک مشکل هستند، پس برنامه نویسان آنها را هشدار می دهند و غیرفعال می کنند.- انتظار مشتریان: سطح سختی که کاربران رابط خود را انتخاب کرده اند می تواند باعث ایجاد نگرانی در بین باند و یا خارج از باند شود. - مثال ها: - اگر شما از یک کتابخانه موتیکس استفاده می کنید، پس شما تصمیم گرفتید که در مورد موارد قاعدگی مراقبت کنید. Rust بازگشت Resultfrommutex.lock() به عفونت سطح در بین باند مناسب است. - یک زبان اسکرپت سطح بالا مانند پیتون که به صورت پیش فرض به I/O بفرستد بدون نیاز به کاربر برای انتخاب اندازه حافظه مناسب است. اکثر کاربران پیتون در مورد تنظیم عملکرد I/O نگرانی ندارند؛ آنها فقط می خواهند یک فایل را بخوانند. - اگر شما از یک کتابخانه موتیکس استفاده می کنید، پس شما تصمیم گرفتید که در مورد موارد قاعدگی مراقبت کنید. Rust بازگشت - نسبت: اگر یک رابطهر ارتباطی در باند توجه کاربر را مالی می دهد. هر ارتباطی خارج از باند ریسک یک اشتباه خاموش است. طراحی یک رابط به این معنی است که کدام هزینه را برای هر ارتباط پرداخت می کند انتخاب کنید. آن را در جهت در باند اشتباه کنید و کاربران در مراسم غرق شده اند. آن را در جهت خارج از باند اشتباه کنید و کاربران با اعتماد به نفس بیگ های پنهان را حمل می کنند. آن را درست کنید و کاربران به میدان موفقیت می آیند. نوار - این بالا از اندازه سخت برای استفاده از رستی راسل است، که سطح های ارتباط را در نیمه های مثبت و منفی تعیین می کند. ↩ - اگرچه طراحی مجدد وضعیت غیرقانونی خود را دارد: یک - کلید اصلاح شده با هر پرچم تنظیم شده به جعلی. یک اتحاد از متغیرها، که هر یک از آنها نیاز به یک پرچم متفاوت باشد- واقعی است، آن را

چرا مهمه؟

این رویکرد به بهبود کیفیت APIها و کاهش هزینهٔ دیباگ در پروژه‌های بزرگ صنعتی کمک می‌کند.

به درد کی می‌خوره؟

developers, tech_leads, product_managers

تو عمل چی کار کنیم؟

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

نظر Blue IT News

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

<div class=“disclosure”> این صفحه ترجمه و تفسیر کاملی از گزارش اصلی Tomeraberba است که توسط تیم تحریریه بلو آی تی نیوز به فارسی ترجمه و تحلیل شده. برای مشاهده نسخه اصلی، به منبع مراجعه کنید. </div>