summary

Gergő Pintér, PhD

gergo.pinter@uni-corvinus.hu

program is like a recipe

  • executing a program is following a recipe
  • programming is like creating a recipe
  • software development is like running a restaurant
    • come up with recipes,
    • cook the food,
    • ingredient logistics and preparation,
    • food serving,
    • marketing,
    • cleaning

software development often compared to house building

  • because it is an engineering discipline
  • but software does not have to obey the laws of physics
  • software design should focus only on the data structures and the connection between the modules
    • not the implementation details
      (e.g., hardware)

software development is more like gardening

  • a garden might be planned
  • external factors influence the result
    • weather, pests
  • garden needs constant care to bloom
  • sometimes also experimentation
    • methods, tools
  • garden is like an art (with function)

software growth

  • number of lines of code is increasing
    • which increases complexity
  • “every line of code written comes at a price: maintenance” [1]
    • larger garden, more gardening
  • software development processes to handle the complexity

evolution of software life cycle models (incomplete)

  • software life cycle models
    • waterfall
      • improved waterfall
    • V model
    • iterative
    • agile
  • regarding to change management

waterfall model

  • sequential, rigid model
    • (originally) not possible to step back to a previous phase
  • testing is after the implementation, errors are found late in the process
  • not possible to make changes during the development
  • could take years

V model

  • still rigid
  • each phase has output and a review process
    • errors are found at early stage
    • decreases the risk of failure
  • large to small: testing is done in a hierarchical perspective

iterative model

  • software is built incrementally,
    • with each iteration adding new features or refining existing ones
  • possible to get feedback after each iteration
  • can be rigid within an iteration

agile model

  • continuous collaboration and fast response to change, while the iterative model takes a more gradual approach, building up the final product over multiple iterations
  • scrum is an agile methodology

scrum team

  • optimally 3 to 9 people
  • cross-functional
  • self-organizing

roles

  • scrum master
    • responsible establishing scrum as defined in the Scrum Guide
      • by helping everyone understand the theory and practice, both within the scrum team and the organization
    • responsible for the scrum team’s effectiveness
  • product owner
    • responsible for maximizing the value of the product resulting from the work of the scrum team
    • also responsible for effective product backlog management
  • developers

sprint planning

  • initiates the sprint
  • maximum of eight hours for a one-month sprint
  • define a sprint goal
    • definition of done
  • it is up to the developers how to turn product backlog items into increments

sprint

  • 1-4 week long
  • considered a short project
  • turns backlog items into increments
  • includes daily scrum

sprint review

  • scrum team presents the their work to the stakeholders
    • increment is evaluated
  • the attendees collaborate on what to do next
  • maximum of four hours for a one-month sprint

sprint retrospective

  • concludes the sprint
  • maximum of three hours for a one-month sprint
  • the scrum team discusses what went well/bad, what problems encountered

kanban

  • uses a visual workflow
  • pull-based system
    • no task in the workflow without request
  • uses columns for states of the product
  • defines conditions when to move a task between columns
  • conditions flow
    • no iterations (sprints)
    • no roles
  • encourages to improve the workflow

steps of requirement analysis

based on [2]

functional and non-functional requirements

  • functional requirements define
    what a system is supposed to do
  • non-functional requirements define
    how a system is supposed to operate
    • e.g., legal requirements (GDPR)

minimum viable product

what is a user story?

  • a popular tool in requirements analysis, particularly in agile software development methodologies
  • simple description of a software feature
    • from the perspective of the end user or customer
  • and are often accompanied by acceptance criteria (BDD),
    • which define the conditions that must be met to be considered complete

as a [type of user], I want to [action/function] in order to [benefit/value]

behaviour-driven development

  • BDD starts from a user story and
    focuses on adding acceptance criteria
  • extends user stories how the software should react in some with scenarios (conditions)
Title (one line describing the story)

Narrative:
As a [role]
I want [feature]
So that [benefit]

Acceptance Criteria:
(presented as Scenarios)

Scenario 1: Title
Given [context]
  And [some more context]...
When  [event]
Then  [outcome]
  And [another outcome]...

Scenario 2: ...

user story mapping

  • performed in workshops including
    • users,
    • (UI) designers,
    • developers,
    • testers,
    • and stakeholders
  • build a shared understanding of the product and a common language
  • living document

user story mapping mistakes

more from Jeff Patton: 5 story mapping mistakes

unified modeling language

  • UML 2.0 released in 2005
    • latest revision in 2017
  • ISO/IEC 19501 standard
  • designed to be a complete language of software modelling
  • UML 2 has 14 diagrams in two categories: structure and behavior

