بدبین ابزاری است که من به عنوان بخشی از پروژه دکترای خود نوشتم. کد را برای تکنیک های برنامه نویسی شی گرا که مانع استفاده مجدد و انعطاف پذیری کد می شود اسکن می کند.
چرا؟
بگذارید با دو مشاهده پیش پا افتاده شروع کنم:
- الزامات تجاری با گذشت زمان تغییر می کند.
- برنامه نویسان بصیر نیستند.
راه اندازی محصولات جدید ، مقررات قفل اضطراری ، گسترش به بازارهای جدید ، عوامل اقتصادی ، قوانین به روز شده در مورد محافظت از داده ها: دلایل زیادی وجود دارد که نرم افزارهای تجاری به بروزرسانی نیاز دارند.
با توجه به این دو مشاهده می توان نتیجه گرفت که برنامه نویسان می دانند کدی که می نویسند تغییر خواهد کرد ، اما اینکه این تغییرات چه زمانی خواهد بود یا چه زمانی اتفاق می افتد.
نوشتن کد به گونه ای که بتوان آن را به راحتی تطبیق داد مهارتی است که سالها طول می کشد تا تسلط داشته باشید.
شما احتمالاً قبلاً با شیوه های برنامه نویسی آشنا شده اید که دوباره شما را آزار می دهد. برنامه نویسان تازه کار به سرعت متوجه می شوند که متغیرهای جهانی بیش از ارزششان دردسرساز هستند و الگوی Singleton که قبلاً فوق العاده محبوب بود ، کلمه کثیف دهه اخیر بوده است.
نحوه کدگذاری برنامه کاربردی شما تأثیر بسزایی در سازگاری آسان برای پاسخگویی به نیازهای جدید دارد. همانطور که در حرفه خود پیشرفت می کنید ، تکنیک هایی را یاد می گیرید که سازگاری کد را آسان تر می کند. هنگامی که اصول برنامه نویسی شی گرا را درک کردید ، تعجب می کنید که چگونه بدون آن کار کرده اید!
اگر از ده توسعه دهنده بخواهید نرم افزار تولید کنند ، با توجه به شرایط مشابه ، ده راه حل مختلف دریافت خواهید کرد. برخی از این راه حل ها به طور حتم بهتر از سایر راه حل ها خواهند بود.
یک کشتی را در یک بطری و یک نمونه مدل را که از لگو ساخته شده در نظر بگیرید. هر دو کشتی نمونه هستند اما تغییر بادبان کشتی در بطری بسیار دشوار است و استفاده مجدد از قطعات تقریباً غیرممکن است. با این حال ، با یک کشتی لگو ، می توانید بادبان ها را به راحتی عوض کنید یا از همان قطعات برای ساخت یک موشک ، خانه یا ماشین مدل استفاده کنید.
برخی از تکنیک های برنامه نویسی منجر به کشتی در بطری نزدیک شوید و کد خود را تغییر دهید و تغییر دهید.
بدبین
بدبین ابزاری است که کد شما را برای اقدامات برنامه نویسی که منجر به این نوع کشتی ها در طراحی بطری می شود ، اسکن می کند.
کد شما را بر اساس انعطاف پذیری آن درجه بندی می کند و مناطقی را که می توان انعطاف پذیری را بهبود بخشید برجسته می کند.
Insphpect به دنبال چه چیزی است؟
در حال حاضر ، Insphpect به دنبال موارد زیر است:
- اتصال کامل
- پیکربندی سخت کدگذاری شده
- تک نفره ها
- تزریق ساتر
- با استفاده از
new
کلمه کلیدی در یک سازنده - خدمات یاب
- وراثت
- روشهای ایستا
- دولت جهانی
- پرونده هایی که بیش از یک نقش دارند (به عنوان مثال تعریف کلاس و اجرای برخی از کدها)
اگر هر چیزی را شناسایی کند که غیرقابل انعطاف باشد ، این کد را برجسته می کند ، توضیح می دهد که چرا این مسئله را برجسته کرده است ، سپس کل پروژه و کلاسهای فردی خود را با نمره 0-100 (با 100 بدون هیچ مشکلی شناسایی شده) درجه بندی می کند به عنوان اثبات مفهوم ، برای برخی از ردیابی ها قادر است به طور خودکار یک فایل وصله ایجاد کند که کد را دوباره بنویسد تا انعطاف پذیری را به طور کامل از بین ببرد.
Insphpect اکنون در مرحله آزمایش است و اگر بتوانید آن را بررسی کرده و نظرسنجی را در بخش “نظرات خود را بگویید” در سایت انجام دهید ، واقعاً به پیشرفت تحقیقات من کمک می کند.
زمینه
با این وجود آیا آن اعمال بد واقعا بد هستند؟
این یکی از بخشهای دشوار تحقیقات پیشینه بود و شما می توانید در مورد چگونگی انجام این کار با جزئیات مطالعه کنید وب سایت Insphpect.
با این حال ، می توان این را خلاصه کرد:
- نظرات هر عمل بد از 100 نویسنده در هر عمل جمع آوری شد.
- نظر نویسنده در مورد عمل در مقیاس 1–5 درجه بندی شد.
- دقت روش شناسی نویسنده در مقیاس 1-7 بر اساس نمره Jadad که برای آزمایشات بالینی استفاده می شود ، درجه بندی شد.
سپس این نمودارها مانند نمودار زیر ترسیم شده اند:
هر خط افقی یک مقاله را نشان می دهد ، و نوار سمت چپ (نارنجی) برای هر مقاله توصیه می شود از 5 – از این عمل به هر قیمتی خودداری کنید (سمت چپ دور) – به 1 – این روش را به جای گزینه های دیگر ترجیح دهید.
نوار مناسب (آبی) برای هر مقاله ، نمره سبک جاداد است که میزان دقت آنالیز را اندازه گیری می کند. نمره هفت به معنای این است که مقاله تمرین را توصیف می کند ، مثالهایی از کد را ارائه می دهد ، در مورد روشهای جایگزین بحث می کند ، نمونه های کد مشابه مانند آنها را ارائه می دهد ، در مورد جوانب مثبت / منفی هر یک از روش ها بحث می کند و توصیه می کند که از کدام روش استفاده شود.
در مورد تک مورد فوق ، نویسندگانی که تک خوان را با رویکردهای جایگزین مقایسه می کنند ، درباره جوانب مثبت / منفی بحث می کنند ، به طور قابل توجهی احتمالاً استفاده از رویکردهای جایگزین را بیشتر پیشنهاد می دهند.
پیاده روی
در حال حاضر ، Insphpect امکان بارگذاری کد از طریق URL مخزن Git یا یک فایل ZIP را فراهم می کند.
بنابراین برای اینکه به نقص کار دیگران اشاره نکنم ، بیایید نگاهی به یکی از پروژه های خودم بیندازیم تا ببینیم چه چیزی مشخص می کند.
ما استفاده خواهیم کرد https://github.com/Level-2/Transphporm به عنوان نمونه پروژه
این مثال کاملاً خوبی است ، زیرا در ابزار دیگری با کیفیت کد دارای نمره بسیار بالایی است موشکافی.
ابتدا آدرس git را وارد کنید https://github.com/Level-2/Transphporm
وارد جعبه متن در بالای صفحه اصلی شوید و “برو” را فشار دهید. بسته به اندازه پروژه ، چند ثانیه تا چند دقیقه طول خواهد کشید و گزارشی تهیه خواهید کرد که شبیه به این شکل است:
هنگامی که در صفحه گزارش قرار گرفتید ، خلاصه ای در بالا با نمره کلی از 100 مشاهده خواهید کرد ، با 100 بسیار خوب و 0 بسیار ضعیف.
در زیر خلاصه ، لیستی از تمام کلاسهای پروژه را مشاهده خواهید کرد که هر کدام دارای نمره خاص خود هستند.
اگر کد شما نمره کاملی نگرفت نگران نباشید. بعید است که چنین شود. به یاد داشته باشید ، Insphpect ابزاری است که انعطاف پذیری را در کد شما شناسایی می کند. قسمتهایی از کد شما وجود دارد (مانند نقطه ورود) که انعطاف پذیری آنها ضمانت نمی کند.
برای Transphporm ، این موضوع در هفت کلاس را برجسته کرده است.
بیایید نگاهی به برخی از آن ها بیندازیم. به پایین بروید TransphpormParserCssToXpath
و روی پیوند کلیک کنید. نمره ای را برای آن کلاس خاص و لیستی از موارد مشخص شده را مشاهده خواهید کرد.
در این حالت ، آن یک متغیر استاتیک و یک روش ایستا را شناسایی کرده است. با کلیک بر روی یکی از خطوط قرمز ، توضیحی در مورد پرچم گذاری این خط نشان داده می شود.
به عنوان مثال ، با کلیک روی خط 12 توضیحی در مورد دلیل انعطاف پذیری کمتر متغیرهای استاتیک نسبت به متغیرهای نمونه ارائه می شود.
اگرچه توضیحات عمیق تری درباره مسائل ناشی از خصوصیات ساکن در شبکه وجود دارد گزارش، به عنوان یک تازه سازی سریع ، متغیرهای استاتیک یک مقدار دارند که در تمام نمونه های کلاس به اشتراک گذاشته می شود.
این امر ذاتاً کمتر از متغیر نمونه انعطاف پذیر است ، زیرا استفاده از متغیر نمونه به هر نمونه اجازه می دهد تا مقدار متفاوتی داشته باشد.
به عنوان مثال ، موارد زیر را در نظر بگیرید:
class User {
public static $db;
public $id;
public $name;
public $email;
public function save() {
$stmt = self::$db->prepare('REPLACE INTO user (id, name, email) VALUES (:id, :name, :email)');
$stmt->execute([
'id' => $this->id,
'name' => $this->name.
'email' => $this->email
]);
}
}
زیرا $db
ثابت است ، هر نمونه از این کلاس یکسان است $db
پرونده ها و پرونده ها همیشه در همان پایگاه داده قرار می گیرند.
گرچه این به نظر منطقی می رسد ، بگذارید یک مثال در دنیای واقعی برای شما بیاورم.
در دنیای واقعی
یکی از مشتریان ما آژانس استخدام بود. حدود دو سال پس از توسعه سایت آنها ، آنها شرکت کوچکتر دیگری را تصاحب کردند. آنها می خواستند وب سایت و مارک تجاری شرکت دوم را حفظ کنند زیرا این کاملاً مشهور در جایگاهی بود که در آن قرار داشتند.
مشتری ما از ما موارد زیر را پرسید:
آیا در سایت شرکت دوم ، آیا می توانید هنگام اضافه کردن شغلی ، یک کادر تأیید اضافه کنید که کار را به پایگاه داده ما اضافه کند ، بنابراین افرادی که سایت ما را مشاهده می کنند ، می توانند کار و ویزا را نیز ببینند.
یک درخواست کاملاً ساده. جستجوی درج را در دو پایگاه داده مختلف اجرا کنید.
اما از آنجا که وب سایت از یک نمونه پایگاه داده جهانی استاتیک استفاده می کند ، این کار بدون مشکل انجام شد!
توسعه دهندگان آن سایت با اطمینان از اینکه فقط به یک اتصال پایگاه داده احتیاج دارد ، این کد را نوشتند. آنها اشتباه می کردند.
به یاد داشته باشید ، شما بصیر نیستید و نمی توان پیش بینی کرد که در آینده چه انعطاف پذیری لازم است.
راه حل
همانطور که Insphpect پیشنهاد کرده است ، راه حل این کار استفاده از متغیرهای نمونه است:
class User {
private $db;
public $id;
public $name;
public $email;
public function __construct(PDO $db) {
$this->db = $db;
}
public function save() {
$stmt = self::$db->prepare('REPLACE INTO user (id, name, email) VALUES (:id, :name, :email)');
$stmt->execute([
'id' => $this->id,
'name' => $this->name.
'email' => $this->email
]);
}
}
حالا یک User
نمونه را می توان با موارد مختلف پایگاه داده استفاده کرد:
new User($database1);
new User($database2);
برای TransphpormParserCssToXpath
ما می توانیم همین کار را انجام دهیم ، متغیر استاتیک را حذف کنیم و در نظر بگیریم که آن را به جای متغیر استاتیک ، به یک متغیر نمونه تبدیل کنیم.
استفاده از جدید در سازنده
بیایید نگاهی به یکی از کلاسهای دیگر بیندازیم: TransphpormBuilder
.
این نمره صفر دارد که نسبتاً ضعیف است. با بررسی دقیق گزارش ، Insphpect سه بار همان مسئله را انتخاب کرده است: با استفاده از new
کلمه کلیدی در یک سازنده.
مربی برنامه نویسی گوگل ، Misko Hevery در توضیح اینکه چرا این یک عمل برنامه نویسی ضعیف است ، بسیار عالی عمل می کند، اما در اینجا یک مثال ساده از خروجی Insphpect آورده شده است:
class Car {
private $engine;
public function __construct() {
$this->engine = new PetrolEngine();
}
}
در اینجا ، هر زمان که نمونه ای از Car
ایجاد شده است ، نمونه ای از PetrolEngine
ایجاد شده است. این مسئله آن را بسیار انعطاف ناپذیر می کند ، زیرا هیچ راهی برای ساختن a وجود ندارد Car
با موتور متفاوت. هر اتومبیل مدل شده در این سیستم باید دارای یک باشد PetrolEngine
.
در عوض ، می توانیم از تزریق وابستگی استفاده کنیم:
class Car {
private $engine;
public function __construct($engine) {
$this->engine = $engine;
}
}
ماشین های مختلفی را می توان با نمونه ای از آن ایجاد کرد PetrolEngine
، DieselEngine
، ElectricEngine
، JetEngine
یا هر نوع موتور دیگری که در پروژه وجود دارد.
برای رفع این خطا در TransphpormBuilder
، تمام متغیرهایی که در حال حاضر نام کلاس های سخت رمزگذاری شده دارند باید به جای آنها از آرگومان های سازنده استفاده کنند.
موارد دیگری نیز توسط Insphpect شناسایی شده است ، اما می توانید خودتان آن را امتحان کنید و ببینید که قیمت پروژه چگونه است.
پشت صحنه
شاید از خود بپرسید که نمرات چگونه محاسبه می شود و چرا این کلاس صفر شده است. در حال حاضر ، با اسکن پروژه های دیگر و ارائه بازخورد بیشتر ، وزن دهی ها ممکن است تغییر کند.
این نمرات به گونه ای طراحی شده اند که برای مقایسه یک پروژه / کلاس با دیگری نشانگر باشند.
نمره کلی پروژه فقط میانگین کل کلاسهای پروژه است. این به این دلیل اجرا شد که یک پروژه با دو موضوع در 1000 کلاس در کل بسیار بهتر از یک پروژه با دو موضوع در دو کلاس است.
هر عملکرد بد بر اساس اینکه آیا مانع انعطاف پذیری برای کل کلاس است یا فقط مانع از انعطاف پذیری برای یک روش می شود ، ارزیابی می شود.
نتیجه
از Insphpect می توان برای شناسایی مناطقی از کد شما استفاده کرد که تغییرات آینده را دشوارتر از آنچه ممکن است باشد ، ارائه می دهد و پیشنهاداتی در مورد نحوه نوشتن کد به روش انعطاف پذیرتری ارائه می دهد. به یاد داشته باشید ، شما بصیر نیستید و راهی ندارید که بدانید کد شما چگونه باید تغییر کند!
بدبین در حال حاضر کاری در دست انجام است و هرچه تعداد افرادی که از آن استفاده می کنند (و نظرسنجی را کامل می کنند) نتیجه بهتری خواهد داشت.
پروژه یا کتابخانه مورد علاقه شما چگونه امتیاز گرفت؟ حتماً نظرسنجی را کامل کنید ، زیرا داده های ارزشمندی برای پروژه دکترای من فراهم می کند و به پیشرفت ابزار کمک می کند!