簡體   English   中英

兩個相關的枚舉映射?

[英]Two related enums mapping?

我有兩個相關的枚舉。

Enum1:

public enum HttpMethodName 
{
    GET, POST, PUT, DELETE; 
}

Enum2:

public enum ProtocolOperation {
    CREATE(1), RETRIEVE(2), UPDATE(3), DELETE(4), NOTIFY(5);


    private BigInteger operationId;

    public BigInteger getOperationId() {
        return operationId;
    }

    private ProtocolOperation(int operationId) {
        this.operationId = BigInteger.valueOf(operationId);
    }
}

枚舉值的映射為:

Create--> POST
Retrieve--> GET
Update--> PUT
Delete--> DELETE
Notify---> POST

因此,除了POST情況之外,值之間存在一對一的映射,其中可以根據條件CreateNotify兩個值。

我在考慮將映射保持為List

    public enum HttpMethodName 
    {

        POST(new List(ProtocolOperation.CREATE, ProtocolOperation.NOTIFY)) ,GET ( new List(ProtocolOperation.RETRIEVE) ) ,
PUT (new List(ProtocolOperation.UPDATE) ,DELETE(new List(ProtocolOperation.DELETE) ;

        List<ProtocolOperation > ops;
        HttpMethodName (List<ProtocolOperation> ops)
        {
            this.ops = ops;
        }
    }

還有更好的方法嗎?

編輯:

我希望從HttpMethodName <----> ProtocolOperation 兩種方式進行映射

為什么你發現你目前的方法不令人滿意?

如果不了解您的顧慮,我只能建議刪除樣板:

import static ProtocolOperation.*;

public enum HttpMethodName {
    GET(RETRIEVE),
    POST(CREATE, NOTIFY),
    PUT(UPDATE),
    DELETE(ProtocolOperation.DELETE);

    final List<ProtocolOperation> ops;

    HttpMethodName(ProtocolOperation... ops) {
        this.ops = Collections.unmodifiableList(Arrays.asList(ops));
    }
}

UPD:

如果你想以兩種方式進行映射,那么首先將ProtocolOperationHttpMethodName映射硬編碼(因為它不需要列表)並在MttpMethodName創建一個簡單的搜索方法是MttpMethodName

public enum ProtocolOperation {
    CREATE(1, HttpMethodName.POST),
    RETRIEVE(2, HttpMethodName.GET),
    UPDATE(3, HttpMethodName.PUT),
    DELETE(4, HttpMethodName.DELETE),
    NOTIFY(5, HttpMethodName.POST);

    private BigInteger operationId;
    private HttpMethodName methodName;

    public BigInteger getOperationId() {
        return operationId;
    }

    public HttpMethodName getMethodName() {
        return methodName;
    }

    private ProtocolOperation(int operationId, HttpMethodName httpMethodName) {
        this.methodName = httpMethodName;
        this.operationId = BigInteger.valueOf(operationId);
    }
}

public enum HttpMethodName {
    GET,
    POST,
    PUT,
    DELETE;

    List<ProtocolOperation> getProtocolOperations() {
        List<ProtocolOperation> ops = new ArrayList<ProtocolOperation>(2);
        for (ProtocolOperation op : ProtocolOperation.values()) {
            if (op.getMethodName() == this) {
                ops.add(op);
            }
        }
        return ops;
    }
}

由於您具有常量和少量值,因此無需在HttpMethodName創建最終靜態映射以提供向后映射,線性搜索對於您的情況來說足夠快。

創建從ProtocolOperationHttpMethodName的映射,就像您用箭頭所示,因此它們是簡單的引用,而不是列表。

然后,反向映射可以是一個靜態方法,它迭代匹配的5個枚舉值。 只有5個值,所以順序搜索足夠快,除非你是在一個非常緊湊的循環中做的事情,在這種情況下這是不可能的。 此外,在分析器說您遇到問題之前,不應編寫性能代碼。

您按照以下方式遵循映射:

// From ProtocolOperation to HttpMethodName
HttpMethodName method = ProtocolOperation.CREATE.getHttpMethodName();

// From HttpMethodName to ProtocolOperation
ProtocolOperation op = ProtocolOperation.forMethod(HttpMethodName.GET);

執行:

public enum HttpMethodName 
{
    GET, POST, PUT, DELETE; 
}
public enum ProtocolOperation {
    CREATE  (1, HttpMethodName.POST),
    RETRIEVE(2, HttpMethodName.GET),
    UPDATE  (3, HttpMethodName.PUT),
    DELETE  (4, HttpMethodName.DELETE),
    NOTIFY  (5, HttpMethodName.POST);

    private final int            operationId;
    private final HttpMethodName httpMethodName;

    private ProtocolOperation(int operationId, HttpMethodName httpMethodName) {
        this.operationId = operationId;
        this.httpMethodName = httpMethodName;
    }

    public int getOperationId() {
        return this.operationId;
    }

    public HttpMethodName getHttpMethodName() {
        return this.httpMethodName;
    }

    public static List<ProtocolOperation> forMethod(HttpMethodName httpMethodName) {
        List<ProtocolOperation> ops = new ArrayList<>();
        for (ProtocolOperation op : values())
            if (op.httpMethodName == httpMethodName)
                ops.add(op);
        return ops;
    }
}

我會將邏輯與枚舉分開。 你的方法是緊密耦合,彈性較小。 有了這個帶變換metod的庫,你就更靈活了

private static final Map<HttpMethodName , ProtocolOperation> mapping = new HashMap<>();
static {
mapping .put(Create, POST);
// rest of methods
}

這里是你的映射方法的主體(我正在使用Jdk8):

public static Optional<HttpMethodName > map(ProtocolOperation  op){
 if (!mapping.containsKey(op)){
   return Optional.empty();
 }
  return Optional.of(mapping.get(op));
}

簡而言之:枚舉不應該有任何與之關聯的業務邏輯,對於映射和轉換,應該使用外部方法(utils)。

更新 :正如@Andreas正確指出的那樣,在這個特定的例子中,映射是固定的,不應該擴展,你可以保持初始化的方式:

 HttpMethodName(ProtocolOperation... ops) {
    this.ops = Collections.unmodifiableList(Arrays.asList(ops));
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM