This site is from a past semester! The current version will be here when the new semester starts.
CS2113/T 2021 Jan-May
  • Full Timeline
  • Week 1 [Mon, Jan 11th]
  • Week 2 [Mon, Jun 21st]
  • Week 3 [Mon, Jun 28th]
  • Week 4 [Mon, Jul 5th]
  • Week 5 [Mon, Jul 12th]
  • Week 6 [Mon, Jul 19th]
  • Week 7 [Mon, Jul 26th]
  • Week 8 [Mon, Aug 9th]
  • Week 9 [Mon, Aug 16th]
  • Week 10 [Mon, Aug 23rd]
  • Week 11 [Mon, Aug 30th]
  • Week 12 [Mon, Sep 6th]
  • Week 13 [Mon, Sep 13th]
  • Textbook
  • Admin Info
  • Dashboards
  •  Individual Project (iP):
  • Individual Project Info
  • iP Upstream Repo
  • iP Code Dashboard
  • iP Progress Dashboard

  •  Team Project (tP):
  • Team Project Info
  • Reference AB3
  • Team List
  • tP Code Dashboard
  • tP Progress Dashboard
  • Java exercises
  • Report Bugs
  • Forum
  • Gitter (Chat)
  • Instructors
  • Announcements
  • Files (handouts, submissions etc.)
  • Tutorial Schedule
  • Java Coding Standard
  • Git Conventions
  • Forum Activities Dashboard
  • Participation Dashboard
  • Principles

    Can explain single responsibility principle

    Single responsibility principle (SRP): A class should have one, and only one, reason to change. -- Robert C. Martin

    If a class has only one responsibility, it needs to change only when there is a change to that responsibility.

    Consider a TextUi class that does parsing of the user commands as well as interacting with the user. That class needs to change when the formatting of the UI changes as well as when the syntax of the user command changes. Hence, such a class does not follow the SRP.

    Gather together the things that change for the same reasons. Separate those things that change for different reasons. ―- Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin

    Can explain Liskov Substitution Principle

    Liskov substitution principle (LSP): Derived classes must be substitutable for their base classes. -- proposed by Barbara Liskov

    LSP sounds the same as substitutability but it goes beyond substitutability; LSP implies that a subclass should not be more restrictive than the behavior specified by the superclass. As you know, Java has language support for substitutability. However, if LSP is not followed, substituting a subclass object for a superclass object can break the functionality of the code.

    Paradigms → OOP → Inheritance →

    Substitutability

    Every instance of a subclass is an instance of the superclass, but not vice-versa. As a result, inheritance allows substitutability: the ability to substitute a child class object where a parent class object is expected.

    An AcademicStaff is an instance of a Staff, but a Staff is not necessarily an instance of an AcademicStaff. i.e. wherever an object of the superclass is expected, it can be substituted by an object of any of its subclasses.

    The following code is valid because an AcademicStaff object is substitutable as a Staff object.

    Staff staff = new AcademicStaff(); // OK
    

    But the following code is not valid because staff is declared as a Staff type and therefore its value may or may not be of type AcademicStaff, which is the type expected by variable academicStaff.

    Staff staff;
    ...
    AcademicStaff academicStaff = staff; // Not OK
    

    Suppose the Payroll class depends on the adjustMySalary(int percent) method of the Staff class. Furthermore, the Staff class states that the adjustMySalary method will work for all positive percent values. Both the Admin and Academic classes override the adjustMySalary method.

    Now consider the following:

    • The Admin#adjustMySalary method works for both negative and positive percent values.
    • The Academic#adjustMySalary method works for percent values 1..100 only.

    In the above scenario,

    • The Admin class follows LSP because it fulfills Payroll’s expectation of Staff objects (i.e. it works for all positive values). Substituting Admin objects for Staff objects will not break the Payroll class functionality.
    • The Academic class violates LSP because it will not work for percent values over 100 as expected by the Payroll class. Substituting Academic objects for Staff objects can potentially break the Payroll class functionality.

    The Rectangle#resize() method can take any integers for height and width. This contract is violated by the subclass Square#resize() because it does not accept a height that is different from the width.

    class Rectangle {
        ...
        /** sets the size to the given height and width*/
        void resize(int height, int width) {
            ...
        }
    }
    
    
    class Square extends Rectangle {
        
        @Override
        void resize(int height, int width) {
            if (height != width) {
                //error
           }
        }
    }
    

    Now consider the following method that is written to work with the Rectangle class.

    void makeSameSize(Rectangle original, Rectangle toResize) {
        toResize.resize(original.getHeight(), original.getWidth());
    }
    

    This code will fail if it is called as makeSameSize(new Rectangle(12, 8), new Square(4, 4)). That is, the Square class is not substitutable for the Rectangle class.

    If a subclass imposes more restrictive conditions than its parent class, it violates Liskov Substitution Principle.

    True.

    Explanation: If the subclass is more restrictive than the parent class, code that worked with the parent class may not work with the child class. Hence, the substitutability does not exist and LSP is violated.

    Can explain separation of concerns principle

    Separation of concerns principle (SoC): To achieve better modularity, separate the code into distinct sections, such that each section addresses a separate concern. -- Proposed by Edsger W. Dijkstra

    A concern in this context is a set of information that affects the code of a computer program.

    Examples for concerns:

    • A specific feature, such as the code related to the add employee feature
    • A specific aspect, such as the code related to persistence or security
    • A specific entity, such as the code related to the Employee entity

    Applying Separation of ConcernsSoC reduces functional overlaps among code sections and also limits the ripple effect when changes are introduced to a specific part of the system.

    If the code related to persistence is separated from the code related to security, a change to how the data are persisted will not need changes to how the security is implemented.

    This principle can be applied at the class level, as well as at higher levels.

    The n-tier architecture utilizes this principle. Each layer in the architecture has a well-defined functionality that has no functional overlap with each other.

    Can identify n-tier architectural style

    In the n-tier style, higher layers make use of services provided by lower layers. Lower layers are independent of higher layers. Other names: multi-layered, layered.

    Operating systems and network communication software often use n-tier style.

    This principle should lead to higher cohesion and lower coupling.

    Can explain coupling

    Coupling is a measure of the degree of dependence between components, classes, methods, etc. Low coupling indicates that a component is less dependent on other components. High coupling (aka tight coupling or strong coupling) is discouraged due to the following disadvantages:

    • Maintenance is harder because a change in one module could cause changes in other modules coupled to it (i.e. a ripple effect).
    • Integration is harder because multiple components coupled with each other have to be integrated at the same time.
    • Testing and reuse of the module is harder due to its dependence on other modules.

    In the example below, design A appears to have more coupling between the components than design B.

    Discuss the coupling levels of alternative designs x and y.

    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.

    Explain the link (if any) between regressions and coupling.

    When the system is highly-coupled, the risk of regressions is higher too e.g. when component A is modified, all components ‘coupled’ to component A risk ‘unintended behavioral changes’.

    Discuss the relationship between coupling and a measure of how easily a given component can be testedtestability.

    Coupling decreases testability because if the Software Under TestSUT is coupled to many other components, it becomes difficult to test the SUT in isolation of its dependencies.

    Choose the correct statements.

    • a. As coupling increases, testability decreases.
    • b. As coupling increases, the risk of regression increases.
    • c. As coupling increases, the value of automated regression testing increases.
    • d. As coupling increases, integration becomes easier as everything is connected together.
    • e. As coupling increases, maintainability decreases.

    (a)(b)(c)(d)(e)

    Explanation: High coupling means either more components are required to be integrated at once in a big-bang fashion (increasing the risk of things going wrong) or more drivers and stubs are required when integrating incrementally.

    Can explain cohesion

    Cohesion is a measure of how strongly-related and focused the various responsibilities of a component are. A highly-cohesive component keeps related functionalities together while keeping out all other unrelated things.

    Higher cohesion is better. Disadvantages of low cohesion (aka weak cohesion):

    • Lowers the understandability of modules as it is difficult to express module functionalities at a higher level.
    • Lowers maintainability because a module can be modified due to unrelated causes (reason: the module contains code unrelated to each other) or many modules may need to be modified to achieve a small change in behavior (reason: because the code related to that change is not localized to a single module).
    • Lowers reusability of modules because they do not represent logical units of functionality.

    “Only the GUI class should interact with the user. The GUI class should only concern itself with user interactions”. This statement follows from,

    • a. A software design should promote separation of concerns in a design.
    • b. A software design should increase cohesion of its components.
    • c. A software design should follow single responsibility principle.

    (a)(b)(c)

    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 (i.e., we separated the concern of user interaction) and the single responsibility principle (the GUI class has only one responsibility).