يقدم
يتيح وضع الحالة للكائن تغيير سلوكه عندما يتغير حالته الداخلية ، ويبدو أن الكائن يعدل فئته.
نص
على سبيل المثال ، عندما نقوم بتنزيل الأشياء ، عادة ما يكون لدينا عدة حالات ، مثل ReadyState و DownloadingState و PuusseState و DownloadState و DownloadState و SavorState. وهذا يعني ، في كل ولاية ، يمكنك فقط فعل ما يمكن أن تفعله الحالة الحالية ، ولكن ليس ما يمكن أن تفعله الدول الأخرى.
لأن نمط الحالة يصف كيف يتصرف التنزيلات (التنزيل) بشكل مختلف في كل ولاية. الفكرة الرئيسية لهذا النمط هي تقديم فئة مجردة تسمى الحالة (أو وظيفة في JS) لتمثيل حالة التنزيل. تعلن وظيفة الحالة (كنموذج أولي) عن بعض الواجهات الشائعة للفئات الفرعية (وظائف الميراث) لكل ولاية. كل وظيفة الميراث تنفذ السلوكيات المتعلقة بحالة معينة ، مثل تنزيل وتنزيل state على التوالي تنزيل السلوكيات التي يتم تنزيلها وتنزيلها. يمكن الحفاظ على هذه السلوكيات من خلال التنزيل.
دعنا ننفذ لعبة ، أولاً ، حدد وظيفة الحالة كنموذج أولي للوظائف الأساسية الأخرى:
نسخة الكود كما يلي:
var state = function () {
} ؛
state.prototype.download = function () {
رمي خطأ جديد ("يجب أن تكون هذه الطريقة مثقلة!") ؛
} ؛
state.prototype.pause = function () {
رمي خطأ جديد ("يجب أن تكون هذه الطريقة مثقلة!") ؛
} ؛
state.prototype.fail = function () {
رمي خطأ جديد ("يجب أن تكون هذه الطريقة مثقلة!") ؛
} ؛
state.prototype.finish = function () {
رمي خطأ جديد ("يجب أن تكون هذه الطريقة مثقلة!") ؛
} ؛
نحدد 4 واجهات طريقة للنموذج الأولي للحالة ، والتي تتوافق مع التنزيل (التنزيل) ، وقفة ، وفشل ، ونهاية بحيث يمكن إعادة كتابة الوظيفة الفرعية.
قبل كتابة وظائف فرعية ، نكتب أولاً وظيفة ReadyState بحيث يمكن نقل الحالة إلى حالة التنزيل الأولى:
نسخة الكود كما يلي:
var readyState = function (Odownload) {
state.apply (هذا) ؛
this.odownload = odownload ؛
} ؛
ReadyState.Prototype = New State () ؛
ReadyState.Prototype.Download = function () {
this.odownload.setState (this.odownload.getDownloadingState ()) ؛
// بعد جاهزة ، يمكنك البدء في التنزيل ، لذلك يمكنك تعيين طريقة اكتساب الحالة في وظيفة التنزيل
console.log ("ابدأ التنزيل!") ؛
} ؛
ReadyState.Prototype.pause = function () {
رمي خطأ جديد ("التنزيل لم يبدأ بعد ، لا يمكن إيقافه مؤقتًا!") ؛
} ؛
ReadyState.Prototype.fail = function () {
رمي خطأ جديد ("لم يبدأ الملف في التنزيل بعد ، كيف يمكن القول أنه فشل!") ؛
} ؛
ReadyState.Prototype.finish = function () {
رمي خطأ جديد ("لم يبدأ الملف في التنزيل ، بالطبع لا يمكن الانتهاء منه!") ؛
} ؛
تأخذ هذه الوظيفة مثيلًا لوظيفة صيانة التنزيل كمعلمة. يتم استخدام وظيفة التنزيل للتحكم في تغييرات الحالة والاستحواذ (على غرار وحدة التحكم المركزية ، مما يسمح بالمكالمات الخارجية). ReadyState يعيد كتابة طريقة تنزيل النموذج الأولي لبدء التنزيل. دعنا نستمر في النظر إلى الوظائف الرئيسية لوظيفة التنزيل:
نسخة الكود كما يلي:
var download = function () {
this.ostate = جديد readyState (هذا) ؛
} ؛
download.prototype.setState = function (ostate) {
this.ostate = ostate ؛
} ؛
// أربع طرق عامة تتعرض للخارج للمكالمات الخارجية
download.prototype.download = function () {
this.ostate.download () ؛
} ؛
download.prototype.pause = function () {
this.ostate.pause () ؛
} ؛
download.prototype.fail = function () {
this.ostate.fail () ؛
} ؛
download.prototype.finish = function () {
this.ostate.finish () ؛
} ؛
// احصل على مختلف الحالات وقم بتمرير هذا الكائن الحالي
download.prototype.getReadyState = function () {
إرجاع New ReadyState (هذا) ؛
} ؛
download.prototype.getDownloadingState = function () {
إرجاع جديد تنزيل (هذا) ؛
} ؛
download.prototype.getDownloadPausedState = function () {
إرجاع تنزيل جديد pausedState (هذا) ؛
} ؛
download.prototype.getDownloadedState = function () {
إرجاع جديد تنزيل (هذا) ؛
} ؛
download.prototype.getDownloadedFailedState = function () {
إرجاع جديد تنزيل FailedState (هذا) ؛
} ؛
يوفر النموذج الأولي لوظيفة التنزيل 8 طرق ، 4 هي سلوكيات تشغيلية لتنزيل الحالات ، ويتم استخدام الـ 4 الأخرى للحصول على الحالات الأربع المختلفة الحالية. تتلقى هذه الأساليب الأربعة هذه كمعلمة ، أي تمرير مثيل التنزيل نفسه كمعلمة إلى كائن الحالة (ReadyState ووظيفة الميراث المراد تنفيذه لاحقًا) ، مما يجعل كائن الحالة متاحًا إلى Odownlaod مما إذا لزم الأمر.
بعد ذلك ، استمر في تحديد 4 وظائف الحالة ذات الصلة:
نسخة الكود كما يلي:
var downloadingState = function (Odownload) {
state.apply (هذا) ؛
this.odownload = odownload ؛
} ؛
downloadingState.Prototype = new State () ؛
downloadingState.Prototype.Download = function () {
رمي خطأ جديد ("الملف يتم تنزيله بالفعل!") ؛
} ؛
DownloadingState.Prototype.pause = function () {this.odownload.setState (this.odownload.getDownloadPausedState ()) ؛
console.log ("تنزيل إيقاف التشغيل!") ؛
} ؛
DownloadingState.Prototype.fail = function () {this.odownload.setState (this.odownload.getDownloadedFailedState ()) ؛
console.log ("فشل التنزيل!") ؛
} ؛
تنزيل state.prototype.finish = function () {
this.odownload.setState (this.odownload.getDownloadedState ()) ؛
console.log ("تنزيل!") ؛
} ؛
الشيء الرئيسي الذي يجب ملاحظته حول التنزيل هو أنه لا يمكن تنزيل الملف الذي يتم تنزيله بالفعل مرة أخرى ، ويمكن تنفيذ حالات أخرى بشكل مستمر.
نسخة الكود كما يلي:
var downloadPausedState = function (Odownload) {
state.apply (هذا) ؛
this.odownload = odownload ؛
} ؛
downloadPausedState.Prototype = new State () ؛
downloadPausedState.Prototype.Download = function () {
this.odownload.setState (this.odownload.getDownloadingState ()) ؛
console.log ("تابع التنزيل!") ؛
} ؛
downloadPausedState.prototype.pause = function () {
رمي خطأ جديد ("لقد تم إيقافه مؤقتًا ، لماذا لا يزال يتعين عليك التوقف!") ؛
} ؛
downloadPausedState.Prototype.fail = function () {this.odownload.setState (this.odownload.getDownloadedFailedState ()) ؛
console.log ("فشل التنزيل!") ؛
} ؛
downloadPausedState.prototype.finish = function () {
this.odownload.setState (this.odownload.getDownloadedState ()) ؛
console.log ("تنزيل!") ؛
} ؛
تجدر الإشارة إلى وظيفة التنزيل التي تم إيقاف تشغيلها مرة أخرى.
نسخة الكود كما يلي:
var downloadState = function (Odownload) {
state.apply (هذا) ؛
this.odownload = odownload ؛
} ؛
تنزيل state.prototype = new state () ؛
تنزيل state.prototype.download = function () {
this.odownload.setState (this.odownload.getDownloadingState ()) ؛
console.log ("إعادة التنزيل!") ؛
} ؛
تنزيل state.prototype.pause = function () {
رمي خطأ جديد ("ماذا ستتوقف مؤقتًا بعد التنزيل؟") ؛
} ؛
تنزيل state.prototype.fail = function () {
رمي خطأ جديد ("لقد كان التنزيل ناجحًا ، لماذا سيفشل؟") ؛
} ؛
تنزيل state.prototype.finish = function () {
رمي خطأ جديد ("التنزيل ناجح ، لا يمكنك القيام بذلك بعد الآن!") ؛
} ؛
وظيفة تنزيلها ، وبالمثل ، بعد التنزيل الناجح ، لم يعد بإمكانك تعيين الانتهاء ، يمكنك فقط تعيين حالة إعادة التنزيل.
نسخة الكود كما يلي:
var downloadFailedState = function (Odownload) {
state.apply (هذا) ؛
this.odownload = odownload ؛
} ؛
downloadFailedState.Prototype = new State () ؛
downloadFailedState.Prototype.Download = function () {
this.odownload.setState (this.odownload.getDownloadingState ()) ؛
console.log ("حاول إعادة التنزيل!") ؛
} ؛
downloadFailedState.prototype.pause = function () {
رمي خطأ جديد ("لا يمكن إيقاف التنزيل الفاشل!") ؛
} ؛
downloadFailedState.prototype.fail = function () {
رمي خطأ جديد ("كل شيء فشل ، لماذا لا يزال فشل!") ؛
} ؛
downloadFailedState.prototype.finish = function () {
رمي خطأ جديد ("التنزيل الفاشل لن ينجح بالتأكيد!") ؛
} ؛
وبالمثل ، لا يمكن أن تفشل حالة فشل وظيفة التنزيل FailedState مرة أخرى ، ولكن يمكنك محاولة تنزيلها مرة أخرى بعد الانتهاء.
استدعاء رمز الاختبار بسيط للغاية. دعونا نوضح ذلك في HTML. أولاً ، تحتاج إلى jQuery ، ثم هناك 3 أزرار تمثل: ابدأ التنزيل ، وقفة ، وإعادة تنزيل. (لاحظ أنك تستخدم Firebug لعرض النتائج في Firefox ، لأنه يتم استخدام طريقة console.log).
نسخة الكود كما يلي:
<html>
<head>
<link type = "text/css" rel = "stylesheet" href = "http://www.cnblogs.com/css/style.css"/>
<title> نمط الحالة </title>
<script type = "text/javaScript" src = "/jQuery.js"> </script>
<script type = "text/javaScript" src = "download.js"> </script>
<script type = "text/javaScript" src = "states/state.js"> </script>
<script type = "text/javaScript" src = "states/downloadFailedState.js"> </script>
<script type = "text/javaScript" src = "states/downloadPausedState.js"> </script>
<script type = "text/javaScript" src = "states/downloadState.js"> </script>
<script type = "text/javaScript" src = "states/downloadingState.js"> </script>
<script type = "text/javaScript" src = "states/reasyState.js"> </script>
</head>
<body>
<type type = "button" value = "start download" id = "download_button" />
<type type = "button" value = "pause" id = "pause_button" />
<type type = "button" value = "re-download" id = "resume_button" />
<script type = "text/javaScript">
var odownload = new download () ؛
$ ("#download_button"). انقر فوق (function () {
Odownload.Download () ؛
}) ؛
$ ("#pause_button"). انقر فوق (function () {
odownload.pause () ؛
}) ؛
$ ("#resume_button"). انقر فوق (function () {
Odownload.Download () ؛
}) ؛
</script>
</body>
</html>
لخص
سيناريوهات الاستخدام لوضع الحالة واضحة أيضًا بشكل خاص ، مع النقطتين التاليتين:
1. يعتمد سلوك كائن ما على حالته ، ويجب أن يغير سلوكه وفقًا لحالته في وقت التشغيل.
2. تحتوي العملية على عدد كبير من عبارات الفرع ، وتعتمد هذه العبارات الفرعية على حالة الكائن. عادة ما تكون الدولة تمثيلًا لثوابت تعداد واحدة أو أكثر.