简体   繁体   English

实现多种条件逻辑的最佳模式

[英]Best pattern to implement multiple conditional logic

Firstly, I have read, and searched ways to refactor conditional logic - seems that 3 main approaches are suggested : Polymorphism (haven't tried, but don't think I can apply it this situation), Enums (have used) and The Strategy Pattern (I have used several times and like it). 首先,我已经阅读并搜索了重构条件逻辑的方法-似乎建议了3种主要方法:多态(尚未尝试过,但我认为在这种情况下我不能应用它),枚举(已使用过)和策略模式(我已经使用过几次并且喜欢它)。

However I have about 6-7 boolean conditions to check, and depending whether each one is true/false I want to do something different ie 但是我有大约6-7个布尔条件要检查,并且根据每个条件是否正确,我想做不同的事情,即

true, false, false, true

false, false, true, false

true, true, ... you get the picture..

The boolean values are set by different preferences, that are all related in someway, but I need to handle differently depending on which ones are true or false. 布尔值由不同的首选项设置,这些首选项在某种程度上都相关,但是我需要根据是对还是错来进行不同的处理。 The amount of preferences could well increase as well, so something that is scalable and maintainable is what I'm after. 偏好的数量也可能会增加,所以我追求的是可扩展和可维护的东西。

I know I can use The Strategy Pattern here, but not without a lot of conditional checks first (which I'm trying to avoid). 我知道我可以在这里使用“策略模式”,但是首先要进行很多条件检查(我想避免这种情况)。

Example situation, the project centres around a music app, and specifically what to do when a track has finished, and what options dictate what happens next ie : 示例情况,该项目围绕音乐应用程序,特别是曲目结束后的操作,以及指示接下来将发生什么的选项,即:

SHUFFLE SHUFFLE

REPEAT 重复

PLAY_FROM_ALBUM_SONGS PLAY_FROM_ALBUM_SONGS

PLAY_FROM_ARTIST PLAY_FROM_ARTIST

PLAY_FROM_GENRE PLAY_FROM_GENRE

PLAY_FROM_ALL_SONGS PLAY_FROM_ALL_SONGS

So a basic example would be the first and last are true (Shuffle & Play from all songs) and rest are false. 因此,一个基本的示例将是第一个和最后一个为真(所有歌曲的随机播放和播放),其余为假。 some cases if one is true, another has to be false - you cant play all songs from your library if you're playing just an album, so when some options are chosen they automatically change other ones they directly affect. 在某些情况下,如果一个是正确的,则另一个必须是错误的-如果您仅播放专辑,则无法播放库中的所有歌曲,因此,选择某些选项后,它们会自动更改它们直接影响的其他歌曲。

Any suggestions how this sort of conditional logic, based on multiple conditions (6/7+), can be refactored so it wont look like a behemoth of ugly code. 如何重构这种基于多个条件(6/7 +)的条件逻辑的任何建议,使其看起来不会像丑陋的代码一样庞然大物。

In your example you should start by classifying the conditions. 在您的示例中,您应该首先对条件进行分类。 Some are exclusive, some may influence one another, and all can be grouped based on what part of the behaviour they specify. 有些是排他性的,有些可能会相互影响,并且都可以根据它们指定的行为的哪一部分进行分组。

In your example the classification might look like this: 在您的示例中,分类可能如下所示:

  • Song selection: FROM_ALBUM, FROM_ARTIST, FROM_GENRE, FROM_ALL_SONGS 歌曲选择:FROM_ALBUM,FROM_ARTIST,FROM_GENRE,FROM_ALL_SONGS
  • Repetition: REPEAT 重复:REPEAT
  • Order: SHUFFLE 订单:SHUFFLE

Repetition and Order each only contain one element, and song-selection is based on a hierarchy from left to right. 重复和顺序每个仅包含一个元素,歌曲选择基于从左到右的层次结构。 If FROM_ARTIST is true, FROM_ALBUM is implicitly true as well, since an album is a subset of tracks produced by the artist (unless you count features as well, but I'll ignore this here). 如果FROM_ARTIST为true,则FROM_ALBUM也隐式为true,因为专辑是艺术家制作的曲目的子集(除非您也计算功能,但在这里我将忽略它)。 So after the classification, things look quite a lot simpler already. 因此,在分类之后,事情看起来已经很简单了。

Since REPEAT and SHUFFLE handle their own specific behavior without influence from any other flag, we can handle them via a trivial if-clause, or some workaround that maps each property to a specific action. 由于REPEAT和SHUFFLE处理它们自己的特定行为而不受其他任何标志的影响,因此我们可以通过琐碎的if子句或将每个属性映射到特定操作的变通方法来处理它们。 For the other flags, the simplest would be to utilize the hierarchy and search for the flag that covers the largest set of songs and set it up as filter. 对于其他标志,最简单的方法是利用层次结构并搜索覆盖最大歌曲集的标志并将其设置为过滤器。

The main-trick here wouldn't be to apply any design-pattern, but actually to classify the flags based on their meaning. 这里的主要技巧不是应用任何设计模式,而是实际上根据标志的含义对标志进行分类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM