【问题标题】:Extend a non-GUI framework by a GUI通过 GUI 扩展非 GUI 框架
【发布时间】:2017-01-04 17:13:15
【问题描述】:

我有一个“框架”,如果我通过代码使用它,它就可以完成它的工作。这很好,因为并非所有运行该框架的系统都安装了图形。

现在我想为这个框架创建一个图形用户界面。因为一个大型的、自我管理的框架组合最终正在运行,我不想创建一个并行的 GUI 层次结构并重新实现 GUI 的所有自我管理的东西以及组织 .事实上,我的想法是为每个类创建一个扩展,例如。 G。称为gui,稍后可以包含在主窗口中。因此,我将其绘制如下:

在这个插图中,我不喜欢多重继承。正如m2() 的示例所示,它引入了一些问题。这里的问题是:“哪个m(2)ConcreteGui 执行,更新后的AbstractGui 还是来自AbstractClass 的过时的ConcreteClass?”

我可以使用哪种方法或设计模式?

编辑:

让我们假设以下给定的框架(这是一个与语言无关的问题,Python 仅用作说明)。

class AbstractClass:
    def __init__(self):
        self.a = 23
        self.b = 42
    def m1(self):
        return self.a + self.b
    def m2(self):
        self.b += 1
        return self.a * 2

class ConcreteClass1(AbstractClass):
    def __init__(self):
        super().__init__()      # constructor of AbstractClass
        self.c = 13
        self.d = 7
    def m3(self):
        return self.a - self.d
    def m4(self):
        self.a += 1
        return self.b / self.c

现在,每个属性都应获得一个 GUI 小部件作为用户友好的表示(显示当前值)以及界面(设置值)。为此,我不想重写 all 方法来使用特定的小部件而不是属性。添加的小部件应该对所有已实现的方法都是透明的。

【问题讨论】:

  • 'AbstractGui' 中的'm2()' 与'AbstractClass' 有什么不同吗?如果你只是用'#gui'扩展'AbstractGui',那么为什么不在两个concreteGui上实现它作为接口(可能使用依赖注入)?
  • 是的,AbstractGuim2()AbstractClass 的不同。 m2() 也有可能(甚至更有可能)在 ConcreteClass 中重新定义,而不是 AbstractGui。那么#gui可以是AbstractGuiConcreteGui实现的接口,但是ConcreteGui的属性ab是怎么变成属性的呢?
  • 为什么不删除'AbstractGui'并用'IGui'或包含“小部件和#gui的属性的+a和+b”的类似内容替换,并在每个ConcreteGui类和你将能够覆盖 AbstractClass 中的 +m2()。
  • 但是在每个(数百个?)ConcreteGuis 中复制相同的“+a、+b 和 m2() 实现”既不高效也不可维护。我想重用widgeta/b的生成和链接以及覆盖的m2()

标签: user-interface design-patterns


【解决方案1】:

您不能同时从 ConcreteClass 和 AbstractGUIClass 派生,您可能必须将 GUI 实现分开并将它们注入到 ConcreteGuiClass 中

public class ConcreteClassGui1 : ConcreteClass1 {

    private IGuiSpecificOperations _guiSpecificOperations;

    public ConcreteClassGui1(IGuiSpecificOperations guiSpecificOperations){

        _guiSpecificOperations = guiSpecificOperations;

        SetSomeGuiProperties();
    }

    ~ConcreteClassGui1(){

    }

    public override Method2()
    {
        // specific implementation
    }

    private void SetGuiProperties()
    {
        _guiSpecificOperations.PropertyGuiA = "Test";
        _guiSpecificOperations.PropertyGuiB = 10;
    }

}

public class ConcreteClassGui2 : ConcreteClass2 {


    private IGuiSpecificOperations _guiSpecificOperations;

    public ConcreteClassGui2(IGuiSpecificOperations guiSpecificOperations){

        _guiSpecificOperations = guiSpecificOperations;
    }

    ~ConcreteClassGui2(){

    }

    public override Method2()
    {
        // specific implementation
        _guiSpecificOperations.PropertyGuiA = "Text";
        _guiSpecificOperations.PropertyGuiB = 10;
    }

}

public class GuiSpecificOperationImplementation : IGuiSpecificOperations {

    public GuiSpecificOperationImplementation(){

    }

    ~GuiSpecificOperationImplementation(){

    }

    public string PropertyGuiA{ get; set;}

    public int PropertyGuiB {get; set;}

}

    public interface IGuiSpecificOperations  
   {    
    public string PropertyGuiA{ get; set;}

    public int PropertyGuiB {get; set;}
   }

还注意到 IGuiSpecificOperations 的实现已被注入到 ConcreteGuiClass 中,而不是派生它们。

【讨论】:

  • 对不起,我不明白。无论如何,我必须使用PropertyX 重新实现所有方法以使用_guiSpecificOperations.PropertyGuiX?我在我的问题中添加了一个示例,希望能更清楚地勾勒出我的担忧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 2015-06-03
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多