Software Design Patterns

Florian Rappl, Fakultät für Physik, Universität Regensburg

Software Design Patterns

Introduction to modern software architecture

software architecture

Basics

What is OOP?

  • OOP is a different way of thinking in programming
  • Instead of having only functions that modify data we have objects that carry data
  • These objects also have associated functions (then called methods)
  • Advantage: Clear separation possible
  • Such objects are usually so called instances of classes
  • Objects are described by the data they carry (which are called fields)

OOP Overview

oop.png

Structure Vs Class

  • Creating own data types is mostly based on either structures or classes
  • Structures should be used for immutable, primitive, i.e. small and atomic, types
  • Classes should be seen as complex, i.e. compound, types that are build from other types
  • Some languages impose restrictions and behavior depending on which kind is chosen (mostly managed languages)
  • In this lecture we will exclusively use classes

Features

  • Encapsulation enforces modularity
  • Inheritance creates groups of similar objects and makes classes re-usable
  • Polymorphism lets specializations implement their own behavior
  • Decoupling makes code highly testable, exchangeable and general

OOP languages

  • Simula (1967) initiated the idea
  • OOP became popular with Smalltalk (mostly due to GUI)
  • In the 80s Ada and Prolog followed
  • Also C++ and Objective-C were introduced
  • With Java the ideas of IL, managed code and OOP merged
  • Finally C# took the ideas of Java even further

Language distinctions

  • Some languages are pure: Eiffel, Scala, Smalltalk, Self, ...
  • Others are focused on OOP (they still have procedural elements): Delphi, C++, C#, Java, Python, JavaScript, ...
  • Some are derived from procedural ancestors: Pascal, VB (from Basic), Fortran, Perl, PHP, COBOL, ...
  • There are also object-based languages, i.e. they support data types but not all OO features (like Modula-2)
  • We will focus on C++, C# and Java

Hello World

using System;

public class Program
{
    public static void Main(String[] args)
    {
        Console.WriteLine("Hello, World!");
    }
}
import System;

public class Program {
    public static void main(String[] args) {
        out.println("Hello, World!");
    }
}
#include <iostream>
using namespace std;

class Program {
    public:
    void Hello() {
        cout << "Hello, World!";
   }
};

int main(int argc, char **argv) {
    Program *p = new Program();
    p->Hello();
    delete p;
    return 0;
}

Basics of C#

  • class creates a class
  • static marks methods as being instance independent
  • using imports types from namespaces
  • public sets members as being visible outside of the class
  • private members are accessible from the outside
  • Primitive types like in C (int, char, double, ...)

Basics of Java

  • Overall quite similar to C#
  • Inheritance is done by a keyword (extends) and not an operator (:)
  • Differentiates in inheritance kind by a keyword (implements)
  • Types are imported with the import keyword
  • The protected modifier is like private, but lets derived classes access the members

Basics of C++

  • We have to take care of the memory
  • Classes should always be created with new
  • Accessing member variables of objects is then done by ->, as opposed to the . in other languages
  • Freeing objects can be achieved by calling delete (beware of arrays!)
  • Modifiers do not have to be set explicitly, but for blocks
  • Header files have to be included as well

Constructors

  • These are functions that are called implicitly after allocating memory
  • Special form: No return value and same name as the class
  • They can be used for doing initialization or checking on conditions
  • They could throw exceptions
  • We can specify arguments to impose dependencies
  • Constructors also have a modifier, i.e. they could be restricted to be accessed from derived class constructors or only within the same class
  • This can result in a very handy pattern: the so called Singleton pattern

Polymorphism

  • Classes allow us to implement a method and re-implement the same method in a derived class
  • This feature is called polymorphism
  • The idea is that even though one talks to a more general kind of type (not knowing the specialized one) one accesses the special method
  • The method is selected by a method selection algorithm
  • This is either done at compile-time (special overload, C++) or at run-time (virtual method dispatch over a function table)

Polymorphism example

public class Shape
{
    public virtual void Draw()
    {
        Console.WriteLine("Base draw");
    }
}
class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a circle");
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a rectangle");
    }
}
public class Shape {
    public void draw() {
        System.out.println("Base draw");
    }
}
class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}
class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle");
    }
}
class Shape {
    public:
    virtual void Draw() {
        cout << "Base draw";
    }
};
class Circle : public Shape {
    public:
    void Draw() {
        cout << "Drawing a circle";
    }
};
class Rectangle : public Shape {
    public:
    void Draw() {
        cout << "Drawing a rectangle";
    }
};

