.NET卑微的对象示例

时间:2012-04-02 13:37:56

标签: c# .net design-patterns

我目前正在尝试实现简洁的对象设计模式。我能找到的唯一资源来自xunit测试网站。不幸的是,尽管多次阅读,但我并不理解它。这个模式可能还有另一个名字吗?

这是我到目前为止所做的。

public interface IHumbleExchangeWebService
{
    GetItemResult BindToItems(IEnumerable<string> itemIds);
    SyncFolderItemsResult Sync();
    void Subscribe();
}

public class ExchangeWebServiceAdapter
{
    private readonly IHumbleExchangeWebService _humbleExchangeWebService;

    public ExchangeWebServiceAdapter(
        IHumbleExchangeWebService humbleExchangeWebService)
    {
        _humbleExchangeWebService = humbleExchangeWebService;

        Start();
    }

    private void Start()
    {
        SyncFolderItemsResult syncFolderItemsResults;
        while(true)
        {
            syncFolderItemsResults = _humbleExchangeWebService.Sync();

            if(syncFolderItemsResults != null)
                break;
        }

        ProcessSyncResults(syncFolderItemsResults);

        LastSyncDateTime = Time.Now;
        _humbleExchangeWebService.Subscribe();
    }

    private void ProcessSyncResults(SyncFolderItemsResult syncFolderItemsResults)
    {
        if (syncFolderItemsResults.Count <= 0) return;

        var missedItemIds = syncFolderItemsResults.ItemChange
            .ToList()
            .Select(x => x.ExchangeItem.ItemId);

        _humbleExchangeWebService.BindToItems(missedItemIds);
    }

    public DateTime LastSyncDateTime { get; private set; }
}

至于测试:

[TestFixture]
public class Tests
{
    private Mock<IHumbleExchangeWebService> _humbleExchangeWebServiceMock;

    [SetUp]
    public void SetUp()
    {
        _humbleExchangeWebServiceMock = new Mock<IHumbleExchangeWebService>();

    }

    [Test]
    public void OnInitialiseWillSyncBeforeSubscribing()
    {
        var callOrder = 0;
        _humbleExchangeWebServiceMock
            .Setup(x => x.Sync())
            .Returns(() => new SyncFolderItemsResult(0, false, String.Empty, GetExchangeItemChangeList()))
            .Callback(() => Assert.That(callOrder++, Is.EqualTo(0)));
        _humbleExchangeWebServiceMock
            .Setup(x => x.Subscribe())
            .Callback(() => Assert.That(callOrder++, Is.EqualTo(1)));

        var service = GetConstructedService();

        _humbleExchangeWebServiceMock.Verify(x => x.Sync(), Times.Once());
        _humbleExchangeWebServiceMock.Verify(x => x.Subscribe(), Times.Once());
    }

    [Test]
    public void WhenSyncingIsCompleteWillProcessMissingItem()
    {
        _humbleExchangeWebServiceMock
            .Setup(x => x.Sync())
            .Returns(new SyncFolderItemsResult(1, false, It.IsAny<string>(), GetExchangeItemChangeList()));

        var service = GetConstructedService();

        _humbleExchangeWebServiceMock.Verify(x => x.BindToItems(It.IsAny<IEnumerable<string>>()));
    }

    [Test]
    public void BindingItemsWillProcess()
    {
        _humbleExchangeWebServiceMock
            .Setup(x => x.Sync())
            .Returns(new SyncFolderItemsResult(1, false, It.IsAny<string>(), GetExchangeItemChangeList()));

        var service = GetConstructedService();

        _humbleExchangeWebServiceMock
            .Verify(x => x.BindToItems(new []{"AAA", "BBB", "CCC", "DDD"}), Times.Once());

        _humbleExchangeWebServiceMock.VerifyAll();
    }

    private ExchangeWebServiceAdapter GetConstructedService()
    {
        return new ExchangeWebServiceAdapter(_humbleExchangeWebServiceMock.Object);
    }

    private IEnumerable<ExchangeItemChange> GetExchangeItemChangeList()
    {
        yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("AAA"));
        yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("BBB"));
        yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("CCC"));
        yield return new ExchangeItemChange(ChangeType.Create, new ExchangeItem("DDD"));
    }
}

基本上,我只是想知道我是否正在使这个卑微的物体变得愚蠢。我的意思是,它是提取所有条件的正确方法,我可以轻松地将测试单元化为包装类(例如ExchangeWebServiceAdapter)。

1 个答案:

答案 0 :(得分:4)

尝试实现简单对象模式时,一个好的经验法则是查看刚创建的对象,并问自己如何测试其中的所有逻辑。如果你对10秒钟内你要做的事情有一个大概的了解并且不会让你大声呻吟,你可能会很好。如果你花费的时间超过这个,或者如果它让你痛苦地思考它,你可能在某个地方犯了错误。

对于不起眼的图案的理解,你可以把它想象成汽车装配线;使那些大规模线条起作用的事实是一切都是可以互换的。只有引擎Go,加热器只有Heat等。在你的脑海中保持直线的最简单的方法是命名你的类,使它们是一个具体的对象,然后摆脱任何不属于该对象应该做的事情。在您的具体示例中,您已将您的类命名为“适配器”。那么,它是什么适应FROM和TO?兼容两个不相容的东西是什么?我猜你的一部分混乱是你的班级在这个时候被误称或太宽。随着你的理解的增长,你的词汇量会增加,你可能会发现它在那时完全没问题。如果你只是在学习这种模式,它将会阻止你的理解直接跳到程序员的行话;我们使用的很多这些词的含义都很差。

更具体地说,如果Starter需要获取其他信息或踢其他资源来完成Start,那很好;只是应该清楚地命名那些其他资源,抽象出其他类,并单独测试。

你已经做了很好的工作,因为你已经把它们呈现得很微不足道了,但是当你到达那一点时,显然你也需要担心你的界面的实现是否足够愚蠢。 / p>

希望这会有所帮助;不起眼的对象模式既独特又非常类似于松散耦合的理想,你会听到人们一直在谈论。简陋的物体图案只是一种特定的规定方式,可以与传统上抵抗它的一堆物体实现松散耦合。