设计/模式-我应该使用接口还是抽象类

本文关键字:接口 抽象类 模式 我应该 设计 | 更新日期: 2023-09-27 17:59:58

我有以下问题:我正在创建一个用于创建UML图的应用程序。现在只是为了简化一切,我假设只有几个可用的图表元素:

  1. 接口
  2. 泛化
  3. 接口实现
  4. 协会
  5. 聚合

我决定为所有这些元素创建一个通用的抽象类:

抽象DiagramElement,它有2个子类也抽象:

  1. DiagramRelation
  2. DiagramObject

Nextly DiagramRelation有4个子类:

  1. 泛化
  2. 接口实现
  3. 协会
  4. 聚合

DiagramObject有两个子类:

  1. 接口
  2. 类别

我真的很想发布一张照片,这样会更简单,但我没有足够的信誉点,所以很抱歉。

我遇到了以下问题:每个元素都有不同的视觉表示,即:接口只有方法等,所以每个元素都需要以不同的方式显示-我不想使用多个"if"指令。

我使用WPF,我决定每个控件都将其竞争放在StackPanel中,StackPanel将放在MyContextControl中(在ContextControl之后继承并添加接口atribute):

public interface IDiagramElementDraw
{
    public StackPanel Draw();
}
public MyContextControl : ContextControl
{
    private IDiagramElementDraw _drawingInterface;
    private StackPanel context;
    public DrawControl()
    {
        context = _drawingInterface.Draw();
    }
} 

但我不知道哪个类应该实现IDiagramElementDraw接口——我不想在interface、class、Generalization等类的级别实现它,因为我希望它们只表示每个元素的逻辑信息。

如果有任何帮助,我将不胜感激,请随时发布完全不同的解决方案——这可能是完全错误的,这只是我的想法。

设计/模式-我应该使用接口还是抽象类

根据我对另一个问题的回答:

使用接口或抽象类作为基础:一个抽象类ia共享实现;接口是共享合同。它们有一些共同点,但遇到的不同要求。例如,您可能想要共享需求(a通用接口IProjectile),或介于致命武器和非致命武器之间,同时执行这三种武器关于三个不同抽象类的类别(LethalSmallArms,非致命小武器和榴弹炮)接口IProjectile。

来自我的另一个答案

一个抽象类可以小心地以非中断的方式扩展方式对接口的所有更改都是中断更改。

更新:相反,接口可以是输入或输出类型的参数而抽象类不能。有时一个或另一个更重要适用于给定的设计,有时这是一个悬而未决的问题。

一般来说,接口和抽象类都很有用;这取决于世界卫生组织:

  • 对于使用API的人来说,接口更为可取,因为保证给予他绝对的自由
  • 抽象类更多希望有人扩展你的API,因为他们可以轻松完成延伸

更敏感的选择是将两者结合起来:设计公共接口的层次结构(用于使用),并提供具有任何实现最常见成员的抽象类(用于扩展),如果您想让客户端扩展API,请将其公开。

而且,在所有层次结构的底部,都需要私有实现类。

使用多态性可能是一个很好的解决方案,可以防止出现"if"情况。1.你可以有一个IDrawable接口,上面有一个Draw方法。这个接口将由抽象类实现。2.然后你会有一个ElementDrawing及其派生类,它将绘制不同的类型(类、接口…)。它可以是一个虚拟属性,将根据类型在每个DiagramElement中进行不同的实例化。

    class abstract DiagramElement : IDrawable
    {
        public abstract void Draw();   
    }

    class ClassDiagramElement:DiagramElement 
    {
        public overrides void Draw()
        {
           ElementDrawing elementDrawing = new ClassDrawing();
           elementDrawing.DrawElement(); 
        }
    }
    class InterfaceDiagramElement:DiagramElement 
    {
        public overrides void Draw()
        {        
           ElementDrawing elementDrawing = new InterfaceDrawing();
           elementDrawing.DrawElement([maybe need some parameters]); 
        }
    }

ElementDrawing是绘制UML中不同元素的所有派生类的基类。它可以被定义为如上所述的虚拟财产。