---
title: "تكرار البيانات المرصودة"
type: "refactoring-technique"
slug: "duplicate-observed-data"
url: "http://localhost:3000/ar/duplicate-observed-data.md"
category: "تنظيم البيانات"
description: "المشكلة: هل يتم تخزين بيانات النطاق (domain data) في فئات مسؤولة عن واجهة المستخدم الرسومية (GUI)؟ الحل: إذن فمن الجيد فصل البيانات في فئات منفصلة، مع ضمان الاتصال والمزامنة بين فئة النطاق وواجهة المستخدم الرسومية."
---
# تكرار البيانات المرصودة

> المشكلة: هل يتم تخزين بيانات النطاق (domain data) في فئات مسؤولة عن واجهة المستخدم الرسومية (GUI)؟ الحل: إذن فمن الجيد فصل البيانات في فئات منفصلة، مع ضمان الاتصال والمزامنة بين فئة النطاق وواجهة المستخدم الرسومية.

## المشكلة

هل يتم تخزين بيانات النطاق في فئات مسؤولة عن واجهة المستخدم الرسومية؟

## الحل

إذن فمن الجيد فصل البيانات في فئات منفصلة، مع ضمان الاتصال والمزامنة بين فئة النطاق وواجهة المستخدم الرسومية.

## دواعي إعادة الهيكلة

تريد الحصول على طرق عرض متعددة لواجهة المستخدم لنفس البيانات (على سبيل المثال، لديك تطبيق سطح مكتب وتطبيق للهاتف المحمول). إذا فشلت في فصل واجهة المستخدم الرسومية عن النقاط، فستواجه صعوبة بالغة في تجنب تكرار الكود والعديد من الأخطاء.

## الفوائد

* تقوم بتقسيم المسؤولية بين فئات منطق العمل (business logic) وفئات العرض (presentation) (قارن مع _مبدأ المسؤولية الفردية_)، مما يجعل برنامجك أكثر وضوحاً وفهماً.
* إذا كنت بحاجة إلى إضافة واجهة عرض جديدة، فستنشئ فئات عرض جديدة؛ ولا تحتاج إلى تعديل كود منطق العمل (قارن مع _مبدأ المفتوح/المغلق_).
* الآن يمكن لأشخاص مختلفين العمل على منطق العمل وواجهات المستخدم بشكل مستقل.

## كيفية إعادة الهيكلة

1. أخفِ الوصول المباشر إلى بيانات النطاق في _فئة واجهة المستخدم الرسومية_. لهذا، من الأفضل استخدام طريقة [التغليف الذاتي للحقل](/self-encapsulate-field). وبالتالي تقوم بإنشاء دوال الحصول والتعيين (getters and setters) لهذه البيانات.
2. في معالجات أحداث _فئة واجهة المستخدم الرسومية_، استخدم دوال التعيين لتعيين قيم الحقول الجديدة. سيسمح لك هذا بتمرير هذه القيم إلى _كائن النطاق_ المرتبط.
3. أنشئ فئة نطاق وانسخ الحقول اللازمة من _فئة واجهة المستخدم الرسومية_ إليها. أنشئ دوال الحصول والتعيين لكل هذه الحقول.
4. أنشئ نمط المراقب (Observer pattern) لهاتين الفئتين:

  * في _فئة النطاق_، أنشئ مصفوفة لتخزين كائنات المراقب (كائنات واجهة المستخدم الرسومية)، بالإضافة إلى دوال لتسجيلها وحذفها وإشعارها.
  * في _فئة واجهة المستخدم الرسومية_، أنشئ حقلاً لتخزين المراجع إلى _فئة النطاق_ بالإضافة إلى دالة `update()`، والتي ستستجيب للتغييرات في الكائن وتحدث قيم الحقول في _فئة واجهة المستخدم الرسومية_. لاحظ أنه يجب تعيين تحديثات القيم مباشرة في الدالة لتجنب التكرار اللانهائي (recursion).
  * في منشئ _فئة واجهة المستخدم الرسومية_، أنشئ نسخة من _فئة النطاق_ واحفظها في الحقل الذي أنشأته. سجل _كائن واجهة المستخدم الرسومية_ كمراقب في _كائن النطاق_.
  * في دوال التعيين لحقول _فئة النطاق_، استدعِ دالة إشعار المراقب (بمعنى آخر، دالة التحديث في _فئة واجهة المستخدم الرسومية_) لتمرير القيم الجديدة إلى واجهة المستخدم الرسومية.
  * قم بتغيير دوال التعيين لحقول _فئة واجهة المستخدم الرسومية_ بحيث تقوم بتعيين القيم الجديدة في كائن النطاق مباشرة. تأكد من عدم تعيين القيم عبر دالة تعيين _فئة النطاق_—وإلا فسيؤدي ذلك إلى تكرار لانهائي.
## Relations

**Eliminates smells**

- [الكلاس الضخمة](/ar/smells/large-class.md)

