模板方法模式,带有任意异常抛出功能。

huangapple go评论90阅读模式
英文:

Template method pattern with arbitrary exception throwing

问题

假设我有一个抽象类 Base,其中有一个具体方法 execute 和三个抽象方法 stepOnestepTwostepThree...

  1. public abstract class Base {
  2. protected abstract void stepOne();
  3. protected abstract void stepTwo();
  4. protected abstract void stepThree();
  5. public final void execute() {
  6. // 做一些事情
  7. stepOne();
  8. // 做一些事情
  9. stepTwo();
  10. // 做一些事情
  11. stepThree();
  12. // 做一些事情
  13. }
  14. }

...并且有一个具体类 Sub1 继承自该抽象类:

  1. public class Sub1 extends Base {
  2. protected void stepOne() {
  3. //...
  4. }
  5. protected void stepTwo() {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

现在假设我有一个第二个子类 Sub2,在 stepOnestepTwo 方法中可能会抛出已检查异常:

  1. public class Sub2 extends Base {
  2. protected void stepOne() throws Exception1 {
  3. //...
  4. }
  5. protected void stepTwo() throws Exception2 {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

我希望按以下方式使用这些类:

  1. Sub1 s1 = new Sub1();
  2. try {
  3. s1.execute();
  4. } catch (Exception1 e1) {
  5. // 处理 e1
  6. } catch (Exception2 e2) {
  7. // 处理 e2
  8. }
  9. Sub2 s2 = new Sub2();
  10. s2.execute();

显然,这并不起作用,因为 Base 类中的方法没有声明任何异常。

如何在实现类中任意地抛出异常呢?
有没有一种方法,不必在 execute 方法中声明 throws Exception,也不必始终使用 try-catch 块?
我还想避免将 execute 中的公共逻辑重复放入其子类中。
在这种情况下,有什么最佳解决方案?是否有更好的设计模式?

英文:

Let's say I have an abstract class Base that has a concrete method execute and three abstract methods stepOne, stepTwo and stepThree...

  1. public abstract class Base {
  2. protected abstract void stepOne();
  3. protected abstract void stepTwo();
  4. protected abstract void stepThree();
  5. public final void execute() {
  6. //do stuff
  7. stepOne();
  8. //do stuff
  9. stepTwo();
  10. //do stuff
  11. stepThree();
  12. //do stuff
  13. }
  14. }

...and is subclassed by a concrete class Sub1

  1. public class Sub1 extends Base {
  2. protected void stepOne() {
  3. //...
  4. }
  5. protected void stepTwo() {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

Now let's suppose I have a second subclass Sub2 that can throw a checked exception in stepOne and stepTwo

  1. public class Sub2 extends Base {
  2. protected void stepOne() throws Exception1 {
  3. //...
  4. }
  5. protected void stepTwo() throws Exception2 {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

I would like to use these classes as follows:

  1. Sub1 s1 = new Sub1();
  2. try {
  3. s1.execute();
  4. } catch (Exception1 e1) {
  5. //handle e1
  6. } catch (Exception2 e2) {
  7. //handle e2
  8. }
  9. Sub2 s2 = new Sub2();
  10. s2.execute();

Clearly this doesn't work since the methods in Base aren't declared with any exceptions.

How can I have arbitrary exception throwing in the implementing classes?
Is there a way without having to declare execute with throws Exception and always having to use a try-catch for it?
I'd also like to avoid duplicating the common logic in execute into its subclasses.
What's the best solution here? Is there a better design pattern for this?

答案1

得分: 0

这是如何通过使Base类方法抛出通用异常来解决这个问题的方法:

  1. public abstract class Base<E1 extends Exception, E2 extends Exception, E3 extends Exception> {
  2. protected abstract void stepOne() throws E1;
  3. protected abstract void stepTwo() throws E2;
  4. protected abstract void stepThree() throws E3;
  5. public final void execute() throws E1, E2, E3 {
  6. // 执行一些操作
  7. stepOne();
  8. // 执行一些操作
  9. stepTwo();
  10. // 执行一些操作
  11. stepThree();
  12. // 执行一些操作
  13. }
  14. }

您可以通过扩展Base<RuntimeException, RuntimeException, RuntimeException>创建一个不抛出任何受检异常的子类,如下所示:

  1. public class Sub1 extends Base<RuntimeException, RuntimeException, RuntimeException> {
  2. protected void stepOne() {
  3. //...
  4. }
  5. protected void stepTwo() {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

以下是如何创建一个在某些步骤中可以抛出受检异常的子类:

  1. public class Sub2 extends Base<Exception1, Exception2, RuntimeException> {
  2. protected void stepOne() throws Exception1 {
  3. //...
  4. }
  5. protected void stepTwo() throws Exception2 {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

您可以像这样使用这些类:

  1. Sub2 s2 = new Sub2();
  2. try {
  3. s2.execute();
  4. } catch (Exception1 e1) {
  5. // 处理 e1
  6. } catch (Exception2 e2) {
  7. // 处理 e2
  8. }
  9. Sub1 s1 = new Sub1();
  10. s1.execute();

注意:代码部分不需要翻译,已经包含在您提供的原始文本中。

英文:

Here is how you can solve this problem by making Base class methods throw generic exceptions:

  1. public abstract class Base&lt;E1 extends Exception, E2 extends Exception, E3 extends Exception&gt; {
  2. protected abstract void stepOne() throws E1;
  3. protected abstract void stepTwo() throws E2;
  4. protected abstract void stepThree() throws E3;
  5. public final void execute() throws E1, E2, E3 {
  6. //do stuff
  7. stepOne();
  8. //do stuff
  9. stepTwo();
  10. //do stuff
  11. stepThree();
  12. //do stuff
  13. }
  14. }

You can create a subclass that doesn't throw any checked exceptions by extending Base&lt;RuntimeException, RuntimeException, RuntimeException&gt; as follows:

  1. public class Sub1 extends Base&lt;RuntimeException, RuntimeException, RuntimeException&gt; {
  2. protected void stepOne() {
  3. //...
  4. }
  5. protected void stepTwo() {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

And here is how you can create a subclass that can throw a checked exception in some steps:

  1. public class Sub2 extends Base&lt;Exception1, Exception2, RuntimeException&gt; {
  2. protected void stepOne() throws Exception1 {
  3. //...
  4. }
  5. protected void stepTwo() throws Exception2 {
  6. //...
  7. }
  8. protected void stepThree() {
  9. //...
  10. }
  11. }

You can use these classes as follows:

  1. Sub2 s2 = new Sub2();
  2. try {
  3. s2.execute();
  4. } catch (Exception1 e1) {
  5. //handle e1
  6. } catch (Exception2 e2) {
  7. //handle e2
  8. }
  9. Sub1 s1 = new Sub1();
  10. s1.execute();

huangapple
  • 本文由 发表于 2020年9月13日 20:49:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63870971.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定