سؤال

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

لدي مجموعة من الاختبارات التالية:

    [TestMethod]
    public void Factory_Interface_Should_Return_IStatusUpdate()
    {
      var factory = MockRepository.GenerateMock<IUpdateFactory<StatusData>>();
      var obj = MockRepository.GenerateStub<IStatusUpdate>();

      var data = new StatusData();
      factory.Stub(x => x.Get(data)).Return(obj);

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(IStatusUpdate));
    }

    [TestMethod]
    public void StatusUpdateFactory_Should_Return_IStatusUpdate()
    {
      var factory = new StatusUpdateFactory();
      var data = new StatusData();

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(IStatusUpdate));   
    }

    [TestMethod]
    public void StatusUpdateFactory_Should_Return_NewStatusUpdate_When_Status_Is_New()
    {
      var data = new StatusData(Status.New);
      var factory = new StatusUpdateFactory();

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(NewStatusUpdate));
    }

يشبه تنفيذ المصنع حتى الآن:

public class StatusUpdateFactory:IUpdateFactory<StatusData>
  {
    public IStatusUpdate Get(StatusData item)
    {
      IList<ISpecification<StatusData>> specs = GetSpecifications();

      foreach (var spec in specs)
      {
        if (spec.IsSatisfiedBy(item))
          //how do I do this?
           return new NewStatusUpdate();

      }
      return null;
    }

    private IList<ISpecification<StatusData>> GetSpecifications()
    {
      var returnList = new List<ISpecification<StatusData>>();
      var specTypes = this.GetType().Assembly.GetTypes()
                        .Where(z => z.IsInstanceOfType(typeof(ISpecification<StatusData>)))
                        .ToList();


      specTypes.ForEach(x => returnList.Add(Activator.CreateInstance(x) as ISpecification<StatusData>));

      return returnList;

    }
  }

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

اقترح شخص ما بحق أن أحتاج إلى تعيين المواصفات إلى مفاجئي ISTATUSUPDATE. يبدو أن هذا التعيين مسؤولية المصنع، معلقة خارج المواصفات تنبعث منها مثل انتهاك SRP. يمكنني إنشاء فئة MAPPER التي لها هذه المسؤولية، لكن هذا لا يبدو عام للغاية ويثير السؤال حول كيفية تعيين mapper إلى المواصفات.

لا يزال هناك قفزة واحدة قليلا هنا أنا في عداد المفقودين.

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

المحلول

لذلك أنا أفترض أننا نركز حقا على مجموعة الخطوط:

if (spec.IsSatisfiedBy(item))
          return new NewStatusUpdate();

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

interface ISpecSupport<T>
{
    bool ItemSpecsContain(ISpecification<T> spec);
}

ثم يمكن أن تأخذ طريقة Spec.issatisfiedby في هذا النوع من الواجهة وتشغيل الطريقة.

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

أيضا، بدلا من ما سبق ربما يمكنك إعادة ترتيبها مثل ذلك:

if (item.Satisfies(spec))
    return new NewStatusUpdate();

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

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

نصائح أخرى

إذا فهمت بشكل صحيح، فأنت تريد، بالنظر إلى كائن تنفيذ ISPECICTION الذي تريده كائن ينفذ ISTATUSUPDATE؟

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

ولكن من المحتمل أن تحتاج إما تحتاج إلى حاجة إلى بعض المصنع لعقد الرمز، أو طريقة ISPecification.getupDate () للقيام بإنشاء الكائن.

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