如何为几个Java枚举添加常用方法? (抽象类祖先?) [英] How to add common methods for a few Java enums? (abstract class ancestor?)

查看:113
本文介绍了如何为几个Java枚举添加常用方法? (抽象类祖先?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些Java枚举这样

I have a few Java enums as such

public enum Aggregation
{
    MORTGAGE( "Mortgage" ),
    POOLS( "Pools" ),
    PORTFOLIO( "Portfolio" );

    private Aggregation( final String name )
    {
        m_Name = name;
    }
    private String m_Name;
    static Map< String, Aggregation > c_LOOKUP =
        new HashMap< String, Aggregation >();
    static {
        for (Aggregation agg:values()){
            c_LOOKUP.put(agg.m_Name,agg);
        }
    }

    public Aggregation lookup(String name){
        return c_LOOKUP.get( name );
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}

public enum Interval
{
    MONTHLY( "Monthly" ),
    QUARTLY( "Quartly" ),
    SEMIANNUALLY( "SemiAnnually" ),
    ANNUALLY("Annually");

    private Interval( final String name )
    {
        m_Name = name;
    }
    private String m_Name;
    static Map< String, Interval > c_LOOKUP =
        new HashMap< String, Interval >();
    static {
        for (Interval agg:values()){
            c_LOOKUP.put(agg.m_Name,agg);
        }
    }

    public Interval lookup(String name){
        return c_LOOKUP.get( name );
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}

如你所见,有很多代码重复这里。如果有一种方法来引入像抽象的共同祖先类,这将是很好的。但是java枚举不是固有的。最好的方法是什么?谢谢。

As you can see, there are quite some code duplication here. It would be nice if there is a way to introduce something like an abstract common ancestor class. But java enum cannot inherent. What would be the best approach? Thanks.

编辑:
我已经编写了一个类似于ŁukaszBachman和missingfacktor的版本。

I have work out a version similar to ŁukaszBachman and missingfacktor

static public enum Aggregation
{
    MORTGAGE( "Mortgage" ),
    POOLS( "Pools" ),
    PORTFOLIO( "Portfolio" );

    private final String m_Name;

    final static private ReverseDictionary< Aggregation > c_DICTIONARY =
        new  ReverseDictionary< Aggregation >( Aggregation.class );

    static public Aggregation lookup( final String name )
    {
        return c_DICTIONARY.lookup( name );
    }

    private Aggregation( final String name )
    {
        m_Name = name;
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}

static public enum Interval
{
    MONTHLY( "Monthly" ),
    QUARTLY( "Quartly" ),
    SEMIANNUALLY( "SemiAnnually" ),
    ANNUALLY( "Annually" );

    private final String m_Name;
    final static private ReverseDictionary< Interval > c_DICTIONARY =
        new ReverseDictionary< Interval >( Interval.class );

    static public Interval lookup( final String name )
    {
        return c_DICTIONARY.lookup( name );
    }

    private Interval( final String name )
    {
        m_Name = name;
    }

    @Override
    public String toString()
    {
        return m_Name;
    }
}


static public class ReverseDictionary< E extends Enum< E >>
{
    Map< String, E > c_LOOKUP = new HashMap< String, E >();

    public ReverseDictionary( final Class< E > enumClass )
    {
        for( final E agg : EnumSet.allOf( enumClass ) )
        {
            c_LOOKUP.put( agg.toString(), agg );
        }
    }

    public E lookup( final String name )
    {
        return c_LOOKUP.get( name );
    }

}

我看到一些推理。但是,这还不是很令人满意。

I see some reasoning. However, it is still not very satisfactory.


  1. 因为 lookup(String)不同的返回类型

  2. 我可以理解, lookup(String)并不是真正的重复,而是一个规范,但我仍然觉得m_Name字段和toString()逻辑有点多余。我们真的指定了一个类别的枚举,在我看来,它似乎是是一个关系。

  1. It is hard to define the interface for lookup(String) because of the different return type
  2. I can appreciate that the lookup(String) is not really duplication but a specification, but I am still feel that m_Name field and the toString() logic is a bit redundant. We are really specifying one category of enum, and it seems to be "is-a" relationship in my opinion.


推荐答案

喜欢继承界面的缘故。由于枚举是类(不是常规的,而是类),您可以创建一些包含共享逻辑的字段,让枚举实现您的界面,并将实现委托给该字段。

Favor composition over inheritance and programming for the sake of interfaces. Since Enums are classes (not regular, but still - classes) you can create some field containing shared logic, let the enum implement you interface and delegate implementation to this field.

相关代码片段:

共享界面

public interface MyInterface {

    void someMethod();

}

逻辑实现

public class MyInterfaceImpl implements MyInterface {

    public void someMethod() {
        System.out.println("Do smth...");
    }

}

strong>

First enum

public enum EnumA implements MyInterface {
    ;

    private MyInterface impl = new MyInterfaceImpl();

    public void someMethod() {
        impl.someMethod();
    }

}

第二个枚举

Second enum

public enum EnumB implements MyInterface {
    ;

    private MyInterface impl = new MyInterfaceImpl();

    public void someMethod() {
        impl.someMethod();
    }

}

请注意 EnumA EnumB 不是真正的代码重复,因为这是一个简单的代理(在我看来是有效的)。还请注意,使用界面,一切都很好地粘在一起。

Please do note that EnumA and EnumB are not really code duplication, since that is plain delegation (valid, in my opinion). Also please note that everything is nicely glued together by using interface.

这篇关于如何为几个Java枚举添加常用方法? (抽象类祖先?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