简体   繁体   English

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

[英]What design pattern should I use to update values on an object of type T

I have the following scenario and I'm trying to figure out what design pattern to place in the for loop. 我有以下场景,我正在试图找出在for循环中放置的设计模式。

The query will only ever return Bananas or Apples. 该查询将只返回香蕉或苹果。 Never a mix of bananas and apples. 从不混合香蕉和苹果。 I know ahead of time when calling DoStuff, whether Bananas or Apples will be returned because I can control the query. 我提前知道调用DoStuff时,是否会返回Bananas或Apples,因为我可以控制查询。

I've been trying an approach of passing through an interface as a second parameter to DoStuff that would either set the length of banana or diameter of apple. 我一直在尝试通过接口作为DoStuff的第二个参数来设置香蕉的长度或苹果的直径。

Any suggestions as how I could achieve this? 有什么建议,我怎么能做到这一点? I need DoStuff to be re-usable. 我需要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
        }
    }

Why have a base class if no derived class shares any behaviour or data? 如果没有派生类共享任何行为或数据,为什么有基类? You should look into Liskov Substitution principle (LSP). 你应该研究Liskov Substitution原则(LSP)。 LSP basically says that correct systems adhere to strong behavioural subtyping and that in a polymorphic scenario when one type is substituted for another it will not violate correctness, etc. LSP基本上表示正确的系统遵循强烈的行为子类型,并且在多态方案中,当一种类型替换另一种类型时,它不会违反正确性等。

You're clearly violating this principle by having two subclasses with nothing real in common. 你明显违反了这个原则,因为它有两个没有共同点的子类。 I would suggest you look at a different way of approaching this and provide more detail on what you want to accomplish so someone might be able to help you accomplish what you need. 我建议你看一下接近这个的不同方式,并提供你想要完成的更多细节,这样有人可以帮助你完成你所需要的。

Without knowing more about what you're trying to do, here's something I would suggest: 如果你不了解更多关于你想做什么的事情,我建议你这样做:

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();
    }
}

You can write your DoStuff method like this 您可以像这样编写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
    }
}

but I do prefer the Liskov Substitution principle... 但我更喜欢Liskov Substitution原则......

I'd make DoStuff an abstract method in BaseClass and override it in Apple & Banana : 我将DoStuff作为BaseClass的抽象方法,并在AppleBanana覆盖它:

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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM