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
- Write a for now failing test for a piece of functionality
- Write production code that passes test
- 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
- Set up Fixture
- Exercise System under test: interact with SUT to exercise the behavior that should be verified
- Result Verification: determine whether outcome fails the test or not
- 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