Method ordering for Requirements API











up vote
0
down vote

favorite












Over the past couple of years I've quietly developed a library for enforcing API contracts. The project is hosted at https://bitbucket.org/cowwoc/requirements/



Users write requireThat(name, "name").isNotNull().size().isLessThan(5) and get back:



java.lang.NullPointerException: name may not be null


or



java.lang.IllegalArgumentException: name must be shorter than 5 characters
Actual: 123456


This design has a few moving parts:




  • Most methods require a user to pass in a value, but treat name as optional. For example isLessThan(5) could be written as isLessThan(5, "MAX_LENGTH") in which case the user is informed that the limit (5) comes from a constant named MAX_LENGTH.

  • Users can provide contextual information in the form of key-value pairs that will get included in the exception message: addContext("ipAddress", session.getRemoteAddress()). This concept is similar to MDC found in most logging libraries.

  • Other APIs (Guava Preconditions, AssertJ) require users to pass in a value as the first parameter.


Chronologically, the design evolved as follows:




  • Initially the parameter ordering was (value, name) where name was optional for most methods.

  • Some time later I added addContext(name, value), mirroring the parameter ordering of Java Maps.

  • I then realized that the parameter ordering was inconsistent so I changed the design to require (name, value) for all methods.

  • A year went by and I still find myself entering requireThat(value, name) on a regular basis. This has lasted long enough that I am seriously considering reverting the order change.


The way I see it, I have 3 options:




  1. Use (name, value) ordering across all methods.


    • Pro: consistent ordering across all methods.

    • Con: Optional parameters (name) show up before mandatory parameters (value)



  2. Use (value, name) ordering across all methods.


    • Pro: The ordering of most methods feels natural. Mandatory parameters come first. Optional parameters last.

    • Con: addContext(value, name) might not be intuitive.



  3. Forget consistency: use (value, name) ordering for most methods and (name, value) for addContext().


    • Pro: Parameter ordering is intuitive from the perspective of each method.

    • Con: Parameter ordering is inconsistent across all methods.




I have two goals:




  1. Maximize the intuitiveness of the ordering: users should be able to enter parameters in the correct order without referring to the documentation.

  2. Maximize the readability of the resulting code: I'd like statements to read like English phrases.










