【问题标题】:Design pattern to "toString" a third party object“toString”第三方对象的设计模式
【发布时间】:2015-09-21 05:17:20
【问题描述】:

我有一个第三方对象,它使用从 Java.lang.Object 继承的 toString 方法。这种方法非常没用。但是我想不出一个干净的设计来覆盖这种行为。下面有不同的方法。

  1. 子类化并覆盖 toString 方法。

问题:如果原始对象内部的任何调用调用 toString 并检查返回的字符串,它们现在将中断。我不想破坏现有的对象,也不想假设第三方代码的清洁度。

  1. 使用 createString 方法创建一个 StringFactory。此方法对我的第三方对象以外的所有对象调用 toString,但我的对象以我的自定义方式构建一个 String。

问题:我既不能要求所有内容都传递给 createString 方法,也不能直接调用 toString(这在大型代码库中会很可笑),我也不能轻松记住哪些对象应该被通过,因为它们有自定义逻辑。

有没有人觉得干净的设计模式?

【问题讨论】:

  • 子类化并提供myToString 方法并在您自己的代码中使用它可能是一种解决方案,具体取决于您想要实现的目标。行得通吗?
  • 关于#1 - 如果他们调用toString 并且根据其正确性的答案,他们无法理解toString 的目的。
  • @glowcoder 是的,这就是为什么我建议使用 new 方法,而不是覆盖。类似于 Bohemian 的回答,但更符合我的口味。

标签: java design-patterns


【解决方案1】:

只需在 util 类上使用静态方法:

public class MyUtils {

    public static String toString(My3rdPartyClass obj) {
        // impl here
    }
}

【讨论】:

  • 我真的很喜欢这个。优雅、简短、可重复使用且无需改动。
  • @glowcoder 这种方法的另一件事是它避免了类膨胀:您可以为任意数量的其他类添加 impls。
  • 我觉得这与我在原始问题中的#2 相同。除了增加这个类的范围以包括所有实用程序,我觉得这是一个错误,因为可能有大量实用程序。
  • 我接受这个答案,因为它可能是回答我所写问题的最佳方式,并且因为想要在不改变子类行为的情况下覆盖自己使用的方法的用例可能不会'不超过'toString'。
【解决方案2】:

我真的很喜欢波西米亚的回答。

考虑到这一点,解决它的 OOP 方法是

class My3rdPartyClassFormatter {
    private My3rdPartyClass data;
    public My3rdPartyClassFormatter(My3rdPartyClass d) { this.data = d; }
    public String toString() { 
        // impl here
    }
}

【讨论】:

  • 这不是装饰器模式的变种吗?再三考虑——这是一个包装类。 1+的建议。现在,在这个问题获得了 3 票之后,我当天的票都没有了。
  • @Hovercraft 是的,它更像是一个包装器。我不会认为它是装饰器,但我可以看到将它与装饰器进行比较的实用性。
【解决方案3】:

使用proxy。您的调用处理程序将拦截对第 3 方对象的所有调用。在大多数情况下,它只会让它们通过。但是,请实现您自己的 toString 逻辑。

InvocationHandler handler = new InvocationHandler
{
       private ThirdParty thrd ;

       public Object invoke ( Object proxy , Method method , Object [ ] args ) throws Throwable
       {
             if ( method . getName().equals ( "toString" ) )
             {
                  return "useful string" ;
             }
             else
             {
                  return method . invoke ( thrd , args ) ;
             }
       }
}

【讨论】:

  • 代理非常强大,但如果您不小心可能会引入问题(例如,您可能还需要处理equals 方法)。此外,代理需要一个目标接口。不过,+1 在某些情况下是一种解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-30
  • 1970-01-01
  • 2011-06-30
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多