الجزء الأول ، استنادا إلى التعليقات ، تسبب في رأي متباين ، وخاصة فيما يتعلق بجزء التعداد. في مكان ما يمكنني أيضًا أن أختلف معه ، سواء مع مؤلف النص الأصلي أو مع بعض التعليقات. ولكن كما هو موضح في الوصف الأولي للجزء الأول ، فإن الشفرة النظيفة ليست عقيدة يجب إتباعها ، إنها مجرد توصيات يختار الجميع مراعاتها لتناسب احتياجاتهم ووجهات نظرهم.

الكائنات وهياكل البيانات
استخدام الحصانة
يتيح لك نظام الكتابة في TypeScript وضع علامة على الخصائص الفردية للواجهة / الفئة كحقول للقراءة فقط (للقراءة فقط) . يتيح لك ذلك العمل وظيفيًا (حدوث طفرة غير متوقعة سيء). بالنسبة للسيناريوهات الأكثر تعقيدًا ، يوجد نوع Readonly
مدمج يأخذ نوع T
ويميز جميع خصائصه للقراءة فقط باستخدام الأنواع المعينة (انظر الأنواع المعينة ).
الفقراء:
interface Config { host: string; port: string; db: string; }
حسن:
interface Config { readonly host: string; readonly port: string; readonly db: string; }
في حالة صفيف ، يمكنك إنشاء صفيف ReadonlyArray<T>
باستخدام ReadonlyArray<T>
. التي لا تسمح بالتغييرات باستخدام push()
و fill()
، لكن يمكنك استخدام concat()
و slice()
لا يغيران القيم.
الفقراء:
const array: number[] = [ 1, 3, 5 ]; array = [];
حسن:
const array: ReadonlyArray<number> = [ 1, 3, 5 ]; array = [];
إعلان وسيطات للقراءة فقط TypeScript 3.4 أسهل قليلاً .
function hoge(args: readonly string[]) { args.push(1);
تأكيدات التفضيلات const للقيم الحرفية.
الفقراء:
const config = { hello: 'world' }; config.hello = 'world';
حسن:
أنواع مقابل واجهات
استخدم أنواعًا عندما تحتاج إلى اتحاد أو تقاطع. استخدم الواجهة عندما تريد استخدام extends
أو implements
. ومع ذلك ، لا توجد قاعدة صارمة ، استخدم ما يناسبك. للحصول على شرح أكثر تفصيلاً ، راجع هذه الإجابات حول الاختلافات بين type
interface
في TypeScript.
الفقراء:
interface EmailConfig {
حسن:
type EmailConfig = {
فصول
يجب أن تكون الفصول صغيرة
يقاس حجم الفصل بمسؤوليته. باتباع مبدأ المسؤولية الفردية ، يجب أن يكون الفصل صغيراً.
الفقراء:
class Dashboard { getLanguage(): string { } setLanguage(language: string): void { } showProgress(): void { } hideProgress(): void { } isDirty(): boolean { } disable(): void { } enable(): void { } addSubscription(subscription: Subscription): void { } removeSubscription(subscription: Subscription): void { } addUser(user: User): void { } removeUser(user: User): void { } goToHomePage(): void { } updateProfile(details: UserDetails): void { } getVersion(): string { }
حسن:
class Dashboard { disable(): void { } enable(): void { } getVersion(): string { } }
ارتفاع التماسك منخفضة السندات
يحدد التماسك الدرجة التي يرتبط بها أعضاء الفصل مع بعضهم البعض. من الناحية المثالية ، يجب استخدام جميع الحقول في الفصل الدراسي بواسطة كل طريقة. نقول أن الفصل متصلاً قدر الإمكان . في الممارسة العملية ، ومع ذلك ، هذا ليس ممكنا دائما وحتى غير مرغوب فيه. ومع ذلك ، يجب عليك التأكد من أن التماسك مرتفع.
يشير الاتصال أيضًا إلى كيفية ارتباط فئتين أو اعتمادهما على بعضهما البعض. تعتبر الفصول الدراسية مترابطًا إذا كانت التغييرات في أحدها لا تؤثر على الآخر.
الفقراء:
class UserManager {
حسن:
class UserService { constructor(private readonly db: Database) { } async getUser(id: number): Promise<User> { return await this.db.users.findOne({ id }); } async getTransactions(userId: number): Promise<Transaction[]> { return await this.db.transactions.find({ userId }); } } class UserNotifier { constructor(private readonly emailSender: EmailSender) { } async sendGreeting(): Promise<void> { await this.emailSender.send('Welcome!'); } async sendNotification(text: string): Promise<void> { await this.emailSender.send(text); } async sendNewsletter(): Promise<void> {
تفضل التكوين على الميراث
كما قيل في أنماط التصميم من عصابة الرابع ، يجب عليك
تفضل تكوين الميراث أينما استطعت. هناك العديد من الأسباب الجيدة لاستخدام الميراث والعديد من الأسباب الجيدة لاستخدام التكوين. يكمن جوهر هذا المبدأ في أنه إذا استمر عقلك غريزيًا في الميراث ، فحاول أن تفكر فيما إذا كانت التركيبة يمكنها أن تصوغ مشكلتك بشكل أفضل. في بعض الحالات ، يمكن.
ثم قد تسأل: "متى يجب أن استخدم الميراث؟" هذا يعتمد على مشكلتك ، لكنها قائمة جيدة عندما يكون الميراث أكثر منطقية من التكوين:
- الميراث الخاص بك هو علاقة "is-a" وليست علاقة "has-a" (الإنسان - الحيوان مقابل المستخدم - تفاصيل المستخدم).
- يمكنك إعادة استخدام الشفرة من الفئات الأساسية (يمكن للأشخاص التنقل مثل جميع الحيوانات).
- تريد إجراء تغييرات عمومية على الفئات المشتقة عن طريق تغيير الفئة الأساسية. (التغير في الإنفاق من السعرات الحرارية في جميع الحيوانات عند نقلها).
الفقراء:
class Employee { constructor( private readonly name: string, private readonly email: string) { }
حسن:
class Employee { private taxData: EmployeeTaxData; constructor( private readonly name: string, private readonly email: string) { } setTaxData(ssn: string, salary: number): Employee { this.taxData = new EmployeeTaxData(ssn, salary); return this; }
استخدام سلاسل الاتصال
هذا النمط مفيد للغاية ويشيع استخدامه في العديد من المكتبات. هذا يسمح رمز الخاص بك لتكون معبرة وأقل مطول. لهذا السبب ، استخدم سلسلة من الطرق وشاهد مدى نظافة الكود.
الفقراء:
class QueryBuilder { private collection: string; private pageNumber: number = 1; private itemsPerPage: number = 100; private orderByFields: string[] = []; from(collection: string): void { this.collection = collection; } page(number: number, itemsPerPage: number = 100): void { this.pageNumber = number; this.itemsPerPage = itemsPerPage; } orderBy(...fields: string[]): void { this.orderByFields = fields; } build(): Query {
حسن:
class QueryBuilder { private collection: string; private pageNumber: number = 1; private itemsPerPage: number = 100; private orderByFields: string[] = []; from(collection: string): this { this.collection = collection; return this; } page(number: number, itemsPerPage: number = 100): this { this.pageNumber = number; this.itemsPerPage = itemsPerPage; return this; } orderBy(...fields: string[]): this { this.orderByFields = fields; return this; } build(): Query {
أن تستمر ...