Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 枚举和常量_Design Patterns_Enums_Constants - Fatal编程技术网

Design patterns 枚举和常量

Design patterns 枚举和常量,design-patterns,enums,constants,Design Patterns,Enums,Constants,有没有比将枚举声明为更好的方法 public enum DepthNumberSize { Bit1 = 1, Bit4 = 4, Bit8 = 8, Bit16 = 16, Bit32 = 32 } 每次使用执行相关数据块的操作时,开关语句如下: switch(size) { case DepthNumberSize.Bit1: buffer[i++] = input[j] & 1; buffer[i++] = (in

有没有比将枚举声明为更好的方法

public enum DepthNumberSize
{
   Bit1 = 1,
   Bit4 = 4,
   Bit8 = 8,
   Bit16 = 16,
   Bit32 = 32
}
每次使用执行相关数据块的操作时,开关语句如下:

switch(size)
{
    case DepthNumberSize.Bit1:
       buffer[i++] = input[j] & 1;
       buffer[i++] = (input[j] >> 1) & 1;
       // cut
    case DepthNumberSize.Bit8:
       buffer[i++] = input[j++];
       break;
    case DepthNumberSize.Bit16:
       buffer[i++] = input[j] | (input[j] << 8);
       j += 2;
       break;
    // cut
}
开关(尺寸)
{
案例深度NumberSize.Bit1:
缓冲区[i++]=输入[j]&1;
缓冲区[i++]=(输入[j]>>1)&1;
//削减
案例深度编号Size.Bit8:
缓冲区[i++]=输入[j++];
打破
案例深度编号Size.Bit16:

buffer[i++]=input[j]|(input[j]您可以这样做:

    interface IBitSize
    {
        object DoStuff();
    }

    class Bit1 : IBitSize
    {
        public object DoStuff()
        {
            buffer[i++] = input[j] & 1;
            buffer[i++] = (input[j] >> 1) & 1;
            return something.
        }
    }

    class Bit2 : IBitSize
    {
        public object DoStuff()
        {
           //Do different stuff here.
        }
    }
    IBitSize size = new Bit1();
    size.DoStuff();
然后你可以这样称呼它:

    interface IBitSize
    {
        object DoStuff();
    }

    class Bit1 : IBitSize
    {
        public object DoStuff()
        {
            buffer[i++] = input[j] & 1;
            buffer[i++] = (input[j] >> 1) & 1;
            return something.
        }
    }

    class Bit2 : IBitSize
    {
        public object DoStuff()
        {
           //Do different stuff here.
        }
    }
    IBitSize size = new Bit1();
    size.DoStuff();

这样您就可以卸下开关。

我想您可能需要澄清一些问题

但是,可以通过将枚举强制转换为字节(枚举的默认类型)来获取枚举的基础值


将返回8。这会更好,因为您实际上是在使用为枚举提供的自定义值(它们默认为0、1、2等)它甚至可以让您摆脱整个开关语句,允许您编写一个通用代码块,使用EnUM变量“大小”的基础值生成期望的结果。

您可以考虑使用类,而可能用工厂方法返回正确的具体类型,例如:

abstract class BitManipulator
{
    public abstract void Manipulate(
        byte[] buffer, byte[] input, ref int i, ref int j);

    public static BitManipulator Create(int size)
    {
        switch (size)
        {
            case 1: return new Bit1Manipulator();
            case 2: return new Bit2Manipulator();
            // etc.
        }
    }
}

class Bit1Manipulator : BitManipulator
{
    public override void Manipulate(
        byte[] buffer, byte[] input, ref int i, ref int j)
    {
        buffer[i++] = input[j] & 1;
        buffer[i++] = (input[j] >> 1) & 1;
    }
}

// etc. for other classes
然后,您只需要一个switch语句,所有逻辑都可以包含在特定于大小的类中,而不是在代码的其余部分的switch语句中乱七八糟。当然,对于需要执行的每种类型,您可以有多个方法


很难说这是否适合您的应用程序,因为没有太多的上下文,但这是另一种可以在这种情况下使用的方法。

在这种通用模式下工作,是的:

   Bit1 = 0x00000001,
   Bit2 = 0x00000002,
   Bit3 = 0x00000004,
   Bit4 = 0x00000008,
   Bit5 = 0x00000010

实际上,这取决于需要什么。如果实际上需要满足任意数量的位,那么最好有一个循环,从源代码中逐个提取位,组装值,然后在读取正确数量的位后将其写入目标。但是,如果真的只有一组固定的宽度,则切换和case是很好的(在我看来),因为它可能更清楚发生了什么。没有必要让代码比需要的更通用

在这两种情况下,最好将所有这些隐藏在函数或其他抽象手段后面,以便更容易重用(“每次”都表明这段代码出现在多个地方),并且决策结果只在一个地方编写

(我要进一步说明的是,如果使用枚举来表示某个固定的位计数集,则每个枚举器都应该具有任意值,而不是相应的位计数。这更好地表明,名称在任何方面都不表示任意位计数,而只是一个表示支持的位计数之一的标记。)


(同样,当读取16位时,其中一个字节可能来自
input[j+1]

此枚举的作用是什么?为什么不直接写入16而不是DepthNumberSize。Bit16?枚举阻止使用幻数。“1”表示一,“Bit1”表示“第一位”。这是有道理的。@AR,我正在尝试重构它。我曾考虑过使用整数,但开关看起来会更难看:-)我认为当实际位的数量需要接口(或抽象类)时,接口(或抽象类)可能有属性NumberOfBits(?)