이 콘텐츠는 선택한 언어로 제공되지 않습니다.

Chapter 18. Development


18.1. Methodology Overview

The diagram below explains the overall structure of the OptaPlanner source code:

methodologyOverview

In the diagram above, it’s important to understand the clear separation between the configuration and runtime classes.

The development philosophy includes:

  • Reuse: The examples are reused as integration tests, stress tests and demos. The documentation images are reused as slides.
  • Consistent terminology: Each example has a class App (executable class), Dao (Data Access Object) and Panel (swing UI).
  • Consistent structure: Each example has the same packages: domain, persistence, app, solver and swingui.
  • Real world usefulness: Every feature is used in an example. Most examples are real world use cases with real world constraints, often with real world data.
  • Automated testing: There are unit tests, integration tests, performance regressions tests and stress tests. The test coverage is high.
  • Fail fast with an understandable error message: Invalid states are checked as early as possible.

18.2. Development guidelines

  1. Fail fast. There are several levels of fail fast, from better to worse:

    1. Fail Fast at compile time. For example: Don’t accept an Object as parameter if it needs to be a String or an Integer.
    2. Fail Fast at startup time. For example: if the configuration parameter needs to be a positive int and it’s negative, fail fast
    3. Fail Fast at runtime. For example: if the request needs to contain a double between 0.0 and 1.0 and it’s bigger than 1.0, fail fast.
    4. Fail Fast at runtime in assertion mode if the detection performance cost is high. For example: If, after every low level iteration, the variable A needs to be equal to the square root of B, check it if and only if an assert flag is set to true (usually controlled by the EnvironmentMode).
  2. Exception messages

    1. The Exception message must include the name and state of each relevant variable. For example:

      if (fooSize < 0) {
          throw new IllegalArgumentException("The fooSize (" + fooSize + ") of bar (" + this + ") must be positive.");
      }

      Notice that the output clearly explains what’s wrong:

      Exception in thread "main" java.lang.IllegalArgumentException: The fooSize (-5) of bar (myBar) must be positive.
          at ...
    2. Whenever possible, the Exception message must include context.
    3. Whenever the fix is not obvious, the Exception message should include advice. Advice normally starts with the word maybe on a new line:

      Exception in thread "main" java.lang.IllegalStateException: The valueRangeDescriptor (fooRange) is nullable, but not countable (false).
      Maybe the member (getFooRange) should return CountableValueRange.
          at ...

      The word maybe is to indicate that the advice is not guaranteed to be right in all cases.

  3. Generics. The Solution class is often passed as a generic type parameter to subsystems. The PlanningEntity class(es) are rarely passed as a generic type parameter.
Red Hat logoGithubRedditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

© 2024 Red Hat, Inc.