diff --git a/lectures/week7.html b/lectures/week7.html index 902bdf6..8cf7c96 100644 --- a/lectures/week7.html +++ b/lectures/week7.html @@ -1,1792 +1,1924 @@ talk slides

Design patterns

Why do we need them ?

Design Patterns: Elements of Reusable Object-Oriented Software by E. Gamma, R. Helm, R. Johnson and J. Vlissides (the gang of four)

  • Designing object oriented code is hard
  • designing reusable object-oriented software is even harder!

Code Design $=$ decomposition into objects


  • Some objects have real world counterparts (e.g. objects of type planet)
  • others don't (e.g. array, matrices, streams).

Design requirements

  • Solution specific to a problem
  • General enough to address future problems
  • Performance Issues
  • Avoid/Minimize re-design
  • Vocabulary for design ideas
  • Minimize costs (development time)

Reuse solutions

  • Object-oriented organisation repeat patterns

The design patterns

  • Knowing the patterns $\Rightarrow$ quick application to your problems
  • Help to produce more reusable systems
  • Design patterns names $\Rightarrow$ vocabulary for team work
Motto: Designing for change

Design patterns: What they are

Design patterns have four essential elements:

  • Pattern name: associates problem with solutions&consequences
    $\Rightarrow$ Improves communication and documentation

  • Problem: Scenario/conditions of when to apply a pattern

  • Solution: Description of the arrangement of classes and objects

  • Consequences: Results and trade-offs. (allows to know design alternatives)

Remarks

  • The appropriate design pattern depends on the programming language.
  • Several design patterns are often combined together

Design patterns pros&cons

  • Pros:
    • consider/evaluate different design solutions
    • easier understanding of existing code (matching patterns)
    • easier start of a project (using general design patterns)


  • Cons:
    • Strictly applying design patterns reduces creativity
    • Standard solutions may not be applied (scientific programming is complex)
      • New cases = new (more complex) solutions
      • In high performance computing: optimization is a strong constraint
Design patterns

A useful source of inspiration
but no bible!

Design patterns examples

Iterator

  • General description: Gives access to elements of a container without exposing its internal representation

  • Our problem (Particles):

    • Particles stored in an container
    • Perform computations/IOs on the particles
    • Traverse the container in different(random) ways
    • Access elements without knowing the internal structure of the container (list, vector, set, ...)
struct List {
   using Element = Planet;
 
   // define a sub type
   struct ListIterator;
 
   int size();
   ListIterator begin();
   ListIterator end();
 };
 
 struct List::ListIterator {
   Element &operator*();
   void operator++();
   bool operator!=(ListIterator &e);
 };
 
struct List {
   struct ListIterator;
 
   int size();
   void add(Element e) { container.push_back(e); };
 
   ListIterator begin();
   ListIterator end();
 
 private:
   std::vector<Element> container;
 };
 
 struct List::ListIterator {
 
   ListIterator(Element &current) { this->ptr = &current; }
   Element &operator*() { return *this->ptr; };
   void operator++() { ++this->ptr; };
   bool operator!=(ListIterator e) { return e.ptr != this->ptr; };
 
 private:
   Element *ptr;
 };
 
 List::ListIterator List::begin() { return ListIterator(this->container[0]); };
 List::ListIterator List::end() {
   return ListIterator(this->container[this->size()]);
 };
 
 int main() {
   int p1 = 1;
 
   List list;
 
   for (auto &&v : list) {
     std::cout << v << std::endl;
   }
 }
 
  • Consequences:
    • Standardize container's interface
    • Can vary how to traverse a container (different iterator types)
    • Concurrent traversal of a container (double loop)
  List list;
 
   for (auto &&v : list) {
     std::cout << v << std::endl;
   }
 

Singleton

  • General description: Ensure that a class has only one instance, and provides a global point of access

  • Our problem (Particles):

    • Only one container of particles
    • Uniqueness enforced by the container himself
    • Access the container of particles from everywhere (global)
    • Contain planets or ping-pong balls (polymorphic)

class Singleton {
 
 private:
   Singleton();
 
   friend Singleton &get();
 };
 

Singleton *unique_instance = nullptr; // no encapsulation
 
 Singleton &get() { // not part of Singleton::
   if (unique_instance == nullptr)
     unique_instance = new Singleton();
 
   return *unique_instance;
 }
 

Static members and static members (C++)

  • static variable/member is a unique and permanent variable
class A {
 public:
   static int a;
 };
 
 int A::a = 1;
 
  • what happens when we do this ? and why ?
  A a1;
   A a2;
 
   a1.a = 2; // also modifies a2.a
 
  • static method applies with no instance