most software developer do not use UML (in a formal way), but hand drawn sketches which often include UML elements [3]

use case diagram

  • depicts the interactions between system users (actors) and the system itself
  • used to specify the functional requirements
  • provides a high-level view
    • helping stakeholders to understand the system’s functionality
  • it’s purpose is similar to the user story

class diagram

  • describes the structure of a system by its classes
    • their attributes, methods, and the relationships among them
  • main building block of the object-oriented modeling

object diagram

  • special case of a class diagram
  • graphical representation of the objects and their relationships
    at a specific moment in time
  • provides a snapshot of the system’s structure
  • does not show anything architecturally different to class diagram

component diagram

  • depicts the component structure and relations
  • highlighting the interfaces

state diagram

  • a visual representation of the states a system or an object can be in also the transitions between those states
  • models the dynamic behavior of the system, capturing how it responds to different events over time
  • shows the system’s life cycle

activity diagram

  • graphical representations of workflows
  • similar to flowcharts
    • but uses UML notation
    • and can visualize parallel processing
    • has more features
flowchart
activity (UML)

sequence diagram

  • shows process interactions arranged in time sequence
  • depicts the processes and objects involved and the sequence of messages exchanged
  • instead of the inner parts of a system, message exchange between software systems can be depicted

what is the issue with UML?

  • closely connected with OOP
  • propagates object-oriented modelling
    • however the design should not consider the implementation

C4 model

overview first, zoom and filter, then details on demand

– Ben Shneiderman

  • hierarchical set of software architecture diagrams
    • different levels of abstraction for different audience
  • has four levels:
    • context, containers, components and code
  • popularized by Simon Brown

this chapter is based on c4model.com

level 1: system context diagram

  • shows how the software fits into the world
    • who use it
    • what other software does it interacts
  • high level diagram
    • technologies, protocols and other low-level details are not important
  • similar to use case diagram
  • understandable for non-technical people

other possible users:

administrator, course planner

level 2: container diagram

  • zooms into the software system
  • shows the containers that make up that software system
    • applications, data stores, microservices, etc.
  • technology decisions are also a key part of this diagram
    • what database management system to use, e.g., PostgreSQL
    • what e-mail service to use, e.g., Mailchimp
    • what language to use
    • what UI framework to use

level 3: component diagram

  • decomposition of each container to identify the major structural building blocks and their interactions
  • shows how a container is made up of a number of “components”
    • what these components are,
    • what they are responsibilities for, and
    • what also shows technology / implementation details
  • roughly equivalent with the UML component diagram
the example shows the components of only one feature, so incomplete

level 4: code

  • optional level of detail
  • ideally this diagram would be automatically generated
  • if you really want or need to, you can zoom into an individual component
    • but show only those attributes and methods that really needed for the storytelling
  • UML class diagram can be used
this may be too much

software design and architecture stack

based on Khalil Stemmel’s figure [4]

gang of four (GoF) design patterns

  • GoF: Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides
  • 23 common software design patterns
    • published in “Design Patterns: Elements of Reusable Object-Oriented Software” (1994) [5]
  • provides solutions to common design problems
  • categorized into three main groups
    1. creational
    2. structural
    3. behavioral

read about the design patterns in details, for example at refactoring.guru

GoF design patterns in functional programming

OO pattern FP pattern
factory pattern function
strategy pattern function
decorator pattern function
visitor pattern function

Peter Norvig demonstrated that 16 out of the 23 patterns are simplified or eliminated by language features in Lisp or Dylan (1998) [6]

more about it from Scott Wlaschin [7]

SOLID principles

SOLID is a mnemonic acronym for five design principles intended to make object-oriented designs more understandable, flexible, and maintainable [8]

single responsibility principle
a class should do one thing and therefore it should have only a single reason to change
open-closed principle
classes should be open for extension and closed to modification
Liskov substitution principle
if class A is a subtype of class B, B should be able to replaced with A without disrupting the behavior of the program
interface segregation principle
many client-specific interfaces are better than one general-purpose interface. Clients should not be forced to implement a function they do no need.
dependency inversion principle
modules should depend upon interfaces or abstract classes, not concrete classes. It’s an inversion because implementations depend upon abstractions and not the other way round

based on [9], [10]

coupling

  • the degree of interdependence between software modules
  • coupling is usually contrasted with cohesion
    • low coupling often correlates with high cohesion, and vice versa
from Wikimedia | public domain

source Wikipedia [11]

architectural styles / topologies

architectural patterns

