Topics
Important Points
SWE Class Diagrams Intermediate
A class diagram can also show different types of relationships between classes: inheritance, compositions, aggregations, dependencies.
We can use a triangle and a solid line (not to be confused with an arrow, which means navigation) to indicate class inheritance.

It does not matter whether the triangle is filled or empty.
Here's an example that combines inheritance with generics:

Composition
Concept
A bit unlike what I have learned in CS2030S, here a composition is an association that represents a strong whole-part relationship. It implies that
when the whole is destroyed, parts are destroyed too e.g., the part cannot exist without being attached to a whole.
there cannot be cyclical links.
Aggregation
Dependency
Concept
In the context of OOP associations, a dependency is a need for one class to depend on another without having a direct association in the same direction. Reason for the exclusion: If there is an association from class Foo to class Bar (e.g., navigable from Foo to Bar), that means Foo is obviously dependent on Bar and hence there is no point in mentioning dependency specifically. In other words, we are specifically focusing on non-obvious dependencies here. One cause of such dependencies is interactions between objects that do not have a long-term link between them.
One example of dependency lies in the method's parameters. For example, in the code below, Foo has a dependency on Bar but it is not an association because it is only a transient interaction and there is no long term relationship between a Foo object and a Bar object. e.g., the Foo object does not keep the Bar object it receives as a parameter.
A class diagram can also show different types of class-like entities, like enumerations, abstract class, interfaces
We have introduced the concept of enumerations in Lec 04. In UML, the enumerations are represented as follows,

In UML, we can use italics or {abstract} (preferred) keyword to denote abstract classes/methods.

UML Notation
An interface is shown similar to a class with an additional keyword <<interface>>. When a class implements an interface, it is shown similar to class inheritance except a dashed line is used instead of a solid line.
For example, the AcademicStaff and the AdminStaff classes implement the SalariedStaff interface.

Java Logging
Logging is the deliberate recording of certain information during a program execution for future reference and it can be useful for troubleshooting problems.
A log file is like the black box of an airplane.
Creating a Logger
To use the default Java logging system, import java.util.logging.*. We obtain a logger instance using a factory method.
Although we can use arbitrary names (e.g., "Foo"), it is recommended to use the class name: Logger.getLogger(MyClass.class.getName()).
Logging Levels (Hierarchy)
Java assigns a level of importance to every log message. This hierarchy determines which messages are important enough to be saved. The standard levels from highest to lowest are:
SEVERE (Highest): Critical failures (crashes).
WARNING: Potential issues.
INFO: Standard operational messages (e.g., "Start", "Stop").
CONFIG: Configuration details.
FINE / FINER / FINEST (Lowest): Detailed tracing for debugging.
Filtering Mechanism
The Logger acts as a filter (like a volume threshold). We set a specific level for the Logger, and it will only output messages that are equal to or higher than that level.
If Level is set to WARNING: It records
WARNINGandSEVERE. (It ignoresINFOand below).If Level is set to INFO: It records
INFO,WARNING, andSEVERE.
Java Assertions
Assertions are used to define assumptions about the program state so that the runtime can verify them. If the runtime detects an assertion failure, it typically takes some drastic action such as terminating the execution with an error message.
Implementation
To implement a Java assertion, we can use the keyword assert. For example, this assertion will fail with the message x should be 0 if x is not 0 at this point.
By default, Java will disable the Java assertions.
When to use Java assertion
Exceptions and assertions are two complementary ways of handling errors in software but they serve different purposes. Therefore, both assertions and exceptions should be used in code.
The raising of an exception indicates an unusual condition created by the user (e.g. user inputs an unacceptable input) or the environment (e.g., a file needed for the program is missing).
An assertion failure indicates the programmer made a mistake in the code (e.g., a null value is returned from a method that is not supposed to return null under any circumstances).
SWE Design Principles
In this part, we will learn three most fundamental design qualities (abstraction, coupling and cohesion) upon which all other design principles are built.
Abstraction
The guiding principle of abstraction is that only details that are relevant to the current perspective or the task at hand need to be considered. As most programs are written to solve complex problems involving large amounts of intricate details, it is impossible to deal with all these details at the same time. That is where abstraction can help.
Awesome explanation above. This is also what we are doing in DDCA!
We have the two abstraction examples,
Data abstraction: abstracting away the lower level data items and thinking in terms of bigger entities
Control abstraction: abstracting away details of the actual control flow to focus on tasks at a higher level. In other words, wrap code into methods.
Coupling
Coupling is a measure of the degree of dependence between components, classes, methods, etc. Low coupling indicates less dependency between components and high coupling should be avoided.
For example, the following image shows that design A have more coupling between the components than design B.

X is coupled to Y if a change to Y can potentially require a change in X. Some examples of coupling: A is coupled to B if,
Ahas access to the internal structure ofB(this results in a very high level of coupling)AandBdepend on the same global variableAcallsBAreceives an object ofBas a parameter or a return valueAinherits fromBAandBare required to follow the same data format or communication protocol
Cohesion
Cohesion is a measure of how strongly-related and focused the various responsibilities of a component are. Higher cohesion is better.
Cohesion can be present in many forms. Some examples:
Code related to a single concept is kept together, e.g. the
Studentcomponent handles everything related to students.Code that is invoked close together in time is kept together, e.g. all code related to initializing the system is kept together.
Code that manipulates the same data structure is kept together, e.g. the
GameArchivecomponent handles everything related to the storage and retrieval of game sessions.
Some other principles
Separation of Concerns Principle (SoC)
To achieve better modularity, separate the code into distinct sections, such that each section addresses a separate concern.
A concern in this context is a set of information that affects the code of a computer program. For example,
A specific feature, such as the code related to the
add employeefeatureA specific aspect, such as the code related to
persistenceorsecurityA specific entity, such as the code related to the
Employeeentity
By applying the SoC principle, we have the following benefits
reduces functional overlaps among code sections and also limits the ripple effect when changes are introduced to a specific part of the system.
By now, you may realize that the two principles given above are somewhat similar, one is specific to OOP and applied at class level while the other is not specific to OOP and can be applied at any level.
Derived classes must be substitutable for their base classes.
LSP implies that a subclass should not be more restrictive than the behavior specified by the superclass. In other words, the subclass cannot break the specifications set by the super class. (How to find that specifications, review CS2030S!)
Classic Questions
Assertion failure
A Calculator program crashes with an ‘assertion failure’ message when you try to find the square root of a negative number.
Explanation: An assertion failure indicates a bug in the code. (b) is not acceptable because of the word "terminated". The application should not fail at all for this input. But it could have used an exception to handle the situation internally.
Coupling Levels
Discuss the coupling levels of alternative designs x and y.

Ans: Overall coupling levels in x and y seem to be similar (neither has more dependencies than the other). (Note that the number of dependency links is not a definitive measure of the level of coupling. Some links may be stronger than the others.). However, in x, A is highly-coupled to the rest of the system while B, C, D, and E are standalone (do not depend on anything else). In y, no component is as highly-coupled as A of x. However, only D and E are standalone.
Some principles
“Only the GUI class should interact with the user. The GUI class should only concern itself with user interactions”. This statement follows from,
Explanation: By making ‘user interaction’ the GUI class’s sole responsibility, we increase its cohesion. This is also in line with the separation of concerns (e.g., we separated the concern of user interaction) and the single responsibility principle (the GUI class has only one responsibility).
Last updated