class B {
 
 public:
   static int foo();
 };
 
  // do not need an instance to be called
   B::foo();
 

Static members and static members (python)

class A:
     # in the scope of the class
     a = 1
 
     def __init__(self):
         pass
 
 
 a1 = A()
 a2 = A()
 
 a1.a = 2 # also modifies a2.a
 
  • static method applies with no instance
class B :
 
     @staticmethod
     def foo(cls):
         print(cls)
 
 
 # do not need an instance to be called
 B.foo()
 

Singleton generic solution

  • Consequences:
    • controlled creation of the unique instance
    • Transverse/global access to instance (with class name)
    • Polymorphic behavior
struct Particles {
   static Particles &get();
 
 private:
   Particles();
   static Particles obj;
 };
 
 struct Planets : public Particles {
   static Particles &get();
 };
 
  Particles &obj = Planets::get();    // creation
   Particles &obj2 = Particles::get(); // access
 

Abstract Factory

  • General description: Provides an interface for creating dependent/coherent objects without specifying their concrete classes.

  • Our problem (Particles)

    • Particles code working for various particle types
    • A run deals with a single particle type
    • Other objects (IO, Compute) must be matching the (unique) particle type
    • "Automatic" creation of all the objects
  • Abstract Factory
    • The system is independent of how the objects are created/composed
    • Related objects are designed to be used together: needs to be enforced
    • Objects are polymorphic (manipulated by interface)

Example with Series

  • Consequences:
    • Isolating concrete/daughter classes
    • Creating packages of objects made easy
    • Promotes consistency among objects
    • Supporting new kinds of objects is difficult (modify the creation routines)
+
+
+
+
+ +
+

Generic description of particles code

+
+
+ +
+
    +
  • Scientific question: the trajectory of a set of particles.
  • +
  • The different particles we want to be able to use are: Solar system planets, ping pong balls, nodes in a grid
  • +
+ +
+
+ +
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
    +
  • The motion of the particles is made with the Newmark/Velocity Verlet explicit integration scheme:

    +
      +
    • $v_i = v_i + \frac{\Delta t}{2} a_i$
    • +
    • $p_i = p_i + \Delta t v_i$
    • +
    • Compute the forces $f_i$
    • +
    • $a_i = \frac{1}{m_i} f_i$
    • +
    • $v_i = v_i + \frac{\Delta t}{2} a_i$
    • +
    +

    $\forall$ particle $i$ with $v_i$ its velocity, $p_i$ its position, $f_i$ the force applying and $a_i$ its acceleration

    +
  • +
+ +
+
+
+
+ +
+
    +
  • Flow of the code
  • +
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
+ +
+

Different models

    +
  • in the particle's interaction forces:

    +
      +
    • Gravitational force: $\mathbf{f}_i = \sum_{j \neq i} \frac{\mathcal{G}}{r_{ij}^2}\mathbf{d}_{ij}$
    • +
    • Contact/interpenetration forces: $\mathbf{f}_i = \epsilon \sum_{j \neq i} \mathcal{C} \left( R_i + R_j - r_{ij} \right) \mathbf{d}_{ij}$
    • +
    • Spring: $\mathbf{f}_i = \sum_{j \neq i} K \left( r_{ij}^0 - r_{ij} \right) \mathbf{d}_{ij}$
    • +
    +

    with $\mathbf{r}_{ij} = p_j - p_i$, $\mathbf{d}_{ij} = \frac{\mathbf{r}_{ij}}{r_{ij}}$, $R_i$ the radius and $K$ a spring stiffness.

    +
  • +
  • in their unit system: astronomical units (AU), SI units...

    +
  • +
  • in data: Some have radius/name, some dissipate energy, all have a mass, etc...
  • +
+ +
+
+
+
+ +
+

Code design

    +
  • A single code $\Rightarrow$ Class hierarchy
  • +
  • Containers for the particles
  • +
  • Produce files for various formats
  • +
  • Read initial system state from a restart file
  • +
  • Vectorial/Matricial functions and operators (for convenience)
  • +
+ +
+
+
+
+ +
+

Interactive session on class diagram

Generating the class diagram of the particle code.
Let's do that together !

+ +
+
+ +
+

Family class for particles

    +
  • capable of representing, planets, ping-pong balls.
  • +
  • we want vector algebra
  • +
+ +
+
+ +
+

Other families

    +
  • IO family
  • +
  • Compute family
  • +
  • Factory family
  • +
+