share|improve this question


























    up vote
    0
    down vote

    favorite












    Over the past couple of years I've quietly developed a library for enforcing API contracts. The project is hosted at https://bitbucket.org/cowwoc/requirements/



    Users write requireThat(name, "name").isNotNull().size().isLessThan(5) and get back:



    java.lang.NullPointerException: name may not be null


    or



    java.lang.IllegalArgumentException: name must be shorter than 5 characters
    Actual: 123456


    This design has a few moving parts:




    • Most methods require a user to pass in a value, but treat name as optional. For example isLessThan(5) could be written as isLessThan(5, "MAX_LENGTH") in which case the user is informed that the limit (5) comes from a constant named MAX_LENGTH.

    • Users can provide contextual information in the form of key-value pairs that will get included in the exception message: addContext("ipAddress", session.getRemoteAddress()). This concept is similar to MDC found in most logging libraries.

    • Other APIs (Guava Preconditions, AssertJ) require users to pass in a value as the first parameter.


    Chronologically, the design evolved as follows:




    • Initially the parameter ordering was (value, name) where name was optional for most methods.

    • Some time later I added addContext(name, value), mirroring the parameter ordering of Java Maps.

    • I then realized that the parameter ordering was inconsistent so I changed the design to require (name, value) for all methods.

    • A year went by and I still find myself entering requireThat(value, name) on a regular basis. This has lasted long enough that I am seriously considering reverting the order change.


    The way I see it, I have 3 options:




    1. Use (name, value) ordering across all methods.


      • Pro: consistent ordering across all methods.

      • Con: Optional parameters (name) show up before mandatory parameters (value)



    2. Use (value, name) ordering across all methods.


      • Pro: The ordering of most methods feels natural. Mandatory parameters come first. Optional parameters last.

      • Con: addContext(value, name) might not be intuitive.



    3. Forget consistency: use (value, name) ordering for most methods and (name, value) for addContext().


      • Pro: Parameter ordering is intuitive from the perspective of each method.

      • Con: Parameter ordering is inconsistent across all methods.




    I have two goals:




    1. Maximize the intuitiveness of the ordering: users should be able to enter parameters in the correct order without referring to the documentation.

    2. Maximize the readability of the resulting code: I'd like statements to read like English phrases.










    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      Over the past couple of years I've quietly developed a library for enforcing API contracts. The project is hosted at https://bitbucket.org/cowwoc/requirements/



      Users write requireThat(name, "name").isNotNull().size().isLessThan(5) and get back:



      java.lang.NullPointerException: name may not be null


      or



      java.lang.IllegalArgumentException: name must be shorter than 5 characters
      Actual: 123456


      This design has a few moving parts:




      • Most methods require a user to pass in a value, but treat name as optional. For example isLessThan(5) could be written as isLessThan(5, "MAX_LENGTH") in which case the user is informed that the limit (5) comes from a constant named MAX_LENGTH.

      • Users can provide contextual information in the form of key-value pairs that will get included in the exception message: addContext("ipAddress", session.getRemoteAddress()). This concept is similar to MDC found in most logging libraries.

      • Other APIs (Guava Preconditions, AssertJ) require users to pass in a value as the first parameter.


      Chronologically, the design evolved as follows:




      • Initially the parameter ordering was (value, name) where name was optional for most methods.

      • Some time later I added addContext(name, value), mirroring the parameter ordering of Java Maps.

      • I then realized that the parameter ordering was inconsistent so I changed the design to require (name, value) for all methods.

      • A year went by and I still find myself entering requireThat(value, name) on a regular basis. This has lasted long enough that I am seriously considering reverting the order change.


      The way I see it, I have 3 options:




      1. Use (name, value) ordering across all methods.


        • Pro: consistent ordering across all methods.

        • Con: Optional parameters (name) show up before mandatory parameters (value)



      2. Use (value, name) ordering across all methods.


        • Pro: The ordering of most methods feels natural. Mandatory parameters come first. Optional parameters last.

        • Con: addContext(value, name) might not be intuitive.



      3. Forget consistency: use (value, name) ordering for most methods and (name, value) for addContext().


        • Pro: Parameter ordering is intuitive from the perspective of each method.

        • Con: Parameter ordering is inconsistent across all methods.




      I have two goals:




      1. Maximize the intuitiveness of the ordering: users should be able to enter parameters in the correct order without referring to the documentation.

      2. Maximize the readability of the resulting code: I'd like statements to read like English phrases.










      share|improve this question













      Over the past couple of years I've quietly developed a library for enforcing API contracts. The project is hosted at https://bitbucket.org/cowwoc/requirements/



      Users write requireThat(name, "name").isNotNull().size().isLessThan(5) and get back:



      java.lang.NullPointerException: name may not be null


      or



      java.lang.IllegalArgumentException: name must be shorter than 5 characters
      Actual: 123456


      This design has a few moving parts:




      • Most methods require a user to pass in a value, but treat name as optional. For example isLessThan(5) could be written as isLessThan(5, "MAX_LENGTH") in which case the user is informed that the limit (5) comes from a constant named MAX_LENGTH.

      • Users can provide contextual information in the form of key-value pairs that will get included in the exception message: addContext("ipAddress", session.getRemoteAddress()). This concept is similar to MDC found in most logging libraries.

      • Other APIs (Guava Preconditions, AssertJ) require users to pass in a value as the first parameter.


      Chronologically, the design evolved as follows:




      • Initially the parameter ordering was (value, name) where name was optional for most methods.

      • Some time later I added addContext(name, value), mirroring the parameter ordering of Java Maps.

      • I then realized that the parameter ordering was inconsistent so I changed the design to require (name, value) for all methods.

      • A year went by and I still find myself entering requireThat(value, name) on a regular basis. This has lasted long enough that I am seriously considering reverting the order change.


      The way I see it, I have 3 options:




      1. Use (name, value) ordering across all methods.


        • Pro: consistent ordering across all methods.

        • Con: Optional parameters (name) show up before mandatory parameters (value)



      2. Use (value, name) ordering across all methods.


        • Pro: The ordering of most methods feels natural. Mandatory parameters come first. Optional parameters last.

        • Con: addContext(value, name) might not be intuitive.



      3. Forget consistency: use (value, name) ordering for most methods and (name, value) for addContext().


        • Pro: Parameter ordering is intuitive from the perspective of each method.

        • Con: Parameter ordering is inconsistent across all methods.




      I have two goals:




      1. Maximize the intuitiveness of the ordering: users should be able to enter parameters in the correct order without referring to the documentation.

      2. Maximize the readability of the resulting code: I'd like statements to read like English phrases.







      java validation library fluent-interface






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 10 mins ago









      Gili

      1596




      1596



























          active

          oldest

          votes











          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: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          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%2f209704%2fmethod-ordering-for-requirements-api%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209704%2fmethod-ordering-for-requirements-api%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Feedback on college project

          Futebolista

          Albești (Vaslui)