MVC

ASP.NET, Django (Python), Ruby on Rails, Laravel (PHP)

MVP

Windows Forms, Java Swing

MVVM

WPF, AngularJS

  • view is responsible for rendering UI
  • controller responds to the user input (in MVC) and performs interactions on the data model
  • model is responsible for managing the data

interface is an agreement

  • how a module / component will work
  • so as long as the agreement is complied the components do not need to know about the internal structure/work of the other components
    • separation of concerns
    • single responsibility principle
    • the other component can be replaced, mocked

interface changes should be communicated

  • during design / development
    • change can be necessary / allowed, but communicate towards the impacted teams
    • diagrams show inner dependencies
  • services announce API deprecations
  • so as library / framework developers
    • can be a source of new issues even if downstream code is not changed

API versions

https://developers.facebook.com/v21.0/me?fields=id,name

def unary_union(self):
    warnings.warn(
        "The 'unary_union' attribute is deprecated, "
        "use the 'union_all' method instead.",
        DeprecationWarning,
        stacklevel=2,
    )
    return self.union_all()

implementation planning

  1. define goals
    • practically done with requirement analysis
  2. conduct research
    • partially done at the requirement elicitation phase
  3. map out risks
  4. schedule milestones
  5. assign responsibilities and tasks
  6. allocate resources

learning could be a task

  • you may need to work a technology / framework / language that you are not familiar with
  • that may require research
    • fail fast
    • document findings
      • minimal workable example
  • or you just have to learn a new codebase
  • calculate with learning during the planning

identify and prioritize risks

a risk is a possibility that something bad can happen

  • there is risk inherent with building any piece of software
  • whether you’re building a completely new greenfield project,
  • or adding a new feature to an existing codebase
    • other parts cease to work
    • the new feature alienate users
    • data loss
  • often difficult to prioritise which risks you should take care of
    • the probability: how likely is it that the risk will happen?
    • and the impact: what is the negative impact if the risk does occur?

risk storming

  • visual and collaborative risk identification technique
  • created by Simon Brown (author of C4 model)
  • motivation: often only one person evaluated risks
  • risk evaluation should be collaborative activity

risk register

  • a risk register is a document used as a risk management tool
  • contains all identified risks with additional information
    • category, name, responsible, probability, impact, mitigation, action by, action when
  • it can be displayed as a table or as a scatterplot
Risk Impact
(1-3)
Likelihood
(0-10)
Risk
(I * L)
Mitigation
Rust Language Changes 2 7 14 Target a specific Rustc version
Missing GCC 13 upstream window 1 6 6 Merge in GCC 14 and be proactive about reviews

schedule milestones

  • visualize project milestones
    • Gantt chart
  • keep the entire team posted
  • pay attention to holidays
    • multiple countries in the case of an international team
  • things won’t go as planned, so
    • add safety margin (wiggle room)
    • e.g., an extra week before deadline for fixing bugs
Gantt chart from Wikipedia   public domain

assign responsibilities and tasks

  • every task you want to make done should have exactly one person responsible
    • no assignee – no one will do it
    • more than one – “I though the other one was doing it”
  • define area of responsibility
    • a task (as in scrum) should have definition of done, which specifies it
  • everyone needs to know what other people are responsible for
    • scrum/kanban board can visualize it
    • issue/ticket trackers can also work

at the end of a sprint planning, every task in the sprint backlog should have an assignee

source: [13]

dependencies

allocate resources

  • scrum (and agile in general) does not say anything about how to estimate (time)
  • story points are often used instead
    • (relative) unit of effort required to fully implement a product backlog item
    • e.g., 1–5,
    • Fibonacci: 1, 2, 3, 5, 8, 13…
    • powers of 2: 1, 2, 4, 8, 16, 32…
planning poker by Hkniberg   public domain

“Story points reward team members for solving problems based on difficulty, not time spent. This keeps team members focused on shipping value, not spending time [14].”

estimation is guessing

  • many developers do not like to estimate
  • seemingly simple task can turn out to be difficult
    • some difficulties are hard to foresee
    • bad architectural decision
      • “Adding manpower to a late software project makes it later.” – Fred Brooks
  • make educated guesses instead
    • measure
      • burn down charts, cumulative flow diagram
    • infer from previous tasks

wireframing

  • responsibility of the UI/UX designers
  • occurs during the exploratory design phase
    • experimenting
  • iterative process
  • iterations are presented to the stakeholders to gain feedback
  • some professional tools: Figma, Balsamiq, Sketch
    • any drawing/diagramming tool can be used for the low or mid fidelity wireframes
