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 - Fatal编程技术网

Design patterns 基于枚举值编写方法而不陷入代码气味

Design patterns 基于枚举值编写方法而不陷入代码气味,design-patterns,Design Patterns,假设我有一个文档(word文档) 我有一个枚举,它将指示如何从文档中提取数据。因此,如果我只想要文本、图像或两者(枚举的3个成员) 我有一个基于此枚举的case语句,但在不陷入代码气味的情况下,如何编写不太重复的代码?对于开关中的每个条件,我应该有一个单独的方法(最简单的方法),还是一个接受参数的方法(比如枚举的值),然后使用if语句来表示if(xyz)do abc,依此类推 或者有没有更快、更有效的方法?我会使用策略模式结合工厂,根据枚举值创建适当的策略编辑正如其他人指出的那样,您也可以通过地

假设我有一个文档(word文档)

我有一个枚举,它将指示如何从文档中提取数据。因此,如果我只想要文本、图像或两者(枚举的3个成员)

我有一个基于此枚举的case语句,但在不陷入代码气味的情况下,如何编写不太重复的代码?对于开关中的每个条件,我应该有一个单独的方法(最简单的方法),还是一个接受参数的方法(比如枚举的值),然后使用if语句来表示if(xyz)do abc,依此类推


或者有没有更快、更有效的方法?

我会使用策略模式结合工厂,根据枚举值创建适当的策略编辑正如其他人指出的那样,您也可以通过地图确定正确的策略。工厂是我的选择,因为它只封装逻辑,不需要任何数据存储

public interface IExtractionStrategy
{
    object Extract( Document doc );  // or what ever result is best
}

public class TextExtractionStrategy : IExtractionStrategy
{
    public object Extract( Document doc )
    {
     .... algorithm for extracting text...
    }
}

public class ImageExtractionStrategy : IExtractionStrategy
{
    public object Extract( Document doc )
    {
     .... algorithm for extracting images...
    }
}


public static class StrategyFactory
{
     IExtractionStrategy GetStrategy( ExtractionEnum strategyType )
     {
         switch (strategyType)
         {
             case ExtractionEnum.Text:
                 return new TextExtractionStrategy();
                 break;
             case ExtractionEnum.Image:
                 return new ImageExtractionStrategy();
                 break;

             ...
         }
     }
}

一个解决方案可以是为您想要提取数据的每一种方式都使用一个类。每个类将完成所有提取工作,并且它们可以有一个通用的IExtract接口。 您只需根据枚举返回接口,然后只需调用接口上的方法。

使用将数据处理方法与其选择分离


然后,您可以使用一个直接的
映射
来保持从枚举到提取策略的关系,甚至可以让枚举的每个实例都包含对其自身策略的引用。

由于在不知道确切代码的情况下很难给出一般性陈述,我只能建议您阅读本文:

斯科特·汉斯曼


由于您的枚举中只有3个值,因此任何模式(如策略模式或映射)都可能是架构上的过度使用(请不要误会,这些模式在较大的枚举中可能非常有用)。这一切都是关于为一个特定问题选择正确的解决方案。

更换一个灯泡需要多少课程

也许这只是术语上的差异,但在我看来,这是一个需要调度表的简单例子:

use constant EXTRACT_TEXT => 1, EXTRACT_IMAGES => 2, EXTRACT_BOTH => 3;
my %extractor = (
    (EXTRACT_TEXT) => \&extract_text,
    (EXTRACT_IMAGES) => \&extract_images,
    (EXTRACT_BOTH) => \&extract_both,
);
...
die "no extractor found for $enum_value" if ! $extractor{ $enum_value };
$extractor{ $enum_value }->( $document_info );
我会做(伪代码):


如果您使用的是Java枚举,那么您可以利用它们实际上是对象这一事实:

enum ExtractionEnum {
    IMAGE {
        public byte[] extract(InputStream is) { ... }
    },

    TEXT {
        public byte[] extract(InputStream is) { ... }
    };

    public abstract byte[] extract(InputStream is);
}

// ...
public void doSomething(ExtractionEnum type) {
    byte[] data = type.extract(getInputStream());
    ...
}

我不确定我是否更喜欢这种策略模式或好的ol'
切换
/
案例
,但它确实有效。

不同意过度使用。该策略将算法分离到单独的容器中,并允许您通过接口实现。这两个良好实践都可以减少耦合并提高可测试性。工厂和地图是一个悬而未决的问题,但工厂更灵活。两个月后,他的老板说“你能写点东西把文档中的脚注|参考书目| URL |等也去掉吗。及其任何组合,按在文件中的出现顺序排列。并不是说这可能会破坏上面所有的策略模式。在这一点上,我重构它们使它们可组合,可能使用Decorator,并更改我的工厂以返回正确组合的策略。如果你使用的是一个好的模式,那么为什么未来的需求可能会破坏当前的解决方案这一事实是一个问题呢?JeeBee,Google for YAGNI,别再强调未知了。:)假设他正在使用Perl(?),当然,他没有说他在使用Perl(?)。不过,他的其他Qs和As倾向于暗示他是个C#guy。不,我不是这么想的。我是跟随别人的榜样,选择了一种武断的语言作为例子。调整以适应(适用于可能的语言)。始终希望看到设计模式的使用。
enum ExtractionEnum {
    IMAGE {
        public byte[] extract(InputStream is) { ... }
    },

    TEXT {
        public byte[] extract(InputStream is) { ... }
    };

    public abstract byte[] extract(InputStream is);
}

// ...
public void doSomething(ExtractionEnum type) {
    byte[] data = type.extract(getInputStream());
    ...
}