Builders غير القابلة للتغيير
أعيدوا نسخ Builder جديدة لتركيب أكثر أمانًا
Builders غير القابلة للتغيير درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
التغيير مقابل عدم القابلية للتغيير
كانت المنشئات حتى الآن تغيّر this وتعيده. أما المنشئ غير القابل للتغيير فيعيد بدلًا من ذلك نسخة جديدة من المنشئ في كل خطوة، من دون تغيير النسخة الأصلية. وهذا يجعل التركيب أكثر أمانًا.
مشكلة التغيير المشترك
إذا احتفظ جزءان من التعليمات البرمجية بالمنشئ نفسه القابل للتغيير، فستؤثر كل دالة تعيين يستدعيها أحدهما في كليهما. وتتجنب المنشئات غير القابلة للتغيير هذه المفاجأة الناتجة عن الأسماء المستعارة تمامًا.
const base = makeMutableBuilder().url("/x");
// If base is shared, later .method() calls mutate everyone's copy.إعادة نسخة جديدة
تنسخ دالة التعيين غير القابلة للتغيير الحالة الحالية، وتضيف الحقل الجديد، ثم تنشئ منشئًا جديدًا. ولا تلمس النسخة الأصلية.
class IB<S> {
constructor(private readonly d: Record<string, unknown> = {}) {}
with<K extends string, V>(k: K, v: V): IB<S & Record<K, V>> {
return new IB<S & Record<K, V>>({ ...this.d, [k]: v });
}
}المشاركة البنيوية باستخدام Spread
ينسخ التعبير { ...this.d, [k]: v } المدخلات الموجودة ويتجاوز قيمة مفتاح واحد. وتتم مشاركة القيم التي لم تتغير بالمرجع، لذلك تبقى النسخ قليلة التكلفة.
const a = new IB<{}>().with("url", "/x");
const c = a.with("method", "GET");
// a still only has url; c has url and method.لا تتغير النسخ الأصلية أبدًا
بما أن كل خطوة تنتج كائنًا جديدًا، فإن إنشاء فروع انطلاقًا من منشئ سابق يكون آمنًا. ويمكنك إعادة استخدام أساس مبني جزئيًا في أماكن متعددة.
const base = new IB<{}>().with("url", "/api");
const get = base.with("method", "GET");
const post = base.with("method", "POST");
console.log("base untouched; get and post diverge");الحالة الداخلية للقراءة فقط
يوثّق تحديد البيانات الداخلية باستخدام readonly هذه النية، ويمنع عمليات الكتابة العرضية داخل الصنف. والطريقة الوحيدة للمتابعة هي إنشاء نسخة جديدة.
class IB<S> {
constructor(private readonly d: Readonly<Record<string, unknown>> = {}) {}
}بناء غير قابل للتغيير ذي أنواع
يستمر تمرير معامل الحالة، ولذلك يمكننا تقييد build() كما سبق تمامًا، ولكن على أساس غير قابل للتغيير هذه المرة.
interface Out { url: string; method: string }
class IB<S> {
constructor(private readonly d: Record<string, unknown> = {}) {}
with<K extends string, V>(k: K, v: V): IB<S & Record<K, V>> {
return new IB<S & Record<K, V>>({ ...this.d, [k]: v });
}
build(this: IB<{ url: string; method: string }>): Out { return this.d as Out; }
}
const out = new IB<{}>().with("url", "/u").with("method", "GET").build();
console.log(out.url);تركيب أكثر أمانًا
تتركب المنشئات غير القابلة للتغيير مثل القيم: مرّر أحدها، واستخرج نسخًا جديدة، ولا تقلق أبدًا من أن يعيد استدعاء لاحق كتابة الحالة المشتركة. وهذه هي الفائدة نفسها التي تمنحها البيانات غير القابلة للتغيير في كل مكان.
إعدادات مسبقة قابلة لإعادة الاستخدام
يمكنك حفظ نقطة بداية شائعة مرة واحدة وإنشاء فروع منها مرات عديدة. ويكون كل فرع مستقلًا بفضل دوال التعيين التي تنسخ عند الكتابة.
const jsonBase = new IB<{}>().with("header", "application/json");
const usersReq = jsonBase.with("url", "/users");
const ordersReq = jsonBase.with("url", "/orders");
console.log("two independent requests from one base");اعتبارات التكلفة
تخصص كل خطوة كائنًا جديدًا. ويكون ذلك ضئيلًا في بناء الإعدادات المعتاد، كما أن المشاركة البنيوية تُبقي النسخ سطحية. ولن تلاحظ التكلفة إلا في الحلقات شديدة التكرار.
ملخص القابلية للتغيير مقابل عدمها
المنشئات القابلة للتغيير أسرع وأبسط قليلًا، أما المنشئات غير القابلة للتغيير فهي أكثر أمانًا عند مشاركتها وأسهل في فهمها. ففضّل غير القابلة للتغيير عندما تُمرّر المنشئات بين الأجزاء أو تُعاد استخدامها كإعدادات مسبقة.
فحص سريع
فحص سريع لهذا الدرس.
مراجعة
يعيد المنشئ غير القابل للتغيير نسخة جديدة في كل خطوة باستخدام المشاركة البنيوية { ...this.d, [k]: v }، ولا يغيّر this أبدًا. وتبقى النسخ الأصلية سليمة، مما يتيح تركيبًا آمنًا وإعدادات مسبقة قابلة لإعادة الاستخدام، مقابل تكلفة تخصيص بسيطة فقط.
الأسئلة الشائعة
هل درس «Builders غير القابلة للتغيير» مجاني؟
نعم — نص درس «Builders غير القابلة للتغيير» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
ماذا ستتعلم في «Builders غير القابلة للتغيير»؟
أعيدوا نسخ Builder جديدة لتركيب أكثر أمانًا تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟
لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «Builders غير القابلة للتغيير»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟
نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أساسيات نمط Builder
- الواجهات السلسة مع الأنواع
- فرض الخطوات المطلوبة
- Builders غير القابلة للتغيير