Interaction Design Foundation [15] | CC BY-SA 4.0

based on: [16]

wireframe

  • a wireframe is an outline / blueprint / concept art of a webpage or application
  • can be hand drawn on paper or built out digitally
  • provides visual understanding of page structure, layout, user flow, functionality and intended behaviours
  • presented to stakeholders before the interface is coded

source: [16]

types of wireframes

low-fidelity
mid-fidelity
high-fidelity

wireframe map

shows user flow, ~ user story map flow

software design and architecture stack

based on Khalil Stemmel’s figure [4]

hierarchy in style guides

not just style guides, also best practices

write idiomatic code

  • a prog. language implements a prog. paradigm
  • a paradigm defines a certain “way” of writing code
    • using different abstractions / building blocks
    • promoting a given concept
  • some languages implements multiple paradigms
  • and languages have their own way of doing things
    • languages have pros and cons for a given problem

just as in the case of natural languages, you ought to use a language properly

clean code / meaningful names [17]

  • use intention-revealing names
  • pick one word per concept
  • avoid disinformation
  • make meaningful distinctions
    • don’t use names like doSomething() and doSomething2()
  • use pronounceable names
  • use searchable names
    • “The longer the scope of a function, the shorter its name should be.” – Robert C. Martin
  • avoid encodings
    • intNumberOfDays = 0
  • don’t pun or use humor, be professional

names for classes, functions

  • a class is a model / blueprint of something
  • the name should be a noun
    • e.g., User, Activity
  • an object is an instance of a class
    • still a noun
    • e.g., user = User()
  • a function does something
  • the name should contain a verb
    • in imperative
    • e.g., aggregate_activity
    • activity_aggregation

clean code / functions [17]

  • “Functions should hardly ever be 20 lines long” [17]
    • shorter functions are easier to understand
  • do one thing (single responsibility principle)
  • “The longer the scope of a function, the shorter its name should be.” – Robert C. Martin
  • do not use more than three arguments
  • do not use flags
  • no side effects
  • prefer exceptions to returning error codes

clean code / comments [17]

avoid

  • journal comments
  • noise comments
  • writing something that is already in the code
  • closing brace comments
  • separating comments

however, comments can be used if they help to understand the code

  • legal comments (licence information)
  • informative comments, that explain what is happening
  • documentation
by Oliver Widder (Geek and Poke) CC BY 3.0

code quality

agile
working software over comprehensive documentation
software craftmanship
not only working software, but also well-crafted software
well-crafted
  • high quality
  • well-designed
  • validated and verified
  • tested
  • code is clean, easy to understand and maintain

code smell

a code smell is a surface indication that usually corresponds to a deeper problem

– Martin Flower [18]

software rot is the degradation, deterioration, or loss of the use or performance of software over time [19]

requirement smell: signs in the requirements that are not necessarily wrong but could be problematic [20]

clean clode violations as code smells

  • long method
  • long parameter list
  • naming
    • notation in names
    • inconsistent names
    • uncommunicative names
  • comments
  • large class
    • possibly do more than one thing
  • a function / class does more than one thing
  • magic number
  • duplicated code
  • speculative generality
  • dead code
  • too complexity comditions
  • feature envy
  • bad comment
    • obsolete, redundant (noise), commented-out code

source: [21], [17]

how to measure code quality?

it is hard to objectively measure the quality of code

  • number of source lines of code (SLOC)
  • style guide compliance – is the code clean?
  • Halstead metrics
  • cyclomatic complexity – is the code simple?
  • maintainability index
  • test coverage – is the code tested?

cyclomatic comlexity

  • developed by Thomas J. McCabe in 1976
  • quantitative measure of the number of linearly independent paths through the source code
  • computed using the control-flow graph of the program

defined as:

M=EN+2P M = E - N + 2P

  • E: the number of edges of the graph
  • N: the number of nodes of the graph
  • P: the number of connected components
    • for a single method, P always equals 1

cyclomatic comlexity – example

def calculate_progress(
    finished: int,
    total: int,
    as_percentage: bool,
    foo: bool
) -> float:
    progress = finished / total

    if as_percentage and foo:
        return progress * 100
    else:
        return progress

activity diagram

control flow

CC=EN+2 CC = E - N + 2 CC=76+2 CC = 7 - 6 + 2 CC=3 CC = 3

WTF per minute

own drawing based on Glen Lipka’s

V model [22]

  • each phase has output and a review process
    • errors are found at early stage
    • decreases the risk of failure
  • testing is done in a hierarchical perspective

