【问题标题】:How to simplify a class without writing methods that are already simple?如何在不编写已经很简单的方法的情况下简化一个类?
【发布时间】:2012-05-17 08:44:08
【问题描述】:

我有一个复杂的类,我想通过实现一个外观类来简化它(假设我无法控制复杂的类)。我的问题是复杂类有很多方法,我将简化其中的一些,其余的将保持原样。下面解释我所说的“简化”。

我想找到一种方法,如果一个方法是用外观实现的,那么调用它,如果没有,那么调用复杂​​类中的方法。我想要这个的原因是写更少的代码:) [少即是多]

示例:

Facade facade = // initialize
facade.simplified(); // defined in Facade class so call it

// not defined in Facade but exists in the complex class
// so call the one in the complex class
facade.alreadySimple(); 

想到的选项是:

选项1:编写一个包含复杂类变量的类并实现复杂类,然后通过直接委托实现简单类:

class Facade {
    private PowerfulButComplexClass realWorker = // initialize
    public void simplified() {
         // do stuff
    }
    public void alreadySimple() {
         realWorker.alreadySimple();
    }
    // more stuff
}

但是使用这种方法,我将需要只用一个委托语句来实现所有简单的方法。所以我需要写更多的代码(虽然很简单)

选项 2: 扩展复杂类并实现简化的方法,但这些方法的简单和复杂版本都将可见。

在 python 中,我可以实现类似的行为:

class PowerfulButComplexClass(object):
    def alreadySimple(self):
        # really simple

    # some very complex methods


class Facade(object):
    def __init__(self):
        self.realworker = PowerfulButComplexClass()
    def simplified(self):
        # simplified version of complex methods in PowerfulButComplexClass

    def __getattribute__(self, key):
    """For rest of the PowerfulButComplexClass' methods use them as they are
    because they are simple enough.
    """
        try:
            # return simplified version if we did
            attr = object.__getattribute__(self, key)
        except AttributeError:
            # return PowerfulButComplexClass' version because it is already simple
            attr = object.__getattribute__(self.data, key)
        return attr


obj = Facace()
obj.simplified() # call the one we have defined
obj.alreadySimple( # call the one defined in PowerfulButComplexClass

那么 Java 的实现方式是什么?

编辑:我所说的“简化”是什么意思:复杂的方法可以是参数太多的方法

void complex method(arg1, arg2, ..., argn) // n is sufficiently large

或一组相关的方法,它们几乎总是一起调用以完成单个任务

outArg1 = someMethod(arg1, arg2);
outArg2 = someOtherMethod(outArg1, arg3);
actualResult = someAnotherMethod(outArg2);

所以我们想要这样的东西:

String simplified(arg1, arg2, arg3) {
    outArg1 = someMethod(arg1, arg2);
    outArg2 = someOtherMethod(outArg1, arg3);
    return someAnotherMethod(outArg2);
}

【问题讨论】:

  • 简化是什么意思?您的更简单的方法是更快的专业化,还是更容易阅读或其他?如果它是专门化优化,那么选项 2 是有意义的,并且您的简单方法应该测试参数是否允许简单的情况,否则调用默认的复杂超类。您的 Java IDE 可以为您编写所有存根。
  • 我编辑了问题以阐明简化的含义。
  • 好的,所以它不是您要简化的类,而是您打算使用它编写的程序。这更有意义。我更倾向于你的封装方法。这意味着您将只实现您的程序所需的 API,并且在阅读您的外观时,您知道根类的“额外”复杂性没有在任何地方使用。这将简化您的单元测试。
  • 我想简化一个库类。这就是为什么我称它为“门面”。感谢 cmets。

标签: java python oop facade


【解决方案1】:

这叫做继承。考虑以下代码:

class Complex {
    public function complex() { /* Complex Function */ }
    public function simple() { /* Already simple function */ }
}

class SimplifiedComplex extends Complex {
    public function complex() { /* Simplify Here */ }
}

simple() 方法适用于 SimplifiedComplex 对象。

【讨论】:

  • 这样你仍然可以访问Complex.complex() 方法,通过显式转换:((Complex) simplifiedComplexInstance).complex()
  • @yair 实际上不是。 DownCasting 仍然调用覆盖方法。但是,您可以在类中调用super.complex() 并可能添加一个显式公共方法来执行此操作。在此处查看更多信息:stackoverflow.com/questions/1032847/…
  • @GuillaumePolet 你说得对。因此,就相关问题而言,这使得 Truth 的解决方案变得完整。
  • 这是我在问题中提到的选项 2,但在减少 args 数量等简化的情况下,简单和复杂的方法都将可见,我们将无法扩展简化类与另一个类(单一继承)。但这仍然是实现这一目标的好方法。
【解决方案2】:

根据您的用例,您可能希望通过委托(选项 1)在复杂类中的某些功能前面创建一个外观,而不是为复杂类中的其余功能提供支持,而是提供表示直接访问复杂类(getComplexClass)。

这可能会使设计更清晰。例如,考虑一个处理银行系统大部分功能的复杂类。创建一个名为“Account”的类,它可以访问复杂的类,但只使用与银行账户相关的方法,这有助于设计。为方便起见,Account 类可以有一个方法 getBankSystemForAccount 或类似的方法。

【讨论】:

    【解决方案3】:

    我想你已经调用它了。我会选择选项 1。鉴于 java 的刚性,它提供了最大的灵活性。

    我更喜欢它,因为它有利于组合而不是继承。虽然这会创建更多代码,但我发现从长远来看,这样的设计通常更容易修改。

    继承只能用于模拟严格的“是”关系,其中子类必须具有基类的所有属性和行为。如果您将继承用于其他任何事情,您会自找麻烦。

    最后,我不赞成“少即是多”的想法(在此处插入非常简洁、难以理解的 perl 示例)。我认同“代码应该尽可能简单,而不是简单”的原则。

    【讨论】:

    • 我认为我们可以在“少即是多”的范围内计算“不要重复自己”和可重用性之类的东西。在我看来,少写代码是个好主意,只要不与可维护性、可读性等冲突。
    【解决方案4】:

    这在 Java 中很难看,但是您可以编写一个函数,该函数接受您要调用的方法的名称和一个参数列表,并使用反射找到要调用的适当方法。这在概念上与您在 Python 中的操作方式相似,只是更丑陋。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多