程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 《模式——工程化實現及擴展》工廠方法模式 Factory Method—“自我檢驗 參考答案

《模式——工程化實現及擴展》工廠方法模式 Factory Method—“自我檢驗 參考答案

編輯:C#入門知識

請修改本章最後完成的那個比較適於工程應用的工廠類型,使其支持含參數的構造函數
 


分析:

1、本著OCP原則,我們不對原有Factory<T> 進行修改,而是通過繼承對其進行擴展


2、繼續采用.NET Framework自帶的Activator提供對於帶參數構造函數的支持


3、為了與原有Factory<T>的方法簽名作區別,我們在新的接口中要求只有明確聲明為object[]的數組才作為構造函數參數


 

參考答案


 

1、為了不引起其歧義,首先修改引用的命名空間

using System;
using F = MarvellousWorks.PracticalPattern.FactoryMethod;
using Microsoft.VisualStudio.TestTools.UnitTesting;

 


 2、定義新的工廠接口和具體工廠類型

interface IFactory : F.IFactory   
{
#region factory method
    TTarget Create<TTarget>(object[] parametes);
    TTarget Create<TTarget>(string name, object[] parametes);
    #endregion
}
       
class Factory : F.Factory, IFactory    
{

    public TTarget Create<TTarget>(object[] parametes)
    {
        return (TTarget)Activator.CreateInstance(registry[typeof(TTarget)], parametes);
    }

    public TTarget Create<TTarget>(string name, object[] parametes)       
    {
        return (TTarget)Activator.CreateInstance(registry[typeof(TTarget), name], parametes);
    }
}
 

3、編寫單元測試驗證

[TestMethod]
public void CreateInstance()
{
    var factory = new Factory()
        .RegisterType<IFruit, Apple>()
        .RegisterType<IFruit, Orange>("o")
        .RegisterType<IVehicle, Bicycle>()
        .RegisterType<IVehicle, Bicycle>("a")
        .RegisterType<IVehicle, Train>("b")
        .RegisterType<IVehicle, Car>("c")
        .RegisterType<IEntry, EntryWithName>()
        .RegisterType<IEntry, EntryWithName>("n")
        .RegisterType<IEntry, EntryWithNameAndAgeAndTitle>("nat");

    #region 構造函數無參數的類型

    Assert.IsInstanceOfType(factory.Create<IFruit>(), typeof(Apple));
    Assert.IsInstanceOfType(factory.Create<IFruit>("o"), typeof(Orange));

    Assert.IsInstanceOfType(factory.Create<IVehicle>(), typeof(Bicycle));
    Assert.IsInstanceOfType(factory.Create<IVehicle>("a"), typeof(Bicycle));
    Assert.IsInstanceOfType(factory.Create<IVehicle>("b"), typeof(Train));
    Assert.IsInstanceOfType(factory.Create<IVehicle>("c"), typeof(Car));

    #endregion

    #region 構造函數帶參數的類型

    //  轉換為新的擴展接口形式
    var f = (IFactory) factory;   

    //  使用擴展的功能
    var e1 = f.Create<IEntry>(new object[] { "joe" });
    Assert.IsInstanceOfType(e1, typeof(EntryWithName));
    Assert.AreEqual<string>("joe", ((EntryWithName) e1).Name);

    var e2 = f.Create<IEntry>("nat", new object[] { "joe", 20});
    Assert.IsInstanceOfType(e2, typeof(EntryWithNameAndAgeAndTitle));
    Assert.AreEqual<string>("joe", ((EntryWithName)e2).Name);
    Assert.AreEqual<int>(20, ((EntryWithNameAndAgeAndTitle)e2).Age);
    Assert.AreEqual<string>(EntryWithNameAndAgeAndTitle.DefaultTitle, ((EntryWithNameAndAgeAndTitle)e2).Title);

    #endregion
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved