C# 哪种设计最适合此场景?

C# 哪种设计最适合此场景?,c#,design-patterns,interface,abstract-class,C#,Design Patterns,Interface,Abstract Class,谁能告诉我哪种设计最适合这种情况 我有叫做BasicAccount,SavingAccount和currentcount的类 savingcount和currentcount应具有BasicAccount的所有功能。稍后,我们可能会引入一个名为AdvanceAccount的新帐户,它应该具有currentcount和savingcount的所有功能。我应该如何设计结构 我的答覆是: 让我们将BasicAccount保持为抽象,SavingAccount也是抽象的,并实现BasicAccount

谁能告诉我哪种设计最适合这种情况

我有叫做
BasicAccount
SavingAccount
currentcount
的类

savingcount
currentcount
应具有
BasicAccount
的所有功能。稍后,我们可能会引入一个名为
AdvanceAccount
的新帐户,它应该具有
currentcount
savingcount
的所有功能。我应该如何设计结构

我的答覆是:

  • 让我们将
    BasicAccount
    保持为抽象,
    SavingAccount
    也是抽象的,并实现
    BasicAccount

  • 创建一个接口
    ICurrentAccount
    ,currentaccount实现
    BasicAccount
    ICurrentAccount

  • 如果我们有
    AdvanceAccount
    ,那么使用
    SavingAccount
    ICurrentAccount
    实现它


还有更好的办法吗?这是在一次面试中问我的,我想面试官对我的回答不满意。

我会用这样的话:

abstract class BasicAccount {}

interface ISavingAccount {}
interface ICurrentAccount {}

class SavingAccount : BasicAccount, ISavingAccount {}  
class CurrentAccount : BasicAccount, ICurrentAccount {}  
class AdvanceAccount : BasicAccount, ISavingAccount, ICurrentAccount {}  
如果
SavingAccount
CurrentAccount
有很多功能,您可以在
AdvanceAccount
实现中使用聚合:

class AdvanceAccount : BasicAccount, ISavingAccount, ICurrentAccount 
{
    private readonly SavingAccount savingAccount;
    private readonly CurrentAccount currentAccount;

    public AdvanceAccount()
    {
        savingAccount = new SavingAccount(...);
        currentAccount = new CurrentAccount(...);
    }

    // redirect ISavingAccount and ICurrentAccount implemetation
    // to savingAccount and currentAccount respectively
}  
UPD

注意,
AdvanceAccount
中的
SavingAccount
currentcount
的直接实例化只是一个示例。IRL您可能会使用IoC容器

我想说,装饰模式在这里比传统继承更适用

public interface IBasicAccount { }
public interface ISavingAccount { }
public interface ICurrentAccount { }
public interface IAdvanceAccount { }

public class BasicAccount : IBasicAccount { }

public class SavingAccount : ISavingAccount
{
    // methods may use basic account internally to delegate some function calls
    private readonly IBasicAccount _basicAccount;

    public SavingAccount(IBasicAccount basicAccount)
    {
        _basicAccount = basicAccount;
    }
}

public class CurrentAccount : ICurrentAccount
{
    private readonly IBasicAccount _basicAccount;

    public CurrentAccount(IBasicAccount basicAccount)
    {
        _basicAccount = basicAccount;
    }
}

public class AdvanceAccount : IAdvanceAccount
{
    private readonly ISavingAccount _savingAccount;
    private readonly ICurrentAccount _currentAccount;

    public AdvanceAccount(ISavingAccount savingAccount, ICurrentAccount currentAccount)
    {
        _savingAccount = savingAccount;
        _currentAccount = currentAccount;
    }
}
您可以根据需要将调用委托给内部IBasicAccount、ISavingAccount和ICurrentAccount实现。
此外,如果您的业务模式需要,您可以使
ISavingAccount
iccurrentcount
继承
ibasiccount

这是一个典型的菱形问题

有各种各样的方式来看待它。最后,这实际上取决于设计的其他方面

  • 其中一种方法是使用行为创建继承
  • 另一种是使用数据创建继承(派生类主要共享数据)

如果您可以使用服务拆分行为,您应该能够将行为添加/删除到您想要的任何新类中,这些行为应该只能从基本帐户派生,如果它们可以从其他子类派生,那么这是一个奖励

除了前面已经说过的内容,如果我们不同时要求
储蓄账户
活期账户
实例,我们可以使用以下内容:

abstract class BasicAccount
{
   // .. some implementation here
}

class SavingAccount : BasicAccount { }

class CurrentAccount : BasicAccount { }

class AdvancedAccount<T> where T : BasicAccount
{
    private readonly T _instance;

    public T AccountToWorkWith { get { return _instance; } }

    public AdvancedAccount(BasicAccount instance)
    {
        this._instance = instance as T;
    }
}
抽象类基本计数
{
//…这里有一些实现
}
类SavingAccount:BasicAccount{}
类CurrentAccount:BasicAccount{}
类AdvancedAccount,其中T:BasicAccount
{
私有只读T_实例;
公共T AccountToWorkWith{get{return}实例;}
公共AdvancedAccount(基本帐户实例)
{
这个。_instance=实例为T;
}
}

如果SavingsAccount是抽象的,那么如何打开SavingsAccount?为什么SavingsAccount是抽象的?为什么要区别对待这两个分支呢?我认为根据accounts层次结构在这里使用接口实现很简单。这样子类型帐户就可以确保除了自己的主类型帐户功能之外,还具有所有主类型帐户功能。还有助于以自己的方式实现这些强制功能。术语:类实现接口,但是继承/扩展/派生自基类。
Advanced Account
是否应该同时与
Saving Account
Current Account
一起工作,或者只在需要时访问这两个帐户中的一个的信息?而不是三级接口实现…..聚合是一个很好的解决方案可以理解的技巧…很好的回答。这也正是我所想的(不过你回答得更快)。但是我会在这里使用IoC,因为我不喜欢在构造函数中实例化
SavingAccount
CurrentAccount
类的想法,就像在这个答案中那样…@Fabjan:是的,这绝对是IoC的工作。但这只是一个示例。对于聚合方法接口实现,需要“class AdvanceAccount:BasicAccount、ISavingAccount、ICurrentAccount”?。当您在“AdvanceAccount”中创建私有变量时。@andy:如果某个方法仅适用于
ISavingsAccount
,我需要在
AdvanceAccount
中继承此接口,以便能够将其传递给该方法。您将如何委托
提取(十进制金额)
method?这与其说是一个
Decorator,不如说是一个
Composite
True,如果所有帐户都实现了一个公共的基本接口,那么它将是一个Decorator。您可以用
void draw(decimal amount){u basicAccount.draw(amount);}来委托调用
任何一个接口都应该继承自
ibasiccount
,或者
SavingAccount
,其他接口也应该实现
ibasiccount
。否则,您将需要复制
ibasiccount
方法,并且层次结构中没有任何基本类型(例如,您不能将所有这些帐户放入某个帐户集合)。