requirement analysis review

user story map
  • can be discussed / reviewed
  • even with a customer representative

user story “reviewed” in an issue tracker

architecture review

C4 diagrams as the output of the high level design

risk storming as a review process

code review

def query_progress(user_id:int) -> float:
    # establish connection
    con= sqlite3.connect("data.db")
    # build query
    progress_query = f"""
    SELECT
        lesson / 50.0 AS progress
    FROM activity
    WHERE
        user_id = {user_id} AND
        result = 'success'
    ORDER BY
        lesson DESC
    LIMIT 1
    ;
    """
    # execute query
    res =con.execute(progress_query)
    progress=res.fetchone()[0]
    return progress
  • does not respect style guide
  • does 3 things
    • establish DB connection
    • build query
    • execute query
  • contains separation comments
  • hard coded divisor
    • magic number

every work product can and should be reviewed

review types by formality

type formality led by effort documentation
informal not formal noone minimal undocumented
walkthrough not formal1 authors very low normal, fault-finding
technical less formal trained moderator, not the author moderate more detailed
inspection most formal trained moderator high thorough; based on standards, checklists

review – author’s perspective

  • be humble
    • mind that everybody’s code can be improved
    • you are not perfect, accept that you will make mistakes
  • open to feedback
  • you are not your code
  • the goal is to deliver higher quality code, not about arguing who was right
    • you and the reviewer are in the same side
  • you and the reviewer are not only talking about the code,
    • you are exchanging best practices and experiences
  • you can learn from the review

review – reviewer’s perspective

  • use I-messages
  • talk about the code, not the coder
  • ask questions instead of making statements
  • refer to the behavior, not the traits of the author
  • accept that there are different solutions
  • respect and trust the author
  • mind the OIR-rule of giving feedback
    • observation, impact, request
  • before giving feedback, ask yourself:
    • is it true? (opinion != truth)
    • is it necessary? (avoid nagging, focus on the current work product)
    • is it kind? (no shaming)
  • be humble; you are not perfect and you can also improve
  • it’s fine to say: Everything is good!
  • don’t forget to praise

V model [22]

  • each phase has output and a review process
    • errors are found at early stage
    • decreases the risk of failure
  • testing is done in a hierarchical perspective
  • review is a testing process usually without executing the code

test pyramid

the turtle and rabbit figures by Delapouite under CC BY 3.0 via game-icons.net

what is a unit?

  • defined as a single behaviour exhibited by the system under test
    • usually corresponding to a requirement
  • often corresponds to a function or a module / method or a class
    • depending on the paradigm
    • often, but not always
  • “only entry points to externally-visible system behaviours define units”
    • by Kent Beck [24]

a unit test is another piece of code, that tests the given unit

arrange, act, assert(, annihilate) pattern

parts of a unit test

arrange
set up the testing environment (e.g., create objects)
act
call the tested unit
assert
compare the result of the ‘act’ step to the expected value
(annihilate)
free resources
automatic in modern languages
def test_fizzbuzz():
    # arrange
    test_input = 3
    # act
    result = fizzbuzz(test_input)
    # assert
    assert result == "Fizz"

mocking

  • the whole unit test suite should be able to run in milliseconds
    • to give immediate feedback
  • slow elements of the software should be mocked
    • e.g., database, network connection
  • part of arrange step

test doubles – mock object types

there is no open standard for categories

  • dummy
  • stub
  • spy
  • mock
  • fake
reproduction of figure 2 from [25]

these are from the book xUnit test patterns: Refactoring test code – by Gerard Meszaros [26]

test-driven development (TDD)

  • write test before writing the tested code
  • without the called unit the test fill fail
    • the called function does not exist
  • write code, that makes the test pass
  • improve the code quality
    • e.g., make it clear and clean
    • both the test and tested code

As the tests get more specific, the code gets more generic.

– Robert C. Martin, The Cycles of TDD [27]

test coverage

  • the percentage of the code lines ‘protected’ or covered by tests

code/fizzbuzz.py

def fizzbuzz(i: int) -> str:
    result = ""
    if i % 15 == 0:
        result += "FizzBuzz"
    elif i % 3 == 0:
        result += "Fizz"
    elif i % 5 == 0:
        result += "Buzz"
    else:
        result = str(i)
    return result
def fizzbuzz(i: int) -> str:
    result = ""
    if i % 15 == 0:
        result += "FizzBuzz"
    elif i % 3 == 0:
        result += "Fizz"
    elif i % 5 == 0:
        result += "Buzz"
    else:
        result = str(i)
    return result
