设计模式:将第三方对象转换为字符串 ("toString")

4

我有一个第三方对象,它使用继承自Java.lang.Object的toString方法。这个方法相当无用。然而,我想不出一个干净的设计来覆盖这种行为。以下是不同的方法。

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

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

  1. 创建一个String工厂,其中包含一个createString方法。该方法对除了我需要处理的第三方对象之外的所有对象调用toString,但对于我的对象,则以自定义方式构建一个字符串。

问题:我既不能要求将所有内容都传递给createString方法且永远不直接调用toString(在大型代码库中这是荒谬的),也不能轻松记住应通过哪些对象(因为存在特定的逻辑)。

有没有人有一种感觉很清晰的设计模式?


通过子类化并提供一个 myToString 方法,并在您自己的代码中使用它,这可能是一种解决方案,具体取决于您想要实现什么。这样做是否可行? - cyco130
3
关于#1-如果他们调用toString()并依赖它的答案来判断正确性,则他们未能理解toString()的目的。 - corsiKa
@glowcoder 是的,这就是为什么我建议使用方法而不是覆盖。类似于Bohemian的答案,但更符合我的面向对象口味。 - cyco130
3个回答

5

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

public class MyUtils {

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

1
我真的很喜欢这个。简洁优雅,短小精悍,可重复使用,没有任何修改。 - corsiKa
@glowcoder 这种方法的另一个好处是避免了类膨胀:您可以为尽可能多的其他类添加实现。 - Bohemian
我觉得这与我在原问题中的第二点相同。除了您正在扩大此类别的范围以包括所有实用程序,我认为这是一个错误,因为可能存在大量实用程序。 - Cory Kendall
我接受这个答案,因为它可能是最好的回答我的问题的方式,并且因为想要覆盖方法以便于自己个人使用而不改变子类行为的用例可能仅限于 'toString'。 - Cory Kendall

5

我很喜欢Bohemian的答案。

考虑到这一点,解决它的面向对象编程方式是

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

1
这不是装饰器模式的变体吗?仔细想想——这是一个包装类。对于这个建议,我给出了1个赞。现在,在这个问题中经过3次投票后,我今天已经没有投票机会了。 - Hovercraft Full Of Eels
@Hovercraft 是的,它更像是一个包装器。我不认为它是一个装饰器,但我可以看到将其与装饰器进行比较的实用性。 - corsiKa

2

使用代理。您的调用处理程序将拦截对第三方对象的所有调用。在大多数情况下,它只需将它们传递。但是,请实现自己的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”方法)。此外,代理需要一个目标接口。尽管如此,在某些情况下这仍然是一种解决方案,值得肯定。 - John McCarthy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接