Getting the right conditional ConfigId

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite












Many conditions need to be scanned for the first one that matches a set of tests. If there is a matching condition, that conditions ConfigId should be returned.



I have a way to do the matching of conditions, but there are too many continue statements. Is there a better way to perform these checks?



private Integer match(List<ConfitionEntity> conditions, ActualDto actualDto) 

if (CollectionUtils.isEmpty(conditions))
return null;

Integer configId = null;
for (ConfitionEntity condition : conditions)
boolean match = matchState(condition, actualDto);
if (!match)
continue;

match = matchStatus(condition, actualDto);
if (!match)
continue;

match = matchType(condition, actualDto);
if (!match)
continue;

match = matchPre(condition, actualDto);
if (!match)
continue;

match = matchMobile(condition, actualDto);
if (!match)
continue;

match = matchAge(condition, actualDto);
if (!match)
continue;

match = matchNumber(condition, actualDto);
if (!match)
continue;

match = matchPassed(condition, actualDto);
if (!match)
continue;

match = matchName(condition, actualDto);
if (match)
configId = condition.getConfigId();
break;



return configId;







share|improve this question



























    up vote
    5
    down vote

    favorite












    Many conditions need to be scanned for the first one that matches a set of tests. If there is a matching condition, that conditions ConfigId should be returned.



    I have a way to do the matching of conditions, but there are too many continue statements. Is there a better way to perform these checks?



    private Integer match(List<ConfitionEntity> conditions, ActualDto actualDto) 

    if (CollectionUtils.isEmpty(conditions))
    return null;

    Integer configId = null;
    for (ConfitionEntity condition : conditions)
    boolean match = matchState(condition, actualDto);
    if (!match)
    continue;

    match = matchStatus(condition, actualDto);
    if (!match)
    continue;

    match = matchType(condition, actualDto);
    if (!match)
    continue;

    match = matchPre(condition, actualDto);
    if (!match)
    continue;

    match = matchMobile(condition, actualDto);
    if (!match)
    continue;

    match = matchAge(condition, actualDto);
    if (!match)
    continue;

    match = matchNumber(condition, actualDto);
    if (!match)
    continue;

    match = matchPassed(condition, actualDto);
    if (!match)
    continue;

    match = matchName(condition, actualDto);
    if (match)
    configId = condition.getConfigId();
    break;



    return configId;







    share|improve this question























      up vote
      5
      down vote

      favorite









      up vote
      5
      down vote

      favorite











      Many conditions need to be scanned for the first one that matches a set of tests. If there is a matching condition, that conditions ConfigId should be returned.



      I have a way to do the matching of conditions, but there are too many continue statements. Is there a better way to perform these checks?



      private Integer match(List<ConfitionEntity> conditions, ActualDto actualDto) 

      if (CollectionUtils.isEmpty(conditions))
      return null;

      Integer configId = null;
      for (ConfitionEntity condition : conditions)
      boolean match = matchState(condition, actualDto);
      if (!match)
      continue;

      match = matchStatus(condition, actualDto);
      if (!match)
      continue;

      match = matchType(condition, actualDto);
      if (!match)
      continue;

      match = matchPre(condition, actualDto);
      if (!match)
      continue;

      match = matchMobile(condition, actualDto);
      if (!match)
      continue;

      match = matchAge(condition, actualDto);
      if (!match)
      continue;

      match = matchNumber(condition, actualDto);
      if (!match)
      continue;

      match = matchPassed(condition, actualDto);
      if (!match)
      continue;

      match = matchName(condition, actualDto);
      if (match)
      configId = condition.getConfigId();
      break;



      return configId;







      share|improve this question













      Many conditions need to be scanned for the first one that matches a set of tests. If there is a matching condition, that conditions ConfigId should be returned.



      I have a way to do the matching of conditions, but there are too many continue statements. Is there a better way to perform these checks?



      private Integer match(List<ConfitionEntity> conditions, ActualDto actualDto) 

      if (CollectionUtils.isEmpty(conditions))
      return null;

      Integer configId = null;
      for (ConfitionEntity condition : conditions)
      boolean match = matchState(condition, actualDto);
      if (!match)
      continue;

      match = matchStatus(condition, actualDto);
      if (!match)
      continue;

      match = matchType(condition, actualDto);
      if (!match)
      continue;

      match = matchPre(condition, actualDto);
      if (!match)
      continue;

      match = matchMobile(condition, actualDto);
      if (!match)
      continue;

      match = matchAge(condition, actualDto);
      if (!match)
      continue;

      match = matchNumber(condition, actualDto);
      if (!match)
      continue;

      match = matchPassed(condition, actualDto);
      if (!match)
      continue;

      match = matchName(condition, actualDto);
      if (match)
      configId = condition.getConfigId();
      break;



      return configId;









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jul 6 at 10:34
























      asked Jun 28 at 4:00









      Frank.D

      1634




      1634




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          With the Java functional extensions you can "easily" encode these tests as a BinaryPredicate short-circuitung and set. See the documentation for The and method on BiPredicate.



          Consider the following code which you can add-to as your conditions change:



          private static final BiPredicate<QueueMsgPushConditionEntity, QueueUpdatedDto> MATCH = ((c, q) -> c != null && q != null)
          .and((c, q) -> matchQueueState(c.getQueueState(), q.getState()))
          .and((c, q) -> matchFirstPush(c.getFirstPush(), q.getSerialId())
          .and((c, q) -> matchPushType(c.getPushType(), PushType.QUEUE_CALL))
          .......


          Now, with that static lambda/functional expression, you can change your match function to look like:



          private Integer match(List<QueueMsgPushConditionEntity> conditions, 
          QueueUpdatedDto queueUpdatedDto)

          Optional<QueueMsgPushConditionEntity> first = conditions.stream()
          .dropWhile(c -> !MATCH.test(c, queueUpdatedDto))
          .findFirst();

          return first.map(c -> c.getQueueMsgPushConfigId()).or(null);




          What the above stream does, is go through all the conditions, and it throws them all away until it finds one that matches all the MATCH tests, and then it stops looking. If/when it finds one, it returns it as the Optional, which is mapped to the Integer, or null if nothing was found.






          share|improve this answer





















          • This is a very good method, but my java version is 1.8.
            – Frank.D
            Jun 29 at 1:40










          • For 1.8, replace dropWhile(x -> condition) with filter(x -> !condition) - the rest should work. And as java 8 has end-of-life in just half a year, you should upgrade soon anyway.
            – mtj
            Jun 29 at 6:40

















          up vote
          3
          down vote













          You could take advantage of short circuit behavior, that is it will stop evaluating at the first "false"



          for (QueueMsgPushConditionEntity condition : conditions) 

          if (matchQueueState(condition.getQueueState(), queueUpdatedDto.getState()) &&
          matchFirstPush(condition.getFirstPush(), queueUpdatedDto.getSerialId())) &&
          matchPushType(condition.getPushType(), PushType.QUEUE_CALL) && .. the rest )

          return condition.getQueueMsgPushConfigId();







          share|improve this answer





















          • I don't think this is a good idea. This method causes the if statement to be too complicated.
            – Frank.D
            Jun 28 at 5:25

















          up vote
          0
          down vote













          This is a classic chain-of-responsibility pattern. Assuming there's enough work to justify it (you would be pushing the contents of the matchXXX methods into the classes), the code would be called like this:



          final MyMatcher queue = new QueueMatcher();
          final MyMatcher firstPush = new FirstPushMatcher();
          queue.setNext(firstPush);
          ...
          final Integer configId = queue.handleCondition(condition, queueUpdate);


          MyMatcher would be an interface or abstract class:



          public interface MyMatcher 
          void setNext(final MyMatcher myMatcher);

          /** @return configId */
          Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate);



          And each link in the chain would look like:



          import java.util.Arrays;
          import java.util.Set;
          import java.util.stream.Collectors;

          final class QueueStateMatcher

          private MyMatcher next;

          public QueueStateMatcher()
          super();


          public void setNext(final MyMatcher myMatcher)
          this.next = myMatcher;


          public Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate)



          Obviously, "MyMatcher" is a terrible name and you should make it more appropriate for your domain. The matchXXX methods you have now would be removed and their contents moved into the corresponding classes. You can make the implementations immutable instead of using setNext as long as you're okay with defining them in the opposite order that they'll execute. Or, if you leave them mutable, you can reorder the chain (probably not useful for you in the problem as described).






          share|improve this answer























          • I understand your idea, can you write the details of the code?
            – Frank.D
            Jun 29 at 2:04










          • @Frank.Dai What does matchQueueState look like?
            – Eric Stein
            Jun 29 at 11:27










          • I added some code.
            – Frank.D
            Jun 29 at 14:46










          • @Frank.Dai Updated with a more concrete example.
            – Eric Stein
            Jun 29 at 16:08










          • If I have ten judgment conditions, will I add ten classes like this?
            – Frank.D
            Jun 29 at 16:46










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f197394%2fgetting-the-right-conditional-configid%23new-answer', 'question_page');

          );

          Post as a guest






























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote



          accepted










          With the Java functional extensions you can "easily" encode these tests as a BinaryPredicate short-circuitung and set. See the documentation for The and method on BiPredicate.



          Consider the following code which you can add-to as your conditions change:



          private static final BiPredicate<QueueMsgPushConditionEntity, QueueUpdatedDto> MATCH = ((c, q) -> c != null && q != null)
          .and((c, q) -> matchQueueState(c.getQueueState(), q.getState()))
          .and((c, q) -> matchFirstPush(c.getFirstPush(), q.getSerialId())
          .and((c, q) -> matchPushType(c.getPushType(), PushType.QUEUE_CALL))
          .......


          Now, with that static lambda/functional expression, you can change your match function to look like:



          private Integer match(List<QueueMsgPushConditionEntity> conditions, 
          QueueUpdatedDto queueUpdatedDto)

          Optional<QueueMsgPushConditionEntity> first = conditions.stream()
          .dropWhile(c -> !MATCH.test(c, queueUpdatedDto))
          .findFirst();

          return first.map(c -> c.getQueueMsgPushConfigId()).or(null);




          What the above stream does, is go through all the conditions, and it throws them all away until it finds one that matches all the MATCH tests, and then it stops looking. If/when it finds one, it returns it as the Optional, which is mapped to the Integer, or null if nothing was found.






          share|improve this answer





















          • This is a very good method, but my java version is 1.8.
            – Frank.D
            Jun 29 at 1:40










          • For 1.8, replace dropWhile(x -> condition) with filter(x -> !condition) - the rest should work. And as java 8 has end-of-life in just half a year, you should upgrade soon anyway.
            – mtj
            Jun 29 at 6:40














          up vote
          4
          down vote



          accepted










          With the Java functional extensions you can "easily" encode these tests as a BinaryPredicate short-circuitung and set. See the documentation for The and method on BiPredicate.



          Consider the following code which you can add-to as your conditions change:



          private static final BiPredicate<QueueMsgPushConditionEntity, QueueUpdatedDto> MATCH = ((c, q) -> c != null && q != null)
          .and((c, q) -> matchQueueState(c.getQueueState(), q.getState()))
          .and((c, q) -> matchFirstPush(c.getFirstPush(), q.getSerialId())
          .and((c, q) -> matchPushType(c.getPushType(), PushType.QUEUE_CALL))
          .......


          Now, with that static lambda/functional expression, you can change your match function to look like:



          private Integer match(List<QueueMsgPushConditionEntity> conditions, 
          QueueUpdatedDto queueUpdatedDto)

          Optional<QueueMsgPushConditionEntity> first = conditions.stream()
          .dropWhile(c -> !MATCH.test(c, queueUpdatedDto))
          .findFirst();

          return first.map(c -> c.getQueueMsgPushConfigId()).or(null);




          What the above stream does, is go through all the conditions, and it throws them all away until it finds one that matches all the MATCH tests, and then it stops looking. If/when it finds one, it returns it as the Optional, which is mapped to the Integer, or null if nothing was found.






          share|improve this answer





















          • This is a very good method, but my java version is 1.8.
            – Frank.D
            Jun 29 at 1:40










          • For 1.8, replace dropWhile(x -> condition) with filter(x -> !condition) - the rest should work. And as java 8 has end-of-life in just half a year, you should upgrade soon anyway.
            – mtj
            Jun 29 at 6:40












          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          With the Java functional extensions you can "easily" encode these tests as a BinaryPredicate short-circuitung and set. See the documentation for The and method on BiPredicate.



          Consider the following code which you can add-to as your conditions change:



          private static final BiPredicate<QueueMsgPushConditionEntity, QueueUpdatedDto> MATCH = ((c, q) -> c != null && q != null)
          .and((c, q) -> matchQueueState(c.getQueueState(), q.getState()))
          .and((c, q) -> matchFirstPush(c.getFirstPush(), q.getSerialId())
          .and((c, q) -> matchPushType(c.getPushType(), PushType.QUEUE_CALL))
          .......


          Now, with that static lambda/functional expression, you can change your match function to look like:



          private Integer match(List<QueueMsgPushConditionEntity> conditions, 
          QueueUpdatedDto queueUpdatedDto)

          Optional<QueueMsgPushConditionEntity> first = conditions.stream()
          .dropWhile(c -> !MATCH.test(c, queueUpdatedDto))
          .findFirst();

          return first.map(c -> c.getQueueMsgPushConfigId()).or(null);




          What the above stream does, is go through all the conditions, and it throws them all away until it finds one that matches all the MATCH tests, and then it stops looking. If/when it finds one, it returns it as the Optional, which is mapped to the Integer, or null if nothing was found.






          share|improve this answer













          With the Java functional extensions you can "easily" encode these tests as a BinaryPredicate short-circuitung and set. See the documentation for The and method on BiPredicate.



          Consider the following code which you can add-to as your conditions change:



          private static final BiPredicate<QueueMsgPushConditionEntity, QueueUpdatedDto> MATCH = ((c, q) -> c != null && q != null)
          .and((c, q) -> matchQueueState(c.getQueueState(), q.getState()))
          .and((c, q) -> matchFirstPush(c.getFirstPush(), q.getSerialId())
          .and((c, q) -> matchPushType(c.getPushType(), PushType.QUEUE_CALL))
          .......


          Now, with that static lambda/functional expression, you can change your match function to look like:



          private Integer match(List<QueueMsgPushConditionEntity> conditions, 
          QueueUpdatedDto queueUpdatedDto)

          Optional<QueueMsgPushConditionEntity> first = conditions.stream()
          .dropWhile(c -> !MATCH.test(c, queueUpdatedDto))
          .findFirst();

          return first.map(c -> c.getQueueMsgPushConfigId()).or(null);




          What the above stream does, is go through all the conditions, and it throws them all away until it finds one that matches all the MATCH tests, and then it stops looking. If/when it finds one, it returns it as the Optional, which is mapped to the Integer, or null if nothing was found.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Jun 28 at 4:54









          rolfl♦

          90.2k13186390




          90.2k13186390











          • This is a very good method, but my java version is 1.8.
            – Frank.D
            Jun 29 at 1:40










          • For 1.8, replace dropWhile(x -> condition) with filter(x -> !condition) - the rest should work. And as java 8 has end-of-life in just half a year, you should upgrade soon anyway.
            – mtj
            Jun 29 at 6:40
















          • This is a very good method, but my java version is 1.8.
            – Frank.D
            Jun 29 at 1:40










          • For 1.8, replace dropWhile(x -> condition) with filter(x -> !condition) - the rest should work. And as java 8 has end-of-life in just half a year, you should upgrade soon anyway.
            – mtj
            Jun 29 at 6:40















          This is a very good method, but my java version is 1.8.
          – Frank.D
          Jun 29 at 1:40




          This is a very good method, but my java version is 1.8.
          – Frank.D
          Jun 29 at 1:40












          For 1.8, replace dropWhile(x -> condition) with filter(x -> !condition) - the rest should work. And as java 8 has end-of-life in just half a year, you should upgrade soon anyway.
          – mtj
          Jun 29 at 6:40




          For 1.8, replace dropWhile(x -> condition) with filter(x -> !condition) - the rest should work. And as java 8 has end-of-life in just half a year, you should upgrade soon anyway.
          – mtj
          Jun 29 at 6:40












          up vote
          3
          down vote













          You could take advantage of short circuit behavior, that is it will stop evaluating at the first "false"



          for (QueueMsgPushConditionEntity condition : conditions) 

          if (matchQueueState(condition.getQueueState(), queueUpdatedDto.getState()) &&
          matchFirstPush(condition.getFirstPush(), queueUpdatedDto.getSerialId())) &&
          matchPushType(condition.getPushType(), PushType.QUEUE_CALL) && .. the rest )

          return condition.getQueueMsgPushConfigId();







          share|improve this answer





















          • I don't think this is a good idea. This method causes the if statement to be too complicated.
            – Frank.D
            Jun 28 at 5:25














          up vote
          3
          down vote













          You could take advantage of short circuit behavior, that is it will stop evaluating at the first "false"



          for (QueueMsgPushConditionEntity condition : conditions) 

          if (matchQueueState(condition.getQueueState(), queueUpdatedDto.getState()) &&
          matchFirstPush(condition.getFirstPush(), queueUpdatedDto.getSerialId())) &&
          matchPushType(condition.getPushType(), PushType.QUEUE_CALL) && .. the rest )

          return condition.getQueueMsgPushConfigId();







          share|improve this answer





















          • I don't think this is a good idea. This method causes the if statement to be too complicated.
            – Frank.D
            Jun 28 at 5:25












          up vote
          3
          down vote










          up vote
          3
          down vote









          You could take advantage of short circuit behavior, that is it will stop evaluating at the first "false"



          for (QueueMsgPushConditionEntity condition : conditions) 

          if (matchQueueState(condition.getQueueState(), queueUpdatedDto.getState()) &&
          matchFirstPush(condition.getFirstPush(), queueUpdatedDto.getSerialId())) &&
          matchPushType(condition.getPushType(), PushType.QUEUE_CALL) && .. the rest )

          return condition.getQueueMsgPushConfigId();







          share|improve this answer













          You could take advantage of short circuit behavior, that is it will stop evaluating at the first "false"



          for (QueueMsgPushConditionEntity condition : conditions) 

          if (matchQueueState(condition.getQueueState(), queueUpdatedDto.getState()) &&
          matchFirstPush(condition.getFirstPush(), queueUpdatedDto.getSerialId())) &&
          matchPushType(condition.getPushType(), PushType.QUEUE_CALL) && .. the rest )

          return condition.getQueueMsgPushConfigId();








          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Jun 28 at 4:25









          Mitchel0022

          1588




          1588











          • I don't think this is a good idea. This method causes the if statement to be too complicated.
            – Frank.D
            Jun 28 at 5:25
















          • I don't think this is a good idea. This method causes the if statement to be too complicated.
            – Frank.D
            Jun 28 at 5:25















          I don't think this is a good idea. This method causes the if statement to be too complicated.
          – Frank.D
          Jun 28 at 5:25




          I don't think this is a good idea. This method causes the if statement to be too complicated.
          – Frank.D
          Jun 28 at 5:25










          up vote
          0
          down vote













          This is a classic chain-of-responsibility pattern. Assuming there's enough work to justify it (you would be pushing the contents of the matchXXX methods into the classes), the code would be called like this:



          final MyMatcher queue = new QueueMatcher();
          final MyMatcher firstPush = new FirstPushMatcher();
          queue.setNext(firstPush);
          ...
          final Integer configId = queue.handleCondition(condition, queueUpdate);


          MyMatcher would be an interface or abstract class:



          public interface MyMatcher 
          void setNext(final MyMatcher myMatcher);

          /** @return configId */
          Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate);



          And each link in the chain would look like:



          import java.util.Arrays;
          import java.util.Set;
          import java.util.stream.Collectors;

          final class QueueStateMatcher

          private MyMatcher next;

          public QueueStateMatcher()
          super();


          public void setNext(final MyMatcher myMatcher)
          this.next = myMatcher;


          public Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate)



          Obviously, "MyMatcher" is a terrible name and you should make it more appropriate for your domain. The matchXXX methods you have now would be removed and their contents moved into the corresponding classes. You can make the implementations immutable instead of using setNext as long as you're okay with defining them in the opposite order that they'll execute. Or, if you leave them mutable, you can reorder the chain (probably not useful for you in the problem as described).






          share|improve this answer























          • I understand your idea, can you write the details of the code?
            – Frank.D
            Jun 29 at 2:04










          • @Frank.Dai What does matchQueueState look like?
            – Eric Stein
            Jun 29 at 11:27










          • I added some code.
            – Frank.D
            Jun 29 at 14:46










          • @Frank.Dai Updated with a more concrete example.
            – Eric Stein
            Jun 29 at 16:08










          • If I have ten judgment conditions, will I add ten classes like this?
            – Frank.D
            Jun 29 at 16:46














          up vote
          0
          down vote













          This is a classic chain-of-responsibility pattern. Assuming there's enough work to justify it (you would be pushing the contents of the matchXXX methods into the classes), the code would be called like this:



          final MyMatcher queue = new QueueMatcher();
          final MyMatcher firstPush = new FirstPushMatcher();
          queue.setNext(firstPush);
          ...
          final Integer configId = queue.handleCondition(condition, queueUpdate);


          MyMatcher would be an interface or abstract class:



          public interface MyMatcher 
          void setNext(final MyMatcher myMatcher);

          /** @return configId */
          Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate);



          And each link in the chain would look like:



          import java.util.Arrays;
          import java.util.Set;
          import java.util.stream.Collectors;

          final class QueueStateMatcher

          private MyMatcher next;

          public QueueStateMatcher()
          super();


          public void setNext(final MyMatcher myMatcher)
          this.next = myMatcher;


          public Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate)



          Obviously, "MyMatcher" is a terrible name and you should make it more appropriate for your domain. The matchXXX methods you have now would be removed and their contents moved into the corresponding classes. You can make the implementations immutable instead of using setNext as long as you're okay with defining them in the opposite order that they'll execute. Or, if you leave them mutable, you can reorder the chain (probably not useful for you in the problem as described).






          share|improve this answer























          • I understand your idea, can you write the details of the code?
            – Frank.D
            Jun 29 at 2:04










          • @Frank.Dai What does matchQueueState look like?
            – Eric Stein
            Jun 29 at 11:27










          • I added some code.
            – Frank.D
            Jun 29 at 14:46










          • @Frank.Dai Updated with a more concrete example.
            – Eric Stein
            Jun 29 at 16:08










          • If I have ten judgment conditions, will I add ten classes like this?
            – Frank.D
            Jun 29 at 16:46












          up vote
          0
          down vote










          up vote
          0
          down vote









          This is a classic chain-of-responsibility pattern. Assuming there's enough work to justify it (you would be pushing the contents of the matchXXX methods into the classes), the code would be called like this:



          final MyMatcher queue = new QueueMatcher();
          final MyMatcher firstPush = new FirstPushMatcher();
          queue.setNext(firstPush);
          ...
          final Integer configId = queue.handleCondition(condition, queueUpdate);


          MyMatcher would be an interface or abstract class:



          public interface MyMatcher 
          void setNext(final MyMatcher myMatcher);

          /** @return configId */
          Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate);



          And each link in the chain would look like:



          import java.util.Arrays;
          import java.util.Set;
          import java.util.stream.Collectors;

          final class QueueStateMatcher

          private MyMatcher next;

          public QueueStateMatcher()
          super();


          public void setNext(final MyMatcher myMatcher)
          this.next = myMatcher;


          public Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate)



          Obviously, "MyMatcher" is a terrible name and you should make it more appropriate for your domain. The matchXXX methods you have now would be removed and their contents moved into the corresponding classes. You can make the implementations immutable instead of using setNext as long as you're okay with defining them in the opposite order that they'll execute. Or, if you leave them mutable, you can reorder the chain (probably not useful for you in the problem as described).






          share|improve this answer















          This is a classic chain-of-responsibility pattern. Assuming there's enough work to justify it (you would be pushing the contents of the matchXXX methods into the classes), the code would be called like this:



          final MyMatcher queue = new QueueMatcher();
          final MyMatcher firstPush = new FirstPushMatcher();
          queue.setNext(firstPush);
          ...
          final Integer configId = queue.handleCondition(condition, queueUpdate);


          MyMatcher would be an interface or abstract class:



          public interface MyMatcher 
          void setNext(final MyMatcher myMatcher);

          /** @return configId */
          Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate);



          And each link in the chain would look like:



          import java.util.Arrays;
          import java.util.Set;
          import java.util.stream.Collectors;

          final class QueueStateMatcher

          private MyMatcher next;

          public QueueStateMatcher()
          super();


          public void setNext(final MyMatcher myMatcher)
          this.next = myMatcher;


          public Integer handleCondition(final QueueMsgPushConditionEntity condition, final QueueUpdateDto queueUpdate)



          Obviously, "MyMatcher" is a terrible name and you should make it more appropriate for your domain. The matchXXX methods you have now would be removed and their contents moved into the corresponding classes. You can make the implementations immutable instead of using setNext as long as you're okay with defining them in the opposite order that they'll execute. Or, if you leave them mutable, you can reorder the chain (probably not useful for you in the problem as described).







          share|improve this answer















          share|improve this answer



          share|improve this answer








          edited Jun 29 at 16:08


























          answered Jun 28 at 18:04









          Eric Stein

          3,658512




          3,658512











          • I understand your idea, can you write the details of the code?
            – Frank.D
            Jun 29 at 2:04










          • @Frank.Dai What does matchQueueState look like?
            – Eric Stein
            Jun 29 at 11:27










          • I added some code.
            – Frank.D
            Jun 29 at 14:46










          • @Frank.Dai Updated with a more concrete example.
            – Eric Stein
            Jun 29 at 16:08










          • If I have ten judgment conditions, will I add ten classes like this?
            – Frank.D
            Jun 29 at 16:46
















          • I understand your idea, can you write the details of the code?
            – Frank.D
            Jun 29 at 2:04










          • @Frank.Dai What does matchQueueState look like?
            – Eric Stein
            Jun 29 at 11:27










          • I added some code.
            – Frank.D
            Jun 29 at 14:46










          • @Frank.Dai Updated with a more concrete example.
            – Eric Stein
            Jun 29 at 16:08










          • If I have ten judgment conditions, will I add ten classes like this?
            – Frank.D
            Jun 29 at 16:46















          I understand your idea, can you write the details of the code?
          – Frank.D
          Jun 29 at 2:04




          I understand your idea, can you write the details of the code?
          – Frank.D
          Jun 29 at 2:04












          @Frank.Dai What does matchQueueState look like?
          – Eric Stein
          Jun 29 at 11:27




          @Frank.Dai What does matchQueueState look like?
          – Eric Stein
          Jun 29 at 11:27












          I added some code.
          – Frank.D
          Jun 29 at 14:46




          I added some code.
          – Frank.D
          Jun 29 at 14:46












          @Frank.Dai Updated with a more concrete example.
          – Eric Stein
          Jun 29 at 16:08




          @Frank.Dai Updated with a more concrete example.
          – Eric Stein
          Jun 29 at 16:08












          If I have ten judgment conditions, will I add ten classes like this?
          – Frank.D
          Jun 29 at 16:46




          If I have ten judgment conditions, will I add ten classes like this?
          – Frank.D
          Jun 29 at 16:46












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f197394%2fgetting-the-right-conditional-configid%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Python Lists

          Aion

          JavaScript Array Iteration Methods