wkrl / se-application

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

se-application

Demo application of the Software Engineering course.

SE-Application has a modular structure that is comprised of components that follow certain software engineering principles.

Components are basic building blocks of an application that represent a coarser level of abstraction than classes. Components often consist of multiple parts such as parts for performing the logic (e.g. transactions or calculations), parts that create views of a GUI (e.g. a web-GUI or a JavaFX-GUI) and parts that configure and control other parts. It has become good software engineering practice to decouple interfaces from implementations, including user interfaces (views) from performing functions (logic). This principle is called separation of concerns and is an essential software engineering method to introduce structure and clarity in software systems.

In this code base, "Views" are used to implement GUI parts of an application component and "Logic" is referred to implementing functionality.

The first application component is a Tax Calculator. Its view-part is responsible for displaying the key panel, receiving key/mouse input and displaying calculation results. The Tax Calculator's

  • GUI-component is comprised of files from the fxgui-package: Calculator.fxml, Calculator.css, CalculatorFXMLController.java.
  • Actual calculations are performed in the logic-part located in the logic-package: CalculatorLogic.java.

Both parts are implemented in separate Java packages and classes. Both are connected by interfaces, ViewIntf and LogicIntf, that connect both parts to each other.

Interfaces consist of Interface definitions (public Java Intf-interfaces) and references to instances (Java objects) that implement interfaces. Those are often instances of private (non-public) Impl-classes of an interface. Instances often exist as singletons meaning that only one instance of a class exists and distributed ("wired") to other parts that need to access them by injecting their references. "Wiring" is a complex configuration task.

In this code base, component interfaces are defined in a "component"-class located in the components-package. components.Calculator.java contains interface definitions for the Tax Calculator:

  • Calculator.ViewIntf - implemented by CalculatorFXMLController.java in the GUI and
  • Calculator.LogicIntf - implemented by CalculatorLogic.java. Both parts have no other connections, dependencies, imports, references other than those two interfaces.

Wiring is the process of connecting instances that implement certain interfaces to component parts that need to access interfaces. An interface cannot be accessed with no implementation (instance) behind. Hence, the reference to an instance that implements an interface must be bound ("wired") into the component where it is accessed. It is important that only the interface definition is known in the code where the interface is used. The implementation class of the interface should be hidden (non-public) to the code making sure that the interface is the only dependency and no other "import" exists other than the interface.

Wiring can be performed by explicitly injecting a reference into a component by invoking a method called inject( Intf ref ); during its configuration. Frameworks such as Spring perform wiring automatically.

Lifecycle. Since components are comprised of multiple parts, they can be complex and their "lifecycle" needs to be carefully designed and implemented. Lifecycle operations span from creation (instantiation) and configuration to start, operation, shut down and destruction - all performed in an explicitly controlled, orderly manner. Lifecycle operations are important for components and should explicitly be defined by lifecycle interfaces that include operations such as create(), startup(), shutdown() and destroy().

Lifecycle Components. This leads to the need for other components that are not concerned with performing application logic or the GUI, but with the "managing" and "operating" the other components by executing their lifecycle operations. Those components include:

  • Configurators as special components that provide configuration information (AppConfigurator.java is an example).
  • Builders are special components that build (create, configure, wire) other components.
  • Runners are special components that execute (start, stop) other components.

Most of these components exist throughout the lifetime of the application as singleton instances. Since they control other components, they must be created first and also shut down last.

About


Languages

Language:Java 93.7%Language:CSS 4.4%Language:C++ 1.9%