def fizzbuzz(i: int) -> str:
    result = ""
    if i % 15 == 0:
        result += "FizzBuzz"
    elif i % 3 == 0:
        result += "Fizz"
    elif i % 5 == 0:
        result += "Buzz"
    else:
        result = str(i)
    return result

code/test_fizzbuzz.py

from fizzbuzz import fizzbuzz


def test_fizzbuzz():
    assert fizzbuzz(15) == "FizzBuzz"
    assert fizzbuzz(3) == "Fizz"
from fizzbuzz import fizzbuzz


def test_fizzbuzz():
    assert fizzbuzz(15) == "FizzBuzz"
    assert fizzbuzz(3) == "Fizz"
    assert fizzbuzz(5) == "Buzz"
from fizzbuzz import fizzbuzz


def test_fizzbuzz():
    assert fizzbuzz(15) == "FizzBuzz"
    assert fizzbuzz(3) == "Fizz"
    assert fizzbuzz(5) == "Buzz"
    assert fizzbuzz(17) == "17"

test coverage: 70%

test coverage: 90%

test coverage: 100%

four control flow branch, all of them needs to be tested

how to measure code quality?

it is hard to objectively measure the quality of code

  • number of source lines of code (SLOC)
  • style guide compliance – is the code clean?
  • Halstead metrics
  • cyclomatic complexity – is the code simple?
  • maintainability index
  • test coverage – is the code tested?

what to test - the edge cases

def calculate_progress(
    finished: int,
    total: int,
    as_percentage: bool,
) -> float:
    progress = finished / total

    if as_percentage:
        return progress * 100
    else:
        return progress

this function need some value checking

what does this function do?
  • divides the number of finished lessons by the total number of lessons
  • returns progress in the closed interval of [0, 1] or [0, 100]
edge cases
  • total is 0
  • total is less than 0
  • finished is less than 0
  • finished is greater than total

test coverage only measures that every control flow branch is tested

the point of testing is testing for the edge cases

changing the software

add feature fix a bug refactor optimize
structure changes changes changes
new funcionality changes
functionality changes
resource usage changes

Michael Feathers, Working Effectively with Legacy Code: part 1 pp 6 [28]

testing approaches

black box

  • examining / testing the functionality without knowing the inner structure
  • works at all levels: unit, integration, system, acceptance
  • also for debugging a legacy code

white box

  • testing the internal structure as opposed to its functionality
  • often associated to unit testing, but also works on higher levels (i.e., integration, system)

what to automatize?

repetitve tasks of

  • style guide compliance
  • code smell finding
  • code quality measurement
  • review
  • building
  • testing
  • deployment

scripting: writing relatively short and simple code to automatize an otherwise manual process

local automatization based on the code editor

linting

  • a linter in modern editors behaves like a spell checker in a word processor
    • gives immediate feedback on syntax errors, styling issues or bad practices
  • can detect some code smells

code formatting

  • reformat the source code to align with the style guide
  • there are code formatters for many languages
  • usually triggered by saving the file
  • needs a well configured editor (personal preferences)
  • can help keeping the feedback loop fast
  • decrease cost
  • developers can focus on non-automatable tasks

continuous integration (CI)

Continuous Integration is a software development practice where each member of a team merges their changes into a codebase together with their colleagues changes at least daily.

– Martin Fowler [29]

  • emerged from extreme programming
  • considered an agile approach
  • gives immediate feedback
    • the integration (merging) will fail if two branches are not compatible
    • and build the integrated software
  • also gives opportunity to do testing on the built software…
feature branching

continuous integration environment

  • scheduled build
  • nightly build: scheduled build during night time because for large software a full build (with all tests) could take hours

build script

  • traditionally called build script
  • responsible not only for building the software
  • but also for running tests, generating reports
    • code coverage
  • and even for packaging the software

continuous deployment (CD)

  • “Continuous Deployment means the product is automatically released to production whenever it passes all the automated tests in the deployment pipeline.” – Martin Fowler [29]
  • CD environment extension of a CI environment
    • triggers are the same
    • deployment is another stage in the build script

blue–green deployment [30]

  • two servers are maintained (“blue” and “green”)
    • expensive
  • at a given time, only one server is handling public request
  • the other can be accessed only from a private network
  • changes applied to the non-live server and verified
  • when verified, the non-live server is swapped with the live server

shadow deployment

  • two servers are maintained (“live” and “shadow”)
  • for testing the performance and stability requirements
    • on success, the release can be deployed to the live server as well
  • specialized strategy, complex and (relatively) expensive to set up