Language implementation

  • In Java every method is virtual, except those which are marked final (cannot be overridden or hidden)
  • C++ does not require placing an override keyword
  • The @Override annotation in Java prevents typing mistakes (it is not required, but strongly recommended)
  • In C# the override is required, even though the method has been marked as virtual

Abstract

  • Previously we have seen a way to re-implement methods
  • Additionally we can enforce implementation
  • An abstract method is such a method that is required to be re-implemented
  • Abstract classes are classes that can never be instantiated
  • These two concepts build the foundation of many patterns

Abstract example

public abstract class Ball
{
    public abstract int Hit(int speed);
}
public class BaseBall : Ball
{
    public override int Hit(int batSpeed)
    {
        //Implementation
    }
}
public abstract class Ball {
    public abstract int hit(int speed);
}
public class BaseBall extends Ball {
    @Override
    public int hit(int batSpeed) {
        //Implementation
    }
}
class Ball {
    public:
    virtual int Hit(int speed) = 0;
};
class BaseBall : public Ball {
    public:
    int Hit(int batSpeed) {
        //Implementation
    }
};

Abstract usage

  • C++ does not have special keywords
  • Any class having abstract methods is abstract
  • Abstract classes have to be marked as such in C# or Java
  • It is not possible to create instances of abstract classes
  • Abstract classes are useful to group something which has at least one method, which requires different implementation

Interfaces

  • A step further than abstract classes are interfaces
  • An interface is like an abstract class without any code
  • It could be seen as a contract (sets up what kind of methods should be available)
  • In modern software development interfaces are crucial
  • Goal: Reduce dependencies and decouple classes

Interfaces in practice

interface IShooter
{
    int Ammo { get; set; }
    void ShootAt(int x, int y);
}
class Player : IShooter
{
    /* Implementations */
}
interface Shooter {
    void setAmmo(int value);
    int getAmmo();
    void shootAt(int x, int y);
}
class Player implements Shooter {
    /* Implementations */
}
class Shooter {
    public:
    virtual void SetAmmo(int value) = 0;
    virtual int GetAmmo() = 0;
    virtual void ShootAt(int x, int y) = 0;
}
class Player : public Shooter {
    /* Implementations */
}

Worth noting ...

  • C# offers special constructs called properties (otherwise we prefer to use the so-called bean convention)
  • In C++ interface-like types can be created by abstract classes that contain only abstract methods marked as public
  • Java requires a different keyword for implementing interfaces (however, for us this is educational)
  • In C# and Java methods in interfaces have implicitly a public modifier

Comparison

C#JavaC++
Managed Managed Native
Pointers possible No pointers Pointers required
High OO High OO Low OO
With Mono Cross platform With Qt
C# 5 Java 7 C++11
Lambdas Proxy Lambdas
Events Custom Custom

The diamond problem

  • C++ allows multiple inheritance, plus merging again
  • Here we can build a diamond structure with a base class A, two subclasses B and C and a class D, that inherits from B and C
  • Problem: We now have the methods have A duplicated
  • Also the data of A is duplicated
  • Solution: Instead of doing a normal inheritance, do a virtual one

Diamond hierarchy

A <|-- B
A <|-- C
B <|-- D
C <|-- D

A look at the creators

C#


Hejlsberg

Java


Gosling

C++


Stroustrup

Other languages

  • Objective-C is an OO language that is empowering iOS and OSX applications
  • Vala is using a lot of C# and D concepts to create native code
  • Eiffel is build upon design by contract and is enforces OO principles
  • JavaScript is a fully OO scripting languages, however, it is prototype-based and not class-based
  • Visual Basic is a popular extension of Basic with OO in mind
  • Functional OO languages like F#, Scala and others mix concepts

Design patterns

  • A general reusable solution to a commonly occurring problem
  • The context for the problem (and solution) is software
  • Since it is a pattern it can be transformed to apply to our problem
  • They usually follow best practices, even though the implementation might not
  • Languages might enhance using these patterns
  • Sometimes languages already provide integrations, which should be preferred

Literature

  • Drayton, Peter; Albahari, Ben; Neward, Ted (2002). C# Language Pocket Reference.
  • Gosling, James; Joy, Bill; Steele, Guy L., Jr.; Bracha, Gilad (2005). The Java Language Specification.
  • Alexandrescu, Andrei; Sutter, Herb (2004). C++ Design and Coding Standards: Rules and Guidelines for Writing Programs.
  • Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1995). Design Patterns: Elements of Reusable Object Oriented Software.