سؤال

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

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

public class CarManager
{
    public static Car GetCarFromDatabase(int carId) { return new Car(); }

    public static void SaveCar(Car car) { }
}

أرى الآن كيف يمكن أن يكون لدي اختلاف Factories أن بناء السيارات بالنسبة لي ، سواء كانت من قاعدة بيانات ، أو في أي مكان! هذا عظيم! لذا ، ها هي أسئلتي:

س 1: فهمي ذلك Factories يجب فقط يبني الكائنات ، هل هذا صحيح؟ إذا كان الأمر كذلك ، ماذا عن سؤالي الثاني؟

س 2: إذا كنت أتابع نمط المصنع لبناء الأشياء الخاصة بي ، فكيف يجب أن أقوم بحفظ الأشياء الخاصة بي؟ هل هناك نمط مختلف لهذا ، أم لا أفهم نمط المصنع تمامًا؟

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

المحلول

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

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

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

نصائح أخرى

لا ينبغي أن يحفظ المصنع البيانات. سيكون كائن الوصول إلى البيانات (DAO) أو Mapper Table فكرة أفضل.

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

namespace Domain.App
{
    public class PresentationClass
    {
        private Collection<ISomeOutput> GetData(ISomeInput1 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier );
            return logic.GetSomeData(input) as Collection<ISomeOutput>;
        }
        private IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier);
            return logic.ExecuteSomeAction(input);
        }
    }
}   

namespace Domain.Logic
{
    public sealed class ServicesLogicContext : ServicesLogicContextBase
    {
        public IList<ISomeOutput> GetSomeData(ISomeInput1 input) 
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            return DBServicesProvider.GetSomeData(input);
        }
        public IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            IMethodResult result = services.ExecuteSomeAction(input);
            return result;
        }
    }
}

namespace Domain.Data
{
    public abstract class DBServices : IServices
    {
        public virtual IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public virtual IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific1 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific2 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public sealed class DBServicesProvider
    {
        public static DBServices CreateServices(MyType identifier)
        {
            DBServices result = null;       
            switch(identifier) 
            {
                case MyType.Specific1: result = new DBServicesSpecific1(); break;
                case MyType.Specific2: result = new DBServicesSpecific2(); break;       
            }
            return result;
        }
    }
}

بشكل عام ، أعتقد أنك تقترب من هذا من الزاوية الخاطئة.

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

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

Q1 - نعم ، يجب استخدام نمط المصنع بشكل مثالي لإنشاء كائنات. لذلك ، يمكنك إنشاء كائن سيارتك باستخدام نمط المصنع.

س 2 - لتوفير كائن سيارتك ، يجب ألا تستخدم نمط المصنع. تفسير إنشاء كائن السيارة وحفظ كائن السيارة. ومن الصعب اقتراح نمط تصميم لإنقاذ كائن سيارتك دون فهم المتطلبات بدقة. في رأيي ، إذا كنت بحاجة فقط إلى حفظ كائنات سيارتك ، فكل ما تحتاجه هو طريقة حفظ في فئة مدير سيارتك. لا تستخدم أنماط التصميم.

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