Maintainability and Clean Code

Advanced Programming, Lecture 11

Advanced Programming, Lecture 11


Set of flashcards Details

Flashcards 29
Language Deutsch
Category Computer Science
Level University
Created / Updated 26.03.2021 / 03.04.2021
Weblink
https://card2brain.ch/box/20210326_maintainability_and_clean_code
Embed
<iframe src="https://card2brain.ch/box/20210326_maintainability_and_clean_code/embed" width="780" height="150" scrolling="no" frameborder="0"></iframe>

Maintainability

  • degree of effectiveness and efficiency with which the product can be modified
  • consists of 
    • Analysability
    • Modularity
    • Reusability
    • Modifiability
    • Testability

Why is Maintainability important?

  • reduces costs during maintenance
  • enables other 7 characteristics of software product quality (security, functional suitability, performance)

How is Maintainability achieved?

  • writing clean code 
  • improves internal and external quality of product

Clean Code - Definition

  • clear, understandable, comprehensible, logical and disciplined implementation of code
  • code is designed to be easy to read, change, expand and maintain

Conventions - Idea and Problem

Idea:

  • improve readability by creating common look and feel

Problems:

  • Conventions are ignored (no knowledge)
  • Conventions differ between languages and communities

Convention - English

Reasons for other Languages

  • harder to write english commentaries/find names
  • bad english skills could lead to misunderstandings/typos

Reasons for using English:

  • English communities are much larger 
  • for help of english community, dont have to translate
  • no mixture of english programming language and local language
  • you should be able to read and speak fluent English

Convention - which to use

  • use language default
    • detailed guidelines available
    • style switches necessary when working on multiple projects within the same team or project with multiple languages
  • decide in your team on a standard
    • keep consistent
    • one style over all languages
    • maybe switching styles between teams

Bad Smells - Definition

  • indications of poor coding and design choices that may lead to bad maintainability
  • technically not incorrect
  • indicate weaknesses and could be slowing down development or increase risk of bugs
  • code vs architectural level

Bad Smells - Architectural Level

  • Lack of Modularity: low cohesion, high coupling
  • God Class: uses many attributes of other classes, many big methods with high complexity, does everything
  • Refused Bequest: Subclasses dont need inherited methods and data from parents, subclass and superclass too different
  • Feature Envy: Method is more interested in data/functions of another class, envies scope of other class
  • Shotgun Surgery: single responsibility has been split up among large number of classes

Bad Smells - Code Level

  • Simulated Polymorphism: conditionals are used instead of inheritance and polymorphism
  • Dead Code: code blocks are never reached, no longer used
  • Duplicated Code: same structure in more than one place, same expressions in two methods,...
  • Data Clumps: Identical group of variables passed from function to function together instead of one single data structure
  • Primitive Obsession: use of primitives to represent domain idea instead of self-defined, meaningful types (Currency, telephone number)

Refactoring - Definition

  • changing a software system in such a way that it doesnt alter external behavior of code but improves internal structure

Refactoring - Advantages

  • improve software design
  • make software easier to understand and modify
  • helps finding bugs by improving general understandability of the code
  • program faster

Refactoring: 

You have a code fragment that could be grouped together

Extract Function

  • turn it into own function
  • replace extracted code with new method call

Refactoring: 

A function is used by more features of another class than by its own class

Move Function

  • in other class create function with similar body
  • turn old function into delegation or remove old function

Refactoring:

type code which affects class behaviour, but subclassing not possible

State/Strategy:

  • replace type code with state object
  • create new state class for type code
  • add subclass of state object for each type code

Refactoring:

Two functions with very similar logic but different literal values

Parameterization

  • use single function and parameterize it 
  • use one of similar functions as baseline
  • replace original calls with calls to parameterized function

Refactoring:

Several sublasses have methods that perfom nearly identical work

Pull up method

  • make methods identical and move them to superclass
  • parameterize them
  • delete sublcass methods

Refactoring: 

subclass and its parent are no longer different enough to be worth keeping separate

Collapse Hierarchy

  • Merge subclass and superclass to one class
  • adjust references and remove empty class

Unit Tests - Placement

  • Unit Testing
    • testing the smallest testable parts (public methods, APIs)
    • do units fulfill functionalities
  • Integration Testing
    • testing groups of units across modules
    • do units perform correctly together
  • System Testing
    • testing entire application as whole
    • does system meet specification
  • Acceptance Testing
    • testing final system before release
    • are end users expectations met

Unit Tests - Definition

  • automated piece of code that invokes unit of work being tested
  • checks assumptions about single end result of that unit
  • consistent in results if production code doesnt change

Unit Tests - Important Properties

  • Self-Documenting and Readable: clear, precise and easy to understand, expressive with clear intent
  • Concept-bounded: should test single concept only, asserts should be minimized
  • Isolated: tested unit should be isolated from external dependencies (databases)

Unit Tests - FIRST

  • properties of clean tests
  • Fast: tests should run quickly, otherwise they are not run frequently
  • Independent: tests should not depend on each other, could cause stream of failure
  • Repeatable: tests should not rely on environment, always yield same result for same code base
  • Self-Validating: boolean output
  • Timely: write tests before production code

Test Driven Development

  1. Write a for now failing test for a piece of functionality
  2. Write production code that passes test
  3. Refactor, run all tests to verify refactoring did not change external behaviour

Stubs

  • controllable replacement for an existing dependency in the system
  • used to test code depending on external objects, without dealing with dependency directly
  • find interface that object under test works against
  • eventually add level of indirection hiding interface
  • replace underlying implementation of interface with something you have control over (stub)

Mocks

  • fake object in system that decides whether unit test fails or passes
  • verifies whether object under test called the fake object as expected
  • class under test communicates with mock, mock records all communication
  • test uses mock object to check if test passed based on verifying communication using expectations

Fakes

  • either mock (tested against) or stub (tested against object under test)
  • main purposes:
    • test independence
    • interface discovery: stubbing/mocking not yet existent classes

Fixtures

  • fixed state that exists at start of the test
  • ensures that test is repeatable by ensuring all preconditions
  • fixture might be setup/torn down after test

Four Phases of a Unit Test

  1. Set up Fixture
  2. Exercise System under test: interact with SUT to exercise the behavior that should be verified
  3. Result Verification: determine whether outcome fails the test or not
  4. Fixture Teardown: put everything back into original state

Unit Tests - Advantages

  • allows programmer to refactor code at later time and make sure that modules still work correctly
  • by testing parts of program first and then sum of its parts integration testing becomes much easier