1. ما هو نمط الحالة
نمط الحالة هو نوع من أنماط التصميم السلوكي المستخدم لحل مشكلة سلوك مختلف لكائن في حالات مختلفة. يقوم بتجميع سلوك الكائن في فئات حالة مختلفة، مما يسمح للكائن بتغيير سلوكه أثناء التشغيل استنادًا إلى التغيرات في حالته الداخلية.
2. السمات والمزايا لنمط الحالة
السمات والمزايا الرئيسية لنمط الحالة كما يلي:
- يجمع منطق اتخاذ القرارات للحالة المعقدة في فئات حالة مختلفة، مما يعزز صيانة الشفرة.
- مبدأ الافتح/أغلق: من خلال إضافة فئات حالة جديدة، يمكن بسهولة إضافة حالات جديدة.
- كل فئة حالة مستقلة عن الأخرى، وتعديل إحدى فئات الحالة لن يؤثر على شفرة الفئات الأخرى.
- يبسط منطق البيانات الشرطية، ويحسن قراءة الشفرة وتوسعها.
3. أمثلة على التطبيقات العملية لنمط الحالة
يحتوي نمط الحالة على العديد من التطبيقات العملية في الحياة الحقيقية، مثل:
- أضواء إشارات المرور: يتم إرسال إشارات ضوئية مختلفة من خلال إشارات المرور استنادًا إلى حالات مختلفة.
- إدارة حالة الطلب: يحتوي الطلب على عمليات وسلوكيات مختلفة في حالات مختلفة، مثل المدفوعة والمشحونة والمستلمة.
4. تنفيذ نمط الحالة في Golang
4.1 الرسم البياني لفئات UML
4.2 مقدمة إلى المثال
في هذا المثال، سنقوم بتنفيذ نظام بسيط لإدارة حالة الطلب. يحتوي الطلب على حالات متعددة، مثل المدفوعة والمشحونة والمستلمة. استنادًا إلى حالات مختلفة، يحتوي الطلب على عمليات وسلوكيات مختلفة.
4.3 عرض حالة التنفيذ
4.3.1 تعريف واجهة حالة الطلب وفئات الحالة المحددة
// واجهة الحالة
type State interface {
Handle(context *Context)
}
// فئة الحالة المحددة A
type ConcreteStateA struct {
name string
}
func (c *ConcreteStateA) Handle(context *Context) {
fmt.Println("الحالة الحالية هي:", c.name)
fmt.Println("تنفيذ العملية المحددة للحالة A...")
context.SetState(&ConcreteStateB{name: "حالة B المحددة"})
}
// فئة الحالة المحددة B
type ConcreteStateB struct {
name string
}
func (c *ConcreteStateB) Handle(context *Context) {
fmt.Println("الحالة الحالية هي:", c.name)
fmt.Println("تنفيذ العملية المحددة للحالة B...")
context.SetState(&ConcreteStateA{name: "حالة A المحددة"})
}
4.3.2 تعريف فئة سياق الطلب وأساليب تبديل الحالة
// فئة السياق
type Context struct {
state State
}
// معالجة الطلب
func (c *Context) Handle() {
c.state.Handle(c)
}
// تعيين الحالة
func (c *Context) SetState(state State) {
c.state = state
}
4.3.3 تنفيذ أساليب تبديل الحالة لفئات الحالة المحددة
// طريقة التبديل لفئة الحالة المحددة A
func (c *ConcreteStateA) SwitchStateB(context *Context) {
context.SetState(&ConcreteStateB{name: "حالة B المحددة"})
}
// طريقة التبديل لفئة الحالة المحددة B
func (c *ConcreteStateB) SwitchStateA(context *Context) {
context.SetState(&ConcreteStateA{name: "حالة A المحدة"})
}
4.3.4 إدارة حالة الطلب باستخدام نمط الحالة
func main() {
// تهيئة سياق الطلب
context := &Context{
state: &ConcreteStateA{name: "حالة A المحدة"},
}
// معالجة الطلب
context.Handle()
// تبديل الحالة
context.state.(*ConcreteStateA).SwitchStateB(context) // التبديل إلى حالة B المحددة
context.Handle()
context.state.(*ConcreteStateB).SwitchStateA(context) // التبديل إلى حالة A المحددة مرة أخرى
context.Handle()
}
التوصيخ
من خلال استخدام نمط الحالة، يمكننا إدارة سلوك الكائن في حالات مختلفة بشكل أفضل، مما يحسن من إعادة استخدام الشفرة وقابلية التوسع. في هذا البرنامج التعليمي، قدمنا كيفية استخدام Golang لتنفيذ نمط الحالة باستخدام نظام بسيط لإدارة الطلب وقدمنا تنفيذًا كاملاً للشفرة ورسم بياني لفئات UML. نأمل أن يساعدك هذا البرنامج التعليمي في فهم وتطبيق نمط الحالة بشكل أفضل.