الاستفادة من البرمجة التعريفية لإنشاء تطبيقات ويب يمكن الحفاظ عليها
نشرت: 2022-03-11في هذه المقالة ، أوضح كيف أن تبني تقنيات البرمجة ذات النمط التصريحي بحكمة يمكن أن يسمح للفرق بإنشاء تطبيقات ويب يسهل توسيعها وصيانتها.
"... البرمجة التصريحية هي نموذج برمجة يعبر عن منطق الحساب دون وصف تدفق التحكم." —Remo H. Jansen ، التدريب العملي على البرمجة الوظيفية باستخدام TypeScript
مثل معظم المشاكل في البرامج ، فإن اتخاذ قرار باستخدام تقنيات البرمجة التصريحية في تطبيقاتك يتطلب تقييمًا دقيقًا للمفاضلات. تحقق من إحدى مقالاتنا السابقة للحصول على مناقشة متعمقة لها.
هنا ، ينصب التركيز على كيفية اعتماد أنماط البرمجة التعريفية تدريجيًا لكل من التطبيقات الجديدة والحالية المكتوبة بلغة JavaScript ، وهي لغة تدعم نماذج متعددة.
أولاً ، نناقش كيفية استخدام TypeScript في كل من الواجهة الخلفية والأمامية لجعل شفرتك أكثر تعبيرًا ومرونة للتغيير. ثم نستكشف آلات الحالة المحدودة (FSMs) لتبسيط تطوير الواجهة الأمامية وزيادة مشاركة أصحاب المصلحة في عملية التطوير.
ولايات ميكرونيزيا الموحدة ليست تقنية جديدة. تم اكتشافها منذ ما يقرب من 50 عامًا وتحظى بشعبية في صناعات مثل معالجة الإشارات والملاحة الجوية والتمويل ، حيث يمكن أن يكون تصحيح البرامج أمرًا بالغ الأهمية. كما أنها مناسبة تمامًا لمشكلات النمذجة التي تظهر بشكل متكرر في تطوير الويب الحديث ، مثل تنسيق التحديثات والرسوم المتحركة المعقدة للحالة غير المتزامنة.
تنشأ هذه الميزة بسبب القيود المفروضة على طريقة إدارة الدولة. يمكن أن تكون آلة الحالة في حالة واحدة فقط في وقت واحد ولها حالات مجاورة محدودة يمكنها الانتقال إليها استجابةً للأحداث الخارجية (مثل نقرات الماوس أو جلب الاستجابات). وعادة ما تكون النتيجة انخفاض معدل الخلل بشكل ملحوظ. ومع ذلك ، قد يكون من الصعب توسيع نطاق نهج ولايات ميكرونيزيا الموحدة للعمل بشكل جيد في التطبيقات الكبيرة. تسمح الامتدادات الحديثة لل ولايات ميكرونيزيا الموحدة والتي تسمى مخططات الحالة بتصور ولايات ميكرونيزيا الموحدة المعقدة وتوسيع نطاقها لتطبيقات أكبر بكثير ، وهي نكهة آلات الحالة المحدودة التي تركز عليها هذه المقالة. في عرضنا التوضيحي ، سنستخدم مكتبة XState ، والتي تعد واحدة من أفضل الحلول ل FSMs ومخططات الحالة في JavaScript.
تصريحي على النهاية الخلفية مع Node.js
تعد برمجة الواجهة الخلفية لخادم الويب باستخدام مناهج تعريفية موضوعًا كبيرًا وقد تبدأ عادةً بتقييم لغة برمجة وظيفية مناسبة من جانب الخادم. بدلاً من ذلك ، لنفترض أنك تقرأ هذا في وقت اخترت فيه بالفعل (أو تفكر في) Node.js للجهة الخلفية.
يوضح هذا القسم بالتفصيل نهجًا لنمذجة الكيانات في النهاية الخلفية له الفوائد التالية:
- تحسين قراءة التعليمات البرمجية
- إعادة هيكلة أكثر أمانًا
- إمكانية لتحسين الأداء بسبب الضمانات التي توفرها نمذجة النوع
ضمانات السلوك من خلال نمذجة النوع
جافا سكريبت
ضع في اعتبارك مهمة البحث عن مستخدم معين عبر عنوان بريده الإلكتروني في JavaScript:
function validateEmail(email) { if (typeof email !== "string") return false; return isWellFormedEmailAddress(email); } function lookupUser(validatedEmail) { // Assume a valid email is passed in. // Safe to pass this down to the database for a user lookup.. }
تقبل هذه الوظيفة عنوان البريد الإلكتروني كسلسلة وترجع المستخدم المقابل من قاعدة البيانات عندما يكون هناك تطابق.
الافتراض هو أنه لن يتم استدعاء lookupUser()
إلا بعد إجراء التحقق الأساسي. هذا هو الافتراض الرئيسي. ماذا لو تم إجراء بعض إعادة البناء بعد عدة أسابيع ولم يعد هذا الافتراض قائماً؟ عبرت الأصابع أن اختبارات الوحدة تلتقط الخطأ ، أو ربما نرسل نصًا غير مصفى إلى قاعدة البيانات!
TypeScript (المحاولة الأولى)
لنفكر في مكافئ TypeScript لوظيفة التحقق:
function validateEmail(email: string) { // No longer needed the type check (typeof email === "string"). return isWellFormedEmailAddress(email); }
يعد هذا تحسنًا طفيفًا ، حيث أن مترجم TypeScript قد أنقذنا من إضافة خطوة إضافية للتحقق من وقت التشغيل.
لم يتم الاستفادة من ضمانات الأمان التي يمكن أن توفرها الكتابة القوية حتى الآن. دعونا ننظر في ذلك.
TypeScript (المحاولة الثانية)
لنعمل على تحسين أمان النوع وعدم السماح بتمرير السلاسل غير المعالجة كمدخلات إلى looukupUser
:
type ValidEmail = { value: string }; function validateEmail(input: string): Email | null { if (!isWellFormedEmailAddress(input)) return null; return { value: email }; } function lookupUser(email: ValidEmail): User { // No need to perform validation. Compiler has already ensured only valid emails have been passed in. return lookupUserInDatabase(email.value); }
هذا أفضل ، لكنه مرهق. تصل جميع استخدامات ValidEmail
إلى العنوان الفعلي من خلال email.value
. يستخدم TypeScript الكتابة الهيكلية بدلاً من الكتابة الاسمية التي تستخدمها لغات مثل Java و C #.
على الرغم من قوته ، فإن هذا يعني أن أي نوع آخر يلتزم بهذا التوقيع يعتبر مكافئًا. على سبيل المثال ، يمكن تمرير نوع كلمة المرور التالي إلى lookupUser()
دون شكوى من المترجم:
type ValidPassword = { value: string }; const password = { value: "password" }; lookupUser(password); // No error.
TypeScript (المحاولة الثالثة)
يمكننا تحقيق الكتابة الاسمية في TypeScript باستخدام التقاطع:
type ValidEmail = string & { _: "ValidEmail" }; function validateEmail(input: string): ValidEmail { // Perform email validation checks.. return input as ValidEmail; } type ValidPassword = string & { _: "ValidPassword" }; function validatePassword(input: string): ValidPassword { ... } lookupUser("[email protected]"); // Error: expected type ValidEmail. lookupUser(validatePassword("MyPassword"); // Error: expected type ValidEmail. lookupUser(validateEmail("[email protected]")); // Ok.
لقد حققنا الآن الهدف المتمثل في أنه لا يمكن تمرير سوى سلاسل البريد الإلكتروني التي تم التحقق من صحتها إلى lookupUser()
.
نصيحة للمحترفين: قم بتطبيق هذا النمط بسهولة باستخدام نوع المساعد التالي:
type Opaque<K, T> = T & { __TYPE__: K }; type Email = Opaque<"Email", string>; type Password = Opaque<"Password", string>; type UserId = Opaque<"UserId", number>;
الايجابيات
من خلال كتابة الكيانات في مجالك بقوة ، يمكننا:
- قلل عدد الفحوصات التي يلزم إجراؤها في وقت التشغيل ، والتي تستهلك دورات وحدة المعالجة المركزية (CPU) الثمينة للخادم (على الرغم من كونها صغيرة جدًا ، إلا أنها تضاف عند خدمة آلاف الطلبات في الدقيقة).
- حافظ على عدد أقل من الاختبارات الأساسية بسبب الضمانات التي يوفرها مترجم TypeScript.
- استفد من إعادة البناء بمساعدة المحرر والمجمع.
- تحسين قابلية قراءة الكود من خلال تحسين نسبة الإشارة إلى الضوضاء.
سلبيات
تأتي نمذجة النوع مع بعض المفاضلات التي يجب مراعاتها:
- يؤدي تقديم TypeScript عادةً إلى تعقيد سلسلة الأدوات ، مما يؤدي إلى إطالة أوقات تنفيذ المجموعة واختبارها.
- إذا كان هدفك هو وضع نموذج أولي لميزة ما وإيصالها إلى أيدي المستخدمين في أسرع وقت ممكن ، فقد لا يستحق الجهد الإضافي المطلوب لنمذجة الأنواع بشكل صريح ونشرها من خلال قاعدة الشفرة.
لقد أظهرنا كيف يمكن توسيع كود JavaScript الموجود على الخادم أو طبقة التحقق من صحة الواجهة الخلفية / الواجهة الأمامية المشتركة بأنواع لتحسين قابلية قراءة الكود والسماح بإعادة بناء أكثر أمانًا - متطلبات مهمة للفرق.
واجهات المستخدم التعريفي
تم تطوير واجهات المستخدم باستخدام تقنيات البرمجة التصريحية التي تركز الجهود على وصف "ماذا" على "كيف". اثنان من المكونات الأساسية الثلاثة الرئيسية للويب ، CSS و HTML ، هما لغات برمجة تصريحية صمدت أمام اختبار الزمن وأكثر من مليار موقع.
تم فتح React بواسطة Facebook في عام 2013 ، وقد غيرت بشكل كبير مسار تطوير الواجهة الأمامية. عندما استخدمته لأول مرة ، أحببت كيف يمكنني إعلان واجهة المستخدم الرسومية كوظيفة لحالة التطبيق. أصبحت الآن قادرًا على إنشاء واجهات مستخدم كبيرة ومعقدة من كتل إنشاء أصغر دون التعامل مع التفاصيل الفوضوية لمعالجة DOM وتتبع أجزاء التطبيق التي تحتاج إلى التحديث استجابةً لإجراءات المستخدم. يمكنني تجاهل الجانب الزمني إلى حد كبير عند تحديد واجهة المستخدم والتركيز على ضمان انتقالات تطبيقي بشكل صحيح من حالة إلى أخرى.
لتحقيق طريقة أبسط لتطوير واجهات المستخدم ، أدخل React طبقة تجريد بين المطور والجهاز / المتصفح: DOM الظاهري .
كما عملت أطر عمل واجهة مستخدم الويب الحديثة الأخرى على سد هذه الفجوة ، وإن كان ذلك بطرق مختلفة. على سبيل المثال ، يستخدم Vue تفاعلًا وظيفيًا من خلال أدوات / أدوات ضبط JavaScript (Vue 2) أو وكلاء (Vue 3). يجلب Svelte التفاعلية من خلال خطوة تجميع شفرة المصدر الإضافية (Svelte).
يبدو أن هذه الأمثلة تظهر رغبة كبيرة في صناعتنا لتوفير أدوات أفضل وأبسط للمطورين للتعبير عن سلوك التطبيق من خلال الأساليب التصريحية.
التصريح حالة التطبيق والمنطق
بينما تستمر طبقة العرض في الدوران حول بعض أشكال HTML (على سبيل المثال ، JSX في React ، والقوالب المستندة إلى HTML الموجودة في Vue و Angular و Svelte) ، أفترض أن مشكلة كيفية نمذجة حالة التطبيق بطريقة يسهل فهمه للمطورين الآخرين ويمكن صيانته مع نمو التطبيق لا يزال بدون حل. نرى دليلاً على ذلك من خلال تكاثر مكتبات إدارة الدولة والأساليب التي لا تزال مستمرة حتى يومنا هذا.
الوضع معقد بسبب التوقعات المتزايدة لتطبيقات الويب الحديثة. بعض التحديات الناشئة التي يجب أن تدعمها مناهج إدارة الدولة الحديثة:
- تطبيقات غير متصلة بالإنترنت تستخدم تقنيات الاشتراك والتخزين المؤقت المتقدمة
- إعادة استخدام كود ورمز موجزين لمتطلبات حجم الحزمة التي تتقلص باستمرار
- الطلب على تجارب المستخدم المعقدة بشكل متزايد من خلال الرسوم المتحركة عالية الدقة والتحديثات في الوقت الفعلي
(إعادة) ظهور آلات الحالة المحدودة ومخططات الدولة
تم استخدام آلات الحالة المحدودة على نطاق واسع لتطوير البرامج في بعض الصناعات حيث تكون قوة التطبيق أمرًا بالغ الأهمية مثل الطيران والتمويل. كما أنها تكتسب شعبية متزايدة لتطوير الواجهة الأمامية لتطبيقات الويب من خلال ، على سبيل المثال ، مكتبة XState الممتازة.
تعرف ويكيبيديا آلة الحالة المحدودة على النحو التالي:
آلة مجردة يمكن أن تكون في حالة واحدة بالضبط من عدد محدود من الحالات في أي وقت. يمكن أن تتغير ولايات ميكرونيزيا الموحدة من حالة إلى أخرى استجابة لبعض المدخلات الخارجية ؛ التغيير من حالة إلى أخرى يسمى الانتقال. تُعرَّف ولايات ميكرونيزيا الموحدة بقائمة من حالاتها وحالتها الأولية وشروط كل انتقال.
و كذلك:
الحالة هي وصف لحالة النظام الذي ينتظر تنفيذ انتقال.
لا تتوافق ولايات ميكرونيزيا الموحدة في شكلها الأساسي جيدًا مع الأنظمة الكبيرة بسبب مشكلة انفجار الحالة. في الآونة الأخيرة ، تم إنشاء مخططات الحالة في UML لتوسيع ولايات ميكرونيزيا الموحدة مع التسلسل الهرمي والتزامن ، والتي تعد عوامل تمكينية للاستخدام الواسع لل ولايات ميكرونيزيا الموحدة في التطبيقات التجارية.

قم بتعريف منطق التطبيق الخاص بك
أولاً ، كيف تبدو ولايات ميكرونيزيا الموحدة كرمز؟ هناك العديد من الطرق التي يمكنك اتباعها لتنفيذ آلة الحالة المحدودة في JavaScript.
- آلة الحالة المحدودة باعتبارها بيان تبديل
إليك آلة تصف الحالات المحتملة التي يمكن أن تكون فيها JavaScript ، ويتم تنفيذها باستخدام تعليمة switch:
const initialState = { type: 'idle', error: undefined, result: undefined }; function transition(state = initialState, action) { switch (action) { case 'invoke': return { type: 'pending' }; case 'resolve': return { type: 'completed', result: action.value }; case 'error': return { type: 'completed', error: action.error ; default: return state; } }
سيكون هذا النمط من التعليمات البرمجية مألوفًا للمطورين الذين استخدموا مكتبة إدارة حالة Redux الشهيرة.
- آلة الحالة المحدودة ككائن JavaScript
إليك نفس الجهاز الذي تم تنفيذه ككائن JavaScript باستخدام مكتبة JavaScript XState:
const promiseMachine = Machine({ id: "promise", initial: "idle", context: { result: undefined, error: undefined, }, states: { idle: { on: { INVOKE: "pending", }, }, pending: { on: { RESOLVE: "success", REJECT: "failure", }, }, success: { type: "final", actions: assign({ result: (context, event) => event.data, }), }, failure: { type: "final", actions: assign({ error: (context, event) => event.data, }), }, }, });
على الرغم من أن إصدار XState أقل ضغطًا ، إلا أن تمثيل الكائن له مزايا عديدة:
- آلة الحالة نفسها هي JSON بسيطة ، والتي يمكن أن تستمر بسهولة.
- نظرًا لأنه إعلاني ، يمكن تصور الآلة.
- في حالة استخدام TypeScript ، يتحقق المترجم من إجراء انتقالات الحالة الصالحة فقط.
تدعم XState مخططات الحالة وتنفذ مواصفات SCXML ، مما يجعلها مناسبة للاستخدام في التطبيقات الكبيرة جدًا.
تصور مخططات الحالة للوعد:
أفضل ممارسات XState
فيما يلي بعض أفضل الممارسات التي يجب تطبيقها عند استخدام XState للمساعدة في الحفاظ على المشروعات قابلة للصيانة.
افصل الآثار الجانبية عن المنطق
يسمح XState بتحديد الآثار الجانبية (التي تتضمن أنشطة مثل التسجيل أو طلبات واجهة برمجة التطبيقات) بشكل مستقل عن منطق جهاز الحالة.
هذا له الفوائد التالية:
- المساعدة في اكتشاف الأخطاء المنطقية عن طريق الحفاظ على رمز آلة الحالة نظيفًا وبسيطًا قدر الإمكان.
- تصور بسهولة آلة الحالة دون الحاجة إلى إزالة القوالب الإضافية أولاً.
- أسهل اختبار لجهاز الدولة عن طريق حقن خدمات وهمية.
const fetchUsersMachine = Machine({ id: "fetchUsers", initial: "idle", context: { users: undefined, error: undefined, nextPage: 0, }, states: { idle: { on: { FETCH: "fetching", }, }, fetching: { invoke: { src: (context) => fetch(`url/to/users?page=${context.nextPage}`).then((response) => response.json() ), onDone: { target: "success", actions: assign({ users: (context, event) => [...context.users, ...event.data], // Data holds the newly fetched users nextPage: (context) => context.nextPage + 1, }), }, onError: { target: "failure", error: (_, event) => event.data, // Data holds the error }, }, }, // success state.. // failure state.. }, });
في حين أنه من المغري كتابة آلات الحالة بهذه الطريقة بينما لا تزال تعمل على عمل الأشياء ، يتم تحقيق فصل أفضل للمخاوف من خلال تمرير الآثار الجانبية كخيارات:
const services = { getUsers: (context) => fetch( `url/to/users?page=${context.nextPage}` ).then((response) => response.json()) } const fetchUsersMachine = Machine({ ... states: { ... fetching: { invoke: { // Invoke the side effect at key: 'getUsers' in the supplied services object. src: 'getUsers', } on: { RESOLVE: "success", REJECT: "failure", }, }, ... }, // Supply the side effects to be executed on state transitions. { services } });
يسمح هذا أيضًا باختبار الوحدة بسهولة لجهاز الحالة ، مما يسمح بالسخرية الصريحة من عمليات جلب المستخدم:
async function testFetchUsers() { return [{ name: "Peter", location: "New Zealand" }]; } const machine = fetchUsersMachine.withConfig({ services: { getUsers: (context) => testFetchUsers(), }, });
تقسيم الآلات الكبيرة
ليس من الواضح دائمًا على الفور أفضل طريقة لبناء مجال مشكلة في تسلسل هرمي جيد لآلة الحالة المحدودة عند البدء.
نصيحة: استخدم التسلسل الهرمي لمكونات واجهة المستخدم للمساعدة في توجيه هذه العملية. راجع القسم التالي حول كيفية تعيين أجهزة الحالة لمكونات واجهة المستخدم.
تتمثل إحدى الفوائد الرئيسية لاستخدام آلات الحالة في وضع نماذج صريحة لجميع الحالات والانتقالات بين الحالات في تطبيقاتك بحيث يتم فهم السلوك الناتج بوضوح ، مما يجعل اكتشاف الأخطاء المنطقية أو الفجوات أمرًا سهلاً.
لكي يعمل هذا بشكل جيد ، يجب أن تكون الآلات صغيرة وموجزة. لحسن الحظ ، فإن تأليف آلات الحالة بشكل هرمي أمر سهل. في مثال مخططات الحالة المتعارف عليها لنظام إشارات المرور ، تصبح الحالة "الحمراء" نفسها آلة حالة تابعة. الجهاز "الخفيف" الأصل ليس على دراية بالحالات الداخلية لـ "أحمر" ولكنه يقرر متى تدخل "أحمر" وما هو السلوك المقصود عند الخروج:
1-1 تعيين أجهزة الحالة لمكونات واجهة المستخدم ذات الحالة
خذ ، على سبيل المثال ، موقعًا خياليًا للتجارة الإلكترونية مبسطًا إلى حد كبير يحتوي على طرق عرض React التالية:
<App> <SigninForm /> <RegistrationForm /> <Products /> <Cart /> <Admin> <Users /> <Products /> </Admin> </App>
قد تكون عملية إنشاء آلات الحالة التي تتوافق مع العروض المذكورة أعلاه مألوفة لأولئك الذين استخدموا مكتبة إدارة حالة Redux:
- هل يحتوي المكون على حالة يحتاج إلى نمذجة؟ على سبيل المثال ، لا يجوز للمسؤول / المنتجات ؛ قد تكون عمليات الجلب المقسمة إلى الخادم بالإضافة إلى حل التخزين المؤقت (مثل SWR) كافية. من ناحية أخرى ، عادةً ما تحتوي مكونات مثل SignInForm أو Cart على حالة يجب إدارتها ، مثل البيانات التي يتم إدخالها في الحقول أو محتويات سلة التسوق الحالية.
- هل تقنيات الحالة المحلية (على سبيل المثال ،
setState() / useState()
) كافية لالتقاط المشكلة؟ لا يتطلب تتبع ما إذا كان النموذج المنبثق للعربة مفتوحًا حاليًا استخدام آلة ذات حالة محدودة. - هل من المحتمل أن تكون آلة الحالة الناتجة معقدة للغاية؟ إذا كان الأمر كذلك ، قسّم الآلة إلى عدة آلات أصغر ، مع تحديد الفرص لإنشاء آلات فرعية يمكن إعادة استخدامها في مكان آخر. على سبيل المثال ، قد تستدعي أجهزة SignInForm و RegistrationForm مثيلات textFieldMachine التابع لنموذج التحقق من صحة النموذج وحقول البريد الإلكتروني للمستخدم والاسم وكلمة المرور.
متى يجب استخدام نموذج آلة الحالة المحدودة
في حين أن مخططات الحالة و FSMs يمكنها حل بعض المشاكل الصعبة بأناقة ، فإن تحديد أفضل الأدوات والأساليب لاستخدامها في تطبيق معين يعتمد عادة على عدة عوامل.
بعض المواقف التي يتألق فيها استخدام آلات الحالة المحدودة:
- يتضمن التطبيق الخاص بك مكونًا كبيرًا لإدخال البيانات حيث يخضع الوصول إلى الحقل أو الرؤية لقواعد معقدة: على سبيل المثال ، إدخال النموذج في تطبيق مطالبات التأمين. هنا ، تساعد ولايات ميكرونيزيا الموحدة على ضمان تنفيذ قواعد العمل بشكل صارم. علاوة على ذلك ، يمكن استخدام ميزات التصور لمخططات الحالة للمساعدة في زيادة التعاون مع أصحاب المصلحة غير التقنيين وتحديد متطلبات العمل التفصيلية في وقت مبكر من التطوير.
- للعمل بشكل أفضل على اتصالات أبطأ وتقديم تجارب عالية الدقة للمستخدمين ، يجب أن تدير تطبيقات الويب تدفقات البيانات غير المتزامنة المتزايدة التعقيد. نماذج FSM صراحة لجميع الحالات التي يمكن أن يكون فيها التطبيق ، ويمكن تصور مخططات الحالة للمساعدة في تشخيص مشاكل البيانات غير المتزامنة وحلها.
- التطبيقات التي تتطلب الكثير من الرسوم المتحركة المعقدة القائمة على الدولة. بالنسبة للرسوم المتحركة المعقدة ، فإن تقنيات نمذجة الرسوم المتحركة كتدفقات الأحداث عبر الوقت باستخدام RxJS شائعة. بالنسبة للعديد من السيناريوهات ، يعمل هذا بشكل جيد ، ومع ذلك ، عندما يتم دمج الرسوم المتحركة الغنية مع سلسلة معقدة من الحالات المعروفة ، توفر FSMs "نقاط راحة" محددة جيدًا تتدفق الرسوم المتحركة بينها. تبدو FSMs جنبًا إلى جنب مع RxJS مزيجًا مثاليًا للمساعدة في تقديم الموجة التالية من تجارب المستخدم التعبيرية عالية الدقة.
- تطبيقات العميل الغنية مثل تحرير الصور أو الفيديو أو أدوات إنشاء المخططات أو الألعاب حيث يوجد الكثير من منطق الأعمال في جانب العميل. يتم فصل FSMs بطبيعتها عن إطار عمل أو مكتبات واجهة المستخدم ويسهل كتابة الاختبارات للسماح بتكرار التطبيقات عالية الجودة بسرعة وشحنها بثقة.
المحاذير المتعلقة بآلة الحالة المحدودة
- يعتبر النهج العام وأفضل الممارسات وواجهة برمجة التطبيقات لمكتبات statechart مثل XState جديدًا لمعظم مطوري الواجهة الأمامية ، الذين سيتطلبون استثمار الوقت والموارد من أجل أن يصبحوا منتجين ، خاصة بالنسبة للفرق الأقل خبرة.
- على غرار التحذير السابق ، بينما تستمر شعبية XState في النمو وموثقة جيدًا ، فإن مكتبات إدارة الدولة الحالية مثل Redux أو MobX أو React Context لديها متابعون هائلون يوفرون ثروة من المعلومات عبر الإنترنت لم تتطابق XState بعد.
- بالنسبة للتطبيقات التي تتبع نموذج CRUD أبسط ، فإن تقنيات إدارة الحالة الحالية جنبًا إلى جنب مع مكتبة تخزين موارد جيدة مثل SWR أو React Query ستكون كافية. هنا ، قد تؤدي القيود الإضافية التي توفرها FSM ، في حين أنها مفيدة بشكل لا يصدق في التطبيقات المعقدة ، إلى إبطاء عملية التطوير.
- الأدوات أقل نضجًا من مكتبات إدارة الحالة الأخرى ، مع استمرار العمل على تحسين دعم TypeScript وامتدادات أدوات تطوير المتصفح.
تغليف
تستمر شعبية البرمجة التصريحية واعتمادها في مجتمع تطوير الويب في الارتفاع.
بينما يستمر تطوير الويب الحديث في أن يصبح أكثر تعقيدًا ، تظهر المكتبات والأطر التي تتبنى مناهج البرمجة التصريحية بوتيرة متزايدة. يبدو السبب واضحًا - يجب إنشاء مناهج أبسط وأكثر وصفًا لكتابة البرامج.
يتيح استخدام اللغات المكتوبة بقوة مثل TypeScript للكيانات في مجال التطبيق أن تكون نموذجية بإيجاز وصريح ، مما يقلل من فرصة الأخطاء ومقدار كود التحقق المعرض للخطأ الذي يحتاج إلى التلاعب. يسمح اعتماد آلات الحالة المحدودة ومخططات الحالة في الواجهة الأمامية للمطورين بالإعلان عن منطق عمل التطبيق من خلال انتقالات الحالة ، مما يتيح تطوير أدوات تصور ثرية وزيادة فرصة التعاون الوثيق مع غير المطورين.
عندما نقوم بذلك ، فإننا نحول تركيزنا من الصواميل والمسامير حول كيفية عمل التطبيق إلى عرض مستوى أعلى يسمح لنا بالتركيز بشكل أكبر على احتياجات العميل وخلق قيمة دائمة.