带有枚举的实现策略模式

问题描述 投票:0回答:3

我正在尝试创建一种服务来处理不同的付款方式。我想实施策略模式。我想使用不同的付款方式来枚举。这是我所拥有的一个例子:

public enum Pay {
    CREDITCARD(1) {
        @Override
        public void pay() {
            System.out.println("Payment functionality");
        }

    },
    OTHERMETHOD(2) {
        @Override
        public void pay() {
            System.out.println("Payment functionality");
        }
    };

    private int id;

    Payment(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public abstract void pay();
}

客户端中的某个位置:

user.setPay(Pay.CREDITCARD);
user.pay();

这种方法的问题在于,“ pay”方法可能有很多逻辑,所以我想将其放在另一个类中。我可以这样定义一个接口:

public interface Pay {
    void pay();
}

public class CreditCard implements Pay {
    @Override
    public void pay() {
    }
}

public class OtherMethod implements Pay {
    @Override
    public void pay() {
    }
}

客户端中的某个位置:

if (method.equals("creditcard")) {
    user.setPay(new CreditCard());
    user.pay();
}
else {
    user.setPay(new OtherMethod());
    user.pay();
}

但是我更喜欢Enum的外观以及保持这种状态的原因。谢谢

java design-patterns
3个回答
2
投票

我不建议在枚举内部实现逻辑,因为您可能需要调用外部服务来实现付款,因此,您希望能够将这些依赖项注入您的付款实现中。枚举是静态初始化的,它们对于注入根本不友好。可以将一些逻辑放在枚举中可以,尽管它们通常在很大程度上应保留为简单数据,但是这种情况似乎太复杂了,无法在枚举中进行处理。您可以有一个枚举来决定付款的类型,然后根据需要从每个枚举项到单个付款实现的映射,但是逻辑应与枚举解耦。


1
投票

您在客户端不需要if语句。如果使用类型为Pay的参数(接口)声明set Pay,则可以通过实现Pay接口的每个类来调用它。您的代码成为

user.setPay(new CreditCard()); //or every class which implements Pya interface
user.pay();

在这种情况下,枚举是无用的。如果您想给每种付款方式一个数字ID,请将其添加到界面中。


1
投票

可以这样开发

public enum PayType {
   CREDITCARD(new CreditCard()),
   OTHER(new OtherMethod();

   private Pay pay;
   PayType(Pay pay) {
      this.pay = pay;
   }

}
© www.soinside.com 2019 - 2024. All rights reserved.