简体   繁体   English

使用枚举实现策略模式

[英]Implement strategy pattern with enum

I'm trying to create a service to handle different payment methods.我正在尝试创建一项服务来处理不同的付款方式。 I want to implement strategy pattern.我想实施策略模式。 I'd like to have an enum with the different payment methods.我想要一个具有不同付款方式的枚举。 This is an example of what I have:这是我所拥有的一个例子:

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();
}

somewhere in the client:客户端某处:

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

The problem with this approach is that method "pay" could be have a lot of logic so I'd like to have it in a different class.这种方法的问题是“支付”方法可能有很多逻辑,所以我想把它放在不同的 class 中。 I could define an interface like this:我可以定义这样的接口:

public interface Pay {
    void pay();
}

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

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

somewhere in the client:客户端某处:

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

but I like much more how it looks with Enum and that the reason to keep that way.但我更喜欢 Enum 的外观以及保持这种方式的原因。 Thanks谢谢

I don't recommend implementing the logic inside an enum because you will likely need to make calls to external services to implement a payment, and therefore you'll want to be able to inject those dependencies in your payment implementations.我不建议在枚举中实现逻辑,因为您可能需要调用外部服务来实现支付,因此您希望能够在支付实现中注入这些依赖项。 Enums being statically initialized, they are not friendly at all for injection.枚举是静态初始化的,它们对注入一点也不友好。 It can be ok to put some logic in enumerations, although they should generally largely remain simple data, but this case seems too complex for being handled in enums.可以将一些逻辑放入枚举中,尽管它们通常应该在很大程度上保持简单数据,但这种情况似乎过于复杂,无法在枚举中处理。 You can have an enum to decide the type of payment and then have a mapping from each enum item to a singleton of a payment implementations if you want, but the logic should be decoupled from the enum.如果需要,您可以使用枚举来决定支付类型,然后将每个枚举项映射到支付实现的 singleton,但逻辑应该与枚举分离。

You don't need the if statement in the client.您不需要客户端中的 if 语句。 If you declare set Pay with a parameter of type Pay (the interface), you can invoke it passing every class which implements the Pay interface.如果您使用Pay类型的参数(接口)声明 set Pay,则可以通过每个实现 Pay 接口的 class 来调用它。 Your code becames你的代码变成了

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

The enum is useless in this case.在这种情况下,枚举是无用的。 If you want to give to each payment methods a numerical id, add it to the interface.如果您想为每种付款方式提供一个数字 ID,请将其添加到界面中。

It can be developed like this可以这样开发

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

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM