الفرق بين المراجعتين لصفحة: «Refactoring/encapsulate field»
Khaled-yassin (نقاش | مساهمات) ط ←مصادر |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(4 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE: تغليف الحقول (Encapsulate Field)}}</noinclude> | <noinclude>{{DISPLAYTITLE: تغليف الحقول (Encapsulate Field)}}</noinclude> | ||
== المشكلة == | == المشكلة == | ||
لديك حقل عام.<syntaxhighlight lang="java"> | لديك حقل عام. | ||
== الحل == | |||
جعل الحقل خاصًّا وإنشاء توابع وصول له. | |||
=== مثال === | |||
==== قبل إعادة التصميم ==== | |||
وجود الحقل العام <code>name</code> في الصنف <code>Person</code>: | |||
في لغة Java:<syntaxhighlight lang="java"> | |||
class Person { | class Person { | ||
public String name; | public String name; | ||
} | |||
</syntaxhighlight>في لغة C#:<syntaxhighlight lang="c#"> | |||
class Person | |||
{ | |||
public string name; | |||
} | |||
</syntaxhighlight>في لغة PHP:<syntaxhighlight lang="php"> | |||
public $name; | |||
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript"> | |||
class Person { | |||
name: string; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | ==== بعد إعادة التصميم ==== | ||
جعل الحقل | جعل الحقل <code>name</code> خاصًّا وإنشاء تابع جلب <code>getName</code> وضبط <code>setName</code> له: | ||
في لغة Java:<syntaxhighlight lang="java"> | |||
class Person { | class Person { | ||
private String name; | private String name; | ||
سطر 17: | سطر 40: | ||
public void setName(String arg) { | public void setName(String arg) { | ||
name = arg; | name = arg; | ||
} | |||
} | |||
</syntaxhighlight>في لغة C#:<syntaxhighlight lang="c#"> | |||
class Person | |||
{ | |||
private string name; | |||
public string Name | |||
{ | |||
get { return name; } | |||
set { name = value; } | |||
} | |||
} | |||
</syntaxhighlight>في لغة [[PHP]]:<syntaxhighlight lang="php"> | |||
private $name; | |||
public getName() { | |||
return $this->name; | |||
} | |||
public setName($arg) { | |||
$this->name = $arg; | |||
} | |||
</syntaxhighlight>في لغة TypeScript:<syntaxhighlight lang="typescript"> | |||
class Person { | |||
private _name: string; | |||
get name() { | |||
return this._name; | |||
} | |||
setName(arg: string): void { | |||
this._name = arg; | |||
} | } | ||
} | } | ||
سطر 22: | سطر 77: | ||
== لم إعادة التصميم؟ == | == لم إعادة التصميم؟ == | ||
يُعد التغليف (Encapsulation) واحدًا من ركائز البرمجة الكائنية، وهو القدرة على إخفاء بيانات الكائن. وإلا فإن جميع الكائنات ستكون عامة ويمكن للكائنات الأخرى الحصول على بيانات الكائن وتعديلها دون أي ضوابط وتوازنات! | يُعد التغليف (Encapsulation) واحدًا من ركائز البرمجة الكائنية، وهو القدرة على إخفاء بيانات الكائن. وإلا فإن جميع الكائنات ستكون عامة ويمكن للكائنات الأخرى الحصول على بيانات الكائن وتعديلها دون أي ضوابط وتوازنات! تُفصَل البيانات عن السلوكيات المرتبطة بهذه البيانات، وتتأثر قابلية تركيب أقسام البرنامج، وتصبح الصيانة مُعقَّدة. | ||
== فوائد تطبيق الحل == | == فوائد تطبيق الحل == | ||
سطر 28: | سطر 83: | ||
* يمكن أيضا تنفيذ عمليات معقدة تتعلق بالوصول إلى حقول الكائنات. | * يمكن أيضا تنفيذ عمليات معقدة تتعلق بالوصول إلى حقول الكائنات. | ||
== متى | == متى يترك هذا الحل؟ == | ||
* | * في بعض الحالات، يكون التغليف خيارًا سيئًا بسبب اعتبارات الأداء. هذه الحالات نادرة ولكن عندما تحدث، يصبح هذا الظرف مهم جدًا. | ||
لنفترض أنَّ لديك محرر رسوم يحتوي على كائنات تمتلك إحداثيات x- و y-. ومن غير المرجح أن تتغير هذه الحقول في المستقبل. أكثر من ذلك، ينطوي البرنامج علي مجموعة كبيرة من العديد من الكائنات المختلفة التي يوجد بها هذه الحقول. إذًا، الوصول إلى حقول الإحداثيات مباشرة يحفظ دورات وحدة المعالجة المركزية المهمة والتي يجب تناولها بطريقة أخرى عن طريق استدعاء توابع الوصول. | |||
كمثال على هذه الحالة غير العادية، | كمثال على هذه الحالة غير العادية، هنالك الصنف [http://docs.oracle.com/javase/7/docs/api/java/awt/Point.html Point] في جافا، إذ جميع الحقول من هذا الصنف عامة. | ||
== آلية الحل == | == آلية الحل == | ||
سطر 40: | سطر 95: | ||
== الخطوات التالية == | == الخطوات التالية == | ||
تغليف الحقل هو الخطوة الأولى فقط في جعل البيانات والسلوكيات التي تنطوي على هذه البيانات أقرب معًا. بعد إنشاء توابع بسيطة من أجل الوصول إلى الحقول، يجب إعادة فحص أماكن استدعاء هذه التوابع. ومن الممكن أن تبدو الشيفرة البرمجية في هذه المجالات أكثر | تغليف الحقل هو الخطوة الأولى فقط في جعل البيانات والسلوكيات التي تنطوي على هذه البيانات أقرب معًا. بعد إنشاء توابع بسيطة من أجل الوصول إلى الحقول، يجب إعادة فحص أماكن استدعاء هذه التوابع. ومن الممكن أن تبدو الشيفرة البرمجية في هذه المجالات أكثر ملاءمةً في توابع الوصول. | ||
== انظر أيضًا == | == انظر أيضًا == | ||
سطر 47: | سطر 102: | ||
== مصادر == | == مصادر == | ||
* [https://refactoring.guru/encapsulate-field صفحة توثيق تغليف الحقول في موقع refactoring.guru]. [[تصنيف:Refactoring]] [[تصنيف:Refactoring Techniques]] [[تصنيف:Refactoring Organizing Data]] | * [https://refactoring.guru/encapsulate-field صفحة توثيق تغليف الحقول في موقع refactoring.guru]. [[تصنيف:Refactoring]] [[تصنيف:Refactoring Techniques]] [[تصنيف:Refactoring Organizing Data]] |
المراجعة الحالية بتاريخ 10:50، 7 أكتوبر 2022
المشكلة
لديك حقل عام.
الحل
جعل الحقل خاصًّا وإنشاء توابع وصول له.
مثال
قبل إعادة التصميم
وجود الحقل العام name
في الصنف Person
:
في لغة Java:
class Person {
public String name;
}
في لغة C#:
class Person
{
public string name;
}
في لغة PHP:
public $name;
في لغة TypeScript:
class Person {
name: string;
}
بعد إعادة التصميم
جعل الحقل name
خاصًّا وإنشاء تابع جلب getName
وضبط setName
له:
في لغة Java:
class Person {
private String name;
public String getName() {
return name;
}
public void setName(String arg) {
name = arg;
}
}
في لغة C#:
class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
في لغة PHP:
private $name;
public getName() {
return $this->name;
}
public setName($arg) {
$this->name = $arg;
}
في لغة TypeScript:
class Person {
private _name: string;
get name() {
return this._name;
}
setName(arg: string): void {
this._name = arg;
}
}
لم إعادة التصميم؟
يُعد التغليف (Encapsulation) واحدًا من ركائز البرمجة الكائنية، وهو القدرة على إخفاء بيانات الكائن. وإلا فإن جميع الكائنات ستكون عامة ويمكن للكائنات الأخرى الحصول على بيانات الكائن وتعديلها دون أي ضوابط وتوازنات! تُفصَل البيانات عن السلوكيات المرتبطة بهذه البيانات، وتتأثر قابلية تركيب أقسام البرنامج، وتصبح الصيانة مُعقَّدة.
فوائد تطبيق الحل
- إذا كانت بيانات وسلوك مُكوِّن ما مترابطة بشكل وثيق وتكون في نفس المكان في الشيفرة البرمجية، فمن الأسهل بكثير الحفاظ علي هذا المُكوِّن وتطويره.
- يمكن أيضا تنفيذ عمليات معقدة تتعلق بالوصول إلى حقول الكائنات.
متى يترك هذا الحل؟
- في بعض الحالات، يكون التغليف خيارًا سيئًا بسبب اعتبارات الأداء. هذه الحالات نادرة ولكن عندما تحدث، يصبح هذا الظرف مهم جدًا.
لنفترض أنَّ لديك محرر رسوم يحتوي على كائنات تمتلك إحداثيات x- و y-. ومن غير المرجح أن تتغير هذه الحقول في المستقبل. أكثر من ذلك، ينطوي البرنامج علي مجموعة كبيرة من العديد من الكائنات المختلفة التي يوجد بها هذه الحقول. إذًا، الوصول إلى حقول الإحداثيات مباشرة يحفظ دورات وحدة المعالجة المركزية المهمة والتي يجب تناولها بطريقة أخرى عن طريق استدعاء توابع الوصول.
كمثال على هذه الحالة غير العادية، هنالك الصنف Point في جافا، إذ جميع الحقول من هذا الصنف عامة.
آلية الحل
- أنشئ مُتلقي وضابط للحقل.
- ابحث عن كافة استدعاءات الحقل. استبدل استلام قيمة الحقل بالمُتلقي، واستبدل إعدادات قيم الحقول الجديدة بالضابط.
- بعد استبدال كافة الاستدعاءات الحقل، اجعل الحقل خاصًا.
الخطوات التالية
تغليف الحقل هو الخطوة الأولى فقط في جعل البيانات والسلوكيات التي تنطوي على هذه البيانات أقرب معًا. بعد إنشاء توابع بسيطة من أجل الوصول إلى الحقول، يجب إعادة فحص أماكن استدعاء هذه التوابع. ومن الممكن أن تبدو الشيفرة البرمجية في هذه المجالات أكثر ملاءمةً في توابع الوصول.
انظر أيضًا
- عمليات مماثلة لإعادة التصميم: تغليف الحقول الداخلي (إنشاء مُتلقيات وضوابط لحقل بدلًا من الوصول المباشر داخل أصناف التوابع).
- إزالة اختلال الشيفرات: أصناف البيانات.