canary deployment

  • deployment in an incremental fashion
  • starts with a small number of users
  • and continues until 100% is reached
  • allows to test updates in live environment
    • on small groups of users
    • before deploying to many users
    • may involve telemetry

A/B testing is more of a testing approach than a deployment technique, but it works similarly to canary deployment. It involves reviewing two versions of updates in small set of users to identify which version perform better. [31]

devops

  • software development + IT operations
    • collaboration
  • who is responsible for what?
  • agile mindset, set of principles [32]
    • automation of the SDLC
    • collaboration and communication
    • continuous improvement
    • focus on user needs with short feedback loops
  • relies on automatization, CI and CD
  • to build, test and release better software
    • frequently, reliably, rapidly

further reading: 11 DevOps Principles and Practices to Master: Pro Advice - by Fernando Doglio

automatized review

  • using CI environment
  • do static code analysis
    • analyzing the code without execution
    • searching for syntax errors, styling issues, bad practices or code smells
  • run test suite
  • vulnerability alerts
    • uses package manager’s dependency info to checks for vulnerabilities (CVE) among dependencies
  • generate review report from the findings

should not replace human reviewing

just decrease the work by automatizing trivial tasks

semantic versioning

  • alpha: incomplete feature-wise, external release is uncommon for proprietary software
    • whitebox testing
  • beta: the software is feature-complete but contains several known or unknown bugs
    • blackbox testing
  • rc: release candidate, final touches
    • highest level testing
  1. major version when you make incompatible API changes
    • a way of communicating changes
  2. minor version when you add functionality in a backward compatible manner
  3. patch version when you make backward compatible bug fixes

additional labels for pre-release and build metadata are available as extensions to the major.minor.patch format | from semver.org

calendar versioning

format examples:

  • YYYY.MINOR.PATCH
    • micro is used instead of patch
  • YYYY.MM.MINOR.PATCH

CalVer is a versioning convention based on your project’s release calendar, instead of arbitrary numbers.” | calver.org

interruption

the cost of interruption

  • the greatest “enemy” of a developer is interruption
    • “getting back to the exact state of mind you were at right before an interruption is nearly impossible” [33]
  • according to a study, the average lost time per major interruption is 23 minutes [34]
    • for developers, it could be worse
    • according to another study it is at least 15 minutes [35]
  • define small tasks during the sprint planning to preventing interruption
    • 1–4 hours, but ideally closer to 1
    • a programmer probably get one uninterrupted 2-hour session in a day [35]
© Ash Lamb used with the author’s permission

source: The Cost of Interruption for Software Developers – by Steven To [33]

planned and unplanned interruptions

unplanned

  • someone asks about something or to do something
    • usually a small task
      • informal review, advice, etc.
  • mitigation
    • wear headphones (in open offices)
    • notify in advance

planned

  • meetings, including standup
  • standup is usually the first thing in a workday, not to divide the work time until lunch
  • a wrongly placed meeting can be even worse than an unplanned interruption
    • you have to keep in mind that you have a meeting, cannot start anyting serious
  • mitigation
    • schedule small, easy tasks before meeting

source: The Cost of Interruption for Software Developers – by Steven To [33]

techniques to minimize context switching

  • time blocking
    • divide workday into blocks
  • time batching
    • do similar tasks in a batch
  • prioritize tasks
  • tackle the biggest task first in the morning
  • turn off notifications
  • adopt asynchronous communication
    • e-mail, documentation, ADR
ideal, very bad, much better schedule

references

