سؤال

كنت أحاول العثور على مثال واضح وبسيط لما يعنيه مجال فقر الدم حقًا.هناك الكثير من النظريات حولها، وكذلك العديد من الأسئلة التي تمت الإجابة عليها بشكل جيد.ومع ذلك، لم أتمكن من الحصول على صورة واضحة حول المدى الحقيقي الذي يصل إليه معنى "مجال فقر الدم".لذلك، أعتقد أنه سيكون من الأسهل رؤية مثال عملي وهمي لتصميم مجال ضعيف ومن أن نسألك كيف يمكن تطوير هذا إلى مجال يحركه...

لذلك، لنفترض أن لدينا كيان بيانات من النوع TaskData:

public class TaskData
{
    public Guid InternalId { get; set; }

    public string Title { get; set; }

    public string Details { get; set; }

    public TaskState ExplicitState { get; set; }

    public IEnumerable<TaskData> InnerTasks { get; set; }

}

وهناك حاجة لعقار إضافي يسمى "الحالة الفعلية"، وهي حالة محسوبة:إذا كانت المهمة تحتوي على مهام فرعية داخلية، فإن القيمة تعتمد بشكل صارم على العناصر الفرعية، وإلا، فإن "الحالة الفعلية" مساوي ل "حالة صريحة"

إذا كنت أكتب هذا المنطق في منفصلة خدمة فئة (أنا أسميهم "المحركات") لدينا:

internal class TaskStateCalculator
{
    public TaskState GetState(TaskData taskData)
    {
        if (taskData.InnerTasks.Any())
        {
            if (taskData.InnerTasks.All(x => this.GetState(x) == TaskState.Done))
            {
                return TaskState.Done;
            }
            if (taskData.InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
            {
                return TaskState.InProgress;
            }

            return TaskState.Default;
        }

        return taskData.ExplicitState;
    }       
}

ال السؤال الأول يكون:

هل يعكس الكود أعلاه تصميم المجال الفقير، حتى لو كان TaskStateCalculator الخدمة/المحرك جزء من طبقة المجال الخاصة بي؟إذا كانت الإجابة بنعم، لتجنب ذلك، سنحتاج إلى نقل المنطق داخل TaskData فئة (وإعادة تسمية TaskData ل مهمة).هل انا على حق؟

ال السؤال الثاني هو (في الواقع سلسلة منهم):

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

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

المحلول

كنت أحاول العثور على مثال واضح وبسيط لما يعنيه مجال فقر الدم حقًا

من السهل حقًا الانتقال من نموذج المجال المصاب بفقر الدم إلى نموذج المجال الغني.

  1. قم بتعيين جميع محددات الملكية على private ثم أضف طرقًا إذا كنت تريد تغيير حالة النموذج.
  2. تقييم الكل قانون ديميتر الانتهاكات وإضافة الأساليب حيثما كان ذلك مناسبا.

في النهاية سيكون لديك النموذج الصحيح.

في حالتك أود أن ألخص هذا المنطق في الداخل TaskData نظرًا لأن TaskStateCalculator الخاص بك ينتهك قانون ديميتر

public class TaskData
{
    public Guid InternalId { get; private set; }

    public string Title { get; private set; }

    public string Details { get; private set; }

    public TaskState ExplicitState { get; private set; }

    public IEnumerable<TaskData> InnerTasks { get; private set; }

    public TaskState GetState()
    {
        if (!InnerTasks.Any())
            return ExplicitState;

        if (InnerTasks.All(x => this.GetState(x) == TaskState.Done))
        {
            return TaskState.Done;
        }

        if (InnerTasks.Any(x => this.GetState(x) == TaskState.InProgress))
        {
            return TaskState.InProgress;
        }

        return TaskState.Default;
    }       
}

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

لماذا المستوطنين الخاصين

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

حتى إذا قمت بتغيير خاصية واحدة فقط، فيمكن لهذه الخاصية تعيين الفئة في حالة غير صالحة لأن التغيير قد لا يكون متوافقًا مع بقية المعلومات الموجودة في الفئة.لا تنس أن التغليف هو أحد المبادئ الأساسية في OOP

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