【问题标题】:Tips: wrapping class in java in order to add new methods提示:在java中包装类以添加新方法
【发布时间】:2014-02-14 10:25:57
【问题描述】:

我想问你一些关于这个java场景的提示: 我有一个名为Sequence 的简单接口,它执行一些基本操作。现在我想在一个单独的类中实现一些额外的方法,称为SequenceWrapper,它实现了上面定义的Sequence。这是一些看起来像我的真实代码的示例代码:

public interface Sequence {       
    public void methodOne();
    public int methodTwo();
}

public abstract class SequenceWrapper implements Sequence {
    private wrappedSequence = null;

    public SequenceWrapper(Sequence sequence){
        this.wrappedSequence = sequence;
    }

    public void methodOne(){
        wrappedSequence.methodOne();
    }

    public int methodTwo(){
        return wrappedSequence.methodTwo();
    }
}

public class ConcreteWrapper extends SequenceWrapper {
    public ConcreteWrapper(Sequence sequence){
         super(sequence);
    }

    // Just an example
    public int addMethodOne(){
         int a = super.methodTwo();
         return a + 3;
    }        
}

现在,如果我想用另一种方法(比如“addMethodTwo()”)实现一个类,我可以简单地扩展“ConcreteWrapper”类并只添加新方法:

public class ConcreteWrapperTwo extends ConcreteWrapper {
    public ConcreteWrapperTwo(Sequence sequence){
         super(sequence);
    }

    public int addMethodTwo(){
         int a = super.methodTwo();
         return a + 30;
    }
}

你怎么看?这段代码是正确的还是另一种策略更可取?

提前致谢

【问题讨论】:

  • 虽然我基本上同意 Carlos Robles 的回答,但您在那里描述的似乎只是装饰者模式en.wikipedia.org/wiki/Decorator_pattern - 这是有道理的,但它应该(像所有模式一样)得到验证它确实适合特定的应用案例
  • 是的,@Marco13,我同意这一点,如果您在我的回答中查看 cmets,我也提到了它,但可能更难实现,正如您所说,首先它必须是检查它是否真的适合当前情况。
  • @Carlos Robles 是的,我注意到您提到了它,但想在此处添加此链接,以防提问者(或其他阅读问题的人)不知道“装饰模式”是特别是众所周知的模式,并且该关键字可用于在网络上找到相当多的资源,显示其优点/缺点和可能的用例。
  • @Marco13 是的,这很有用!
  • 据我所知,这不是“标准”装饰器模式,而且我的案例不适合装饰器模式案例(我需要向类添加新功能而不是“扩展”装饰类的功能,例如 Coffee Milk 场景)

标签: java design-patterns wrapper


【解决方案1】:
  • 首先,您的private wrappedSequence = null; 没有类型。 我想你的意思是private Sequence wrappedSequence = null;

  • 其次,在您的示例中,您将永远无法实例化任何类,因为它们都在构造函数中收到另一个Sequence,并且无法创建Sequence 的第一个实例。

  • 第三,组合优于继承是一个好方法,如果你真的需要的话。通常,当您需要隐藏或保护对被包装对象的访问时,您会包装一个对象。在您的情况下,在包装器中,您将公开被包装对象的所有方法。然后,您创建将影响包装对象的新方法,但不影响包装对象。

你可能需要的只是一个普通的继承场景:

我想向您详细介绍一下这个 Java 场景: 我有一个名为Sequence 的简单接口,它执行一些基本操作。现在我想在一个单独的类中实现一些额外的方法,称为SequenceWrapper,它实现了上面定义的Sequence。这是一些示例代码来解释我的意思:

public interface Sequence {
    public void methodOne();
    public int methodTwo();
}

public abstract class AbstractSequence  implements Sequence {


    public SequenceWrapper( ){  }

    public void methodOne(){
        //basic behavior here
    }

    public int methodTwo(){
         //basic behavior here

    }
}

public class ConcreteSequence extends AbstractSequence {
    public ConcreteSequence ( ){
         super( );
    }

    // Just an example
    public int addMethodOne(){
         int a =  methodTwo();
         return a + 3;
    }        
}


public class ConcreteSequenceTwo extends AbstractSequence {
    public ConcreteSequenceTwo( ){
         super( );
    }

    public int addMethodTwo(){
         int a =  methodTwo();
         return a + 30;
    }
}

【讨论】:

  • 您好,Carlos,感谢您的快速响应!我已经实现了一些具体的序列类,但我没有在示例中报告它们(对不起我的错!)。我不想实现继承方案,因为我想将序列的实现与其余代码分开(我有一些压缩的序列类比其他序列类“慢”,但它们需要更少的内存)
  • 无论如何,这并不意味着你需要一个包装器,你可以通过正确的继承来实现相同的目标。在任何范围内,如果您修复了我的第一点,而第二点已经修复,并且您认为您确实需要一个包装器,您可以完美地使用它,因为它是一种常见且更容易的方法(比策略或装饰器更容易)模式)。这里的任何偏好大多是基于意见的
  • 我想使用策略模式,但我需要我的 Context 类作为 Strategy 类的实例:我的 WrappedSequence 必须是 Sequence,因为我有一些读者以及使用Sequence 作为输入和输出的编写器。
猜你喜欢
  • 2023-01-07
  • 2010-09-10
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2021-02-24
相关资源
最近更新 更多