يجب أن أهتم أن يمر في فئة تمثيل XML ملف الإعدادات ينتهك القانون ديميتر?

StackOverflow https://stackoverflow.com/questions/3689118

سؤال

أنا باستخدام أداة لتوليد تلقائيا فئة التمثيل من تنظيم هرمي ملف XML.XML ملف هو ملف إعدادات التطبيق تحتاج إلى أن تكون قادرة على الوصول إلى (للقراءة فقط).

إذا كنت تمر في أعلى مستوى العقدة (على سبيل المثال ، AppSettings) إلى الدرجة التي تحتاج إلى الوصول إلى واحد أو أكثر من إعدادات يمكنني بسهولة في نهاية المطاف مع رمز التي تبدو شيئا مثل هذا:

var windowSize = AppSettings.Views.Windows.Dashboard.Size;

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

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

هل كانت مفيدة؟

المحلول

نعم ، يجب أن تهتم ، لسبب عملي للغاية!

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

تخيل في المستقبل أنك تريد دعم موضوعات متعددة لتطبيقك. لن ينتهي بك الأمر مع واحد ، ولكن العديد من الاحتمالات لحجم لوحة القيادة ، على سبيل المثال:

AppSettings.Views.ThemeA.Windows.Dashboard.Size;
AppSettings.Views.ThemeB.Windows.Dashboard.Size;

لا تزال فئة واجهة المستخدم الخاصة بك تحتاج إلى شيء واحد فقط ، وهي قيمة لنظام التشغيل Windowsize المتغير ، ولا تحتاج إلى معرفة السمة المستخدمة حاليًا.

هذا صحيح أينما كان لديك واجهة XML ، فأنت لا تريد أن تعتمد على المخطط في كل مكان في الكود الخاص بك ولكن في مكان مركزي واحد فقط.

على سبيل المثال ، يمكنك وضع الإعدادات في الخريطة لاستخدامها داخليًا ، مثل هذا:

public class SettingsReader {

    public static final String VIEW_WINDOW_DASHBOARD_SIZE = "Views.Windows.Dashboard.Size";

    private Map settings = new Hashmap();

    public SettingsReader(AppSettings appSettings) {
        settings.put(VIEW_WINDOW_DASHBOARD_SIZE, appSettings.Views.Windows.Dashboard.Size);
    }

    public String getSettingValue(String key) {
        return settings.get(key);
    }
}

ثم لديك مكان واحد فقط لإعادة صياغة لدعم موضوع ما ، مثل هذا:

public class SettingsReader {

    public static final String VIEW_WINDOW_DASHBOARD_SIZE = "Views.Windows.Dashboard.Size";

    private Map settings = new Hashmap();

    public SettingsReader(AppSettings appSettings, String theme) {
        settings.put(VIEW_WINDOW_DASHBOARD_SIZE, appSettings.Views + theme + Windows.Dashboard.Size);
    }

    public String getSettingValue(String key) {
        return settings.get(key);
    }
}

ملاحظة أخيرة ، لمجرد أن مزيج رمز الزائفة ورمز Java قد يخلط بين الناس ، وخاصة appSettings.Views + theme + Windows.Dashboard.Size: عند العمل مع واجهة XML ، عادة ما يكون XPath مفيدًا جدًا ، حتى عند العمل مع الكائنات بفضل المكتبة اللطيفة JXPath (بالنسبة لجافا ، لا أعرف لغات أخرى).

نصائح أخرى

إذا كنت بصق البكم البيانات ثم ليس هناك حقا أي طريقة أفضل للقيام بذلك.

أنا أميل إلى محاولة العمل نحو الحل حيث يمكنك دفع البوب السياقات ، على الرغم من.

PushContext(AppSettings)
  // do child contexts
  PushContext(Views)
    // more child contexts
    PushContext(Windows)
    // etc.
    PopContext()
  PopContext()
PopContext()

عادة المختلفة يدفع في وظائف مختلفة أو الملفات ولكن تظهر هنا من أجل التوضيح.بغض النظر إذا كنت تدفع في وجهات النظر السياق ثم كنت مجرد تحليل هذا كما لو كنت في جذور الكائن.

إذا كان هذا هو DumbData ، رغم ذلك ، يمكن أيضا تمرير نوع من الشيء الذي 'آراء' يمثل رمز أن يوزع ذلك.أعلى مستوى التعليمات البرمجية الخاصة بك سوف تبدو مثل:

views.ParseSettings(AppSettings.Views);
locale.ParseSettings(AppSettings.Locale);
network.ParseSettings(AppSettings.Network);

وهذا سيكون بالتأكيد "أنظف" من اللد بوف, ولكن قد لا يكون يستحق كل هذا العناء للحصول على عدد من الإعدادات التي لديك.ومع ذلك ، مع نطاق العمق ربما يعني أن لديك الكثير من الإعدادات ، وذلك بتقسيمهم إلى مجالات المسؤولية (للتحميل حفظ الإعدادات) هو على الارجح معقولة.

كل الأشياء نسبية ، وهذا يعتمد حقًا على حجم المشروع وإذا كنت تهتم بالصيانة.

إذا كنت تهتم بالصيانة ، فأنت لا ترغب في فرض أي قيود يفرضها مصدر التكوين الخاص بك على بقية قاعدة الكود الخاصة بك.

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

public interface IConfiguration
{
    Size ViewSize { get; }
}

public class AppSettingsConfiguration : IConfiguration
{
     public Size ViewSize
     {
          return AppSettings.Views.Windows.Dashboard.Size;
     }
}

يجب بعد ذلك ترميز جميع التعليمات البرمجية المستهلكة مقابل واجهة الأيقونات. هذا يعني أنه يمكنك تغيير طريقة استرداد التكوين الخاص بك بأقل تأثير.

قد تكون الأجيال التلقائية مشكلة للمشاريع الكبيرة.

إذا كنت ستستخدم الرمز الذي تم إنشاؤه من مكان واحد (على سبيل المثال حزمة واحدة) ، فربما لا توجد مشكلة.

إذا كنت ستستفيد من الرمز:

var windowSize = AppSettings.Views.Windows.Dashboard.Size;

في العديد من الأماكن ، قد ترغب في إخفاء بعض هذا الاقتران الذي يجعل طريقة على AppSettings:

getSize() {
  return Views.Windows.Dashboard.Size;
}

ولكن إذا كنت ستحتاج إلى القيام بذلك لجميع الفصول ، فربما لا يكون ذلك قابلاً للتطبيق.

يعتمد أفضل قرار على حجم مشروعك (وإذا كان ينوي النمو) ، والوقت الذي يتعين عليك القيام به ، وكمية التعليمات البرمجية التي تم إنشاؤها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top