[1]
tef, “Write code that is easy to delete, not easy to extend.” https://programmingisterrible.com/post/139222674273/write-code-that-is-easy-to-delete-not-easy-to , 13-Feb-2016.
[2]
A. Krysik, “SDLC guide: Requirement analysis in software engineering.” https://stratoflow.com/requirements-analysis , 24-Nov-2023.
[3]
S. Baltes and S. Diehl, “Sketches and diagrams in practice,” in Proceedings of the 22nd ACM SIGSOFT international symposium on foundations of software engineering, 2014, pp. 530–541.
[4]
K. Stemmler, “How to learn software design and architecture.” https://khalilstemmler.com/articles/software-design-architecture/full-stack-software-design , 28-Sep-2019.
[5]
E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design patterns: Elements of reusable object-oriented software. Pearson Education, 1994.
[6]
P. Norvig, “Design patterns in dynamic languages.” http://www.norvig.com/design-patterns/ , 17-Mar-1998.
[7]
S. Wlaschin, “Functional programming design patterns.” https://fsharpforfunandprofit.com/fppatterns/ , Dec-2014.
[8]
Wikipedia contributors, “SOLID — Wikipedia, the free encyclopedia.” https://en.wikipedia.org/w/index.php?title=SOLID&oldid=1237710587, 2024.
[9]
S. Millington, “A solid guide to SOLID principles.” https://www.baeldung.com/solid-principles , 05-Feb-2019.
[10]
S. Oloruntoba and A. S. Walia, “SOLID: The first 5 principles of object oriented design.” https://www.digitalocean.com/community/conceptual-articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design , 23-Apr-2024.
[11]
Wikipedia contributors, “Coupling (computer programming) — Wikipedia, the free encyclopedia.” https://en.wikipedia.org/w/index.php?title=Coupling_(computer_programming)&oldid=1245630908, 2024.
[12]
T. Asana, “What is an implementation plan? 6 steps to create one.” https://asana.com/resources/implementation-plan , 06-Jan-2024.
[13]
P. Paquet, “When everyone is responsible, no one is responsible.” https://medium.com/@philippelyp/when-everyone-is-responsible-no-one-is-responsible-73e9a179237f , 07-Oct-2019.
[14]
D. Radigan, “Story points and estimation.” https://www.atlassian.com/agile/project-management/estimation .
[15]
Interaction Design Foundation, “What are prototypes?” https://www.interaction-design.org/literature/topics/prototypes , 17-Oct-2019.
[16]
L. Bruton, “What is wireframing? A complete guide.” https://www.uxdesigninstitute.com/blog/what-is-wireframing/ , 08-Sep-2022.
[17]
R. C. Martin, Clean code: A handbook of agile software craftsmanship. Pearson Education, 2009.
[18]
M. Fowler, “Code smell.” https://martinfowler.com/bliki/CodeSmell.html , 09-Feb-2006.
[19]
Wikipedia contributors, “Software rot — Wikipedia, the free encyclopedia.” https://en.wikipedia.org/w/index.php?title=Software_rot&oldid=1236668404 , 2024.
[20]
H. Femmer, D. M. Fernández, S. Wagner, and S. Eder, “Rapid quality assurance with requirements smells,” Journal of Systems and Software, vol. 123, pp. 190–213, 2017.
[21]
J. Atwood, “Code smells.” https://blog.codinghorror.com/code-smells/ , 18-May-2006.
[22]
K. Forsberg and H. Mooz, “The relationship of system engineering to the project cycle,” Center for Systems Management, vol. 5333, 1991.
[23]
P. Hauer, “Code review guidelines for humans.” https://phauer.com/2018/code-review-guidelines/ , 31-Jul-2018.
[24]
K. Beck, Test driven development: By example. Addison-Wesley Professional, 2002.
[25]
[26]
G. Meszaros, xUnit test patterns: Refactoring test code. Pearson Education, 2007.
[27]
R. C. Martin, “The cycles of TDD.” http://blog.cleancoder.com/uncle-bob/2014/12/17/TheCyclesOfTDD.html , 17-Dec-2014.
[28]
M. Feathers, Working effectively with legacy code. Prentice Hall Professional, 2004.
[29]
M. Fowler, “Continuous integration.” https://martinfowler.com/articles/continuousIntegration.html , 18-Jan-2024.
[30]
Wikipedia contributors, “Blue–green deployment — Wikipedia, the free encyclopedia.” https://en.wikipedia.org/w/index.php?title=Blue%E2%80%93green_deployment&oldid=1249842339, 2024.
[31]
W. Kazim, “What is software deployment? Process and best practices.” https://learn.g2.com/software-deployment , 31-May-2023.
[32]
GitLab, “4 must-know DevOps principles.” https://about.gitlab.com/blog/2022/02/11/4-must-know-devops-principles , 11-Feb-2022.
[33]
S. To, “The cost of interruption for software developers.” https://www.brightdevelopers.com/the-cost-of-interruption-for-software-developers , 03-May-2018.
[34]
G. Mark, D. Gudith, and U. Klocke, “The cost of interrupted work: More speed and stress,” in Proceedings of the SIGCHI conference on human factors in computing systems, 2008, pp. 107–110.
[35]
C. Parnin, “Programmer, interrupted,” in 2013 IEEE symposium on visual languages and human centric computing, 2013, pp. 171–172.
[36]
N. Pande, “The high price of context switching for developers & ways to avoid it.” https://pacohq.com/blog/guide/the-high-price-of-context-switching-for-developers/ , 23-Apr-2021.

  1. Sometimes it can be somewhat formal.↩︎