我应该使用什么设计模式来更新T类型对象的值

本文关键字:类型 对象 更新 什么 设计模式 我应该 | 更新日期: 2023-09-27 17:58:52

我有以下场景,我正试图弄清楚在for循环中放置什么设计模式。

查询将只返回Bananas或Apples。千万不要把香蕉和苹果混在一起。我提前知道在调用DoStuff时,会返回Bananas还是Apples,因为我可以控制查询。

我一直在尝试一种方法,通过一个接口作为DoStuff的第二个参数,该参数可以设置香蕉的长度或苹果的直径。

关于我如何实现这一目标,有什么建议吗?我需要DoStuff才能重新使用。

    public class BaseClass
    {
    }
    public class Apple : BaseClass
    {
        public int Diameter { get; set; }
    }
    public class Banana : BaseClass
    {
        public int Length { get; set; }
    }
    public void DoStuff(Query query)
    {
        // The query only ever returns bananas OR Apples. Never both.
        var items = repository.GetItems<BaseClass>(query);
        foreach (var item in items)
        {
            // Code to run some arbitrary calculation then set Length if Banana
            // Code to run some arbitrary calculation then set Diameter if Apple
        }
    }

我应该使用什么设计模式来更新T类型对象的值

如果没有派生类共享任何行为或数据,为什么要有基类?你应该研究利斯科夫替代原则(LSP)。LSP基本上说,正确的系统遵循强大的行为亚型,并且在多态场景中,当一种类型被替换为另一种类型时,它不会违反正确性等。

你有两个没有任何共同点的子类,这显然违反了这个原则。我建议你换一种方式来解决这个问题,并提供更多关于你想完成什么的细节,这样有人可能会帮助你完成你需要的事情。

在不知道你想做什么的情况下,我建议你做一些事情:

public abstract class BaseClass
{
    public abstract void DoSomething();
}
public class Apple : BaseClass
{
    public int Diameter { get; set; }
    public override void DoSomething()
    {
        // Do something specific for Apple
    }
}
//...
public void DoStuff(Query query)
{
    // The query only ever returns bananas OR Apples. Never both.
    var items = repository.GetItems<BaseClass>(query);
    foreach (var item in items)
    {
        item.DoSomething();
    }
}

您可以像以下一样编写DoStuff方法

public void DoStuff(Query query)
{
    // The query only ever returns bananas OR Apples. Never both.
    var items = repository.GetItems<BaseClass>(query);
    foreach (var item in items.OfType<Banana>())
    {
        // Code to set Length if Banana
    }
}

但我更喜欢利斯科夫替代原则。。。

我会在BaseClass中使DoStuff成为一个抽象方法,并在Apple&Banana:

public class BaseClass
{
    // Stuff common to Apples & Bananas here
    public abstract void DoStuff(Query query);
}
public class Apple : BaseClass
{
    public int Diameter { get; set; }
    public override DoStuff(Query query)
    {
        // Implementation for Apples
    }
}
public class Bananas : BaseClass
{
    public int length { get; set; }
    public override DoStuff(Query query)
    {
        // Implementation for Bananas
    }
}