代码之家  ›  专栏  ›  技术社区  ›  blizpasta

我应该子类化还是使用枚举?

  •  3
  • blizpasta  · 技术社区  · 15 年前

    我有许多T数组要读。 每个T数组可以表示A、B或C类型的数据。 A:一份名单 B:一个T

    当我读取一个T数组时,我将能够得到一个T的列表,并通过读取列表中的第一个T来确定它是类型a、B还是C。

    1)

    enum {A, B, C};
    
    class X {
        enum dataType;//A, B or C
        List<T> data;//just store all as list of T
        //other essential methods/properties
        //throws exception if an instance cannot fit into either A, B or C.
        X(T[] input)
        {
            //read input
        }
    }
    

    2)

    abstract class X
    {
        abstract int length{get;}
        //and other common essential methods/properties
    }
    class A : X
    {
        List<T> data;
    }
    class B : X
    {
        T data;
    }
    class C : X
    {
        T data1, data2, data3;
    }
    class ConcreteX: X
    {
        List<T> data;
        ConcreteX(T[] input)
        {
            //reads input and stores T(s) into data
        }
    }
    class XFactory
    {
        getX(T[] input)
        {
            ConcreteX conX = new ConcreteX(input);
            //depending on whether it's A, B or C, create an instance of A, B, 
            //or C and map the corresponding fields from conX to the instance.
            //return that instance
        }
    }
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   Gabriel Ščerbák    15 年前

    在OOP中,第二种方法更容易接受。原因是,如果要根据类型(A、B或C)添加行为,在第一种情况下,必须检查枚举值。在第二种情况下,将特定行为添加到具体类型A、B和C中。如果您决定添加另一个类型或删除其中一个,在第一种情况下,您必须更改类型检查的所有内容,在第二种情况下,更改只发生在一个地方。

        2
  •  0
  •   aqwert    15 年前

    如果需要泛型类只接受一系列特定类型,那么在数组中记录接受的类型可能会更容易。由于您没有指定特定的语言,我将使用c#,尽管我不能保证它可以用其他语言完成。我想如果语言能够在运行时创建该类型的实例,那么它们也应该能够检查该类型

    private static List<Type> _acceptedTypes = { typeof(Type1), typeof(Type2) ... }
    
    X(T[] input)
    {
       if(!_acceptedTypes.Contains(typeof(T)))
       {
            throw new SomeException();
       }
       ...
    }
    

    尽管就个人而言,这并不是真正理想的,因为这是一个运行时检查(即,只有在尝试使用类时才知道)。最好能够以.net所拥有的通用方式应用约束,但只针对一种类型(这对您的情况没有帮助)。

    推荐文章