Software Frameworks

Agenda

  • Introduction.

  • Properties

  • Design Principles

  • A toy example

  • Correlated concepts

  • Real-world examples

  • Conclusion

Introduction

Definition

A software framework is a reusable, "semi-complete" application that can be specialized to produce custom applications.
— Johnson and Foote 1988]

In Short, a Framework is

  • A set of classes, abstract classes and interfaces.

  • A set of behaviors, spread over these classes.

  • An incomplete application for a family of products.

  • A set of hooks, where subclasses can insert their specialized behavior.

  • The expectations placed upon the subclasses.

  • A logic decomposition of a problem.

  • Represented by its source code.

Creating Real-World Applications by

  • Modifying working examples.

  • Creating subclasses.

  • Configuring objects.

  • Writing configuration files.

  • Writing programs/scripts for a domain-specific language.

  • Modifying a model@run.time.

Framework Goals

  • Reuse: code, design, domain analysis, and documentation.

  • Simplify software development.

  • Reduce code writing.

  • Allow inexperienced designers and programmers to develop good software.

  • Extract the knowledge of experimented designers and programmers.

Properties

Basic Properties

  1. Modularity

  2. Reusability

  3. Extensibility

  4. Inversion of control

  5. Dependency inversion

  6. Open-Closed

Modularity

  • Abstract classes have a stable interface that encapsulates volatile implementation details.

  • They provide hotspots or "points of planned variability", where the behavior can be extended.

  • Design and implementation changes are limited to these points, reducing the effort to understand and maintain the software.

Reusability

  • The stable interfaces define generic components that can be extended to create new applications.

  • Reuse of framework components improves developer productivity, as well as software performance, reliability, and interoperability.

Extensibility

  • A framework enhances extensibility by providing explicit hook methods for planned variability.

  • Extensibility is essential to ensure rapid customization of new application features.

Inversion of Control

  • In a framework, the flow of control is not dictated by the callers, but by the framework itself (the abstract classes).

  • The inversion of control enables canonical application processing steps to be customized by hotspots.

The Hollywood Principle

The Inversion of Control is also called "The Hollywood Principle"

 — Don’t call us, we’ll call you!
— Richard E. Sweet 1985

The framework code calls the customized/specific code, not the opposite.

Dependency Inversion

High-level modules should not depend upon low-level modules. Both should depend upon abstractions.

Abstractions should not depend upon details. Details should depend upon abstractions

The Dependency Inversion Principle
— Robert (Uncle Bob) Martin

Open-Closed Principle

  • The framework is open for extension and closed for modifications

The source code is supposed to be extended, not modified.

Design Principles

Principles

  1. Template Method Pattern

  2. Annotations

  3. Dependency Injection

Template Method Pattern

Hook and Template Methods
  • Hook and template methods are the building blocks of software frameworks.

  • They allow the implementation of commonality and variability.

Template Method

  • A template method defines the skeleton of an algorithm, deferring some steps to subclasses.

  • Subclasses can redefine some steps without changing the algorithm’s structure.

Template Method Example

public void openDocument(String name) {
    if (!canOpenDocument(name)) {
      // cannot handle this document
    return;
    }

    Document doc = doCreateDocument();
    if (doc != null) {
      docs.add(doc);
      aboutToOpenDocument(doc);
      doc.open();
      doc.doRead();
    }
}
pattern template

Template Method Behavior

A template method usually calls the following kinds of operations:
  • concrete Client operations.

  • concrete AbstractClass operations (i.e., operations that are generally useful to subclasses).

  • concrete operations..

  • abstract operations.

  • factory methods (see Factory Method Pattern).

  • hook operations, which provide default behavior that subclasses can extend if necessary. A hook operation often does nothing by default.

Hook Methods

  • A hook method represents a point of variability by providing the calling interface to a variable behavior.

  • Each implementation of a hook method provides a variant of that behavior.

Annotations

  • An annotation[1] is a technique to provide meta-data on a programming element: classes, methods, fields, etc.

  • The meta-data can be used to add additional behavior to the programming element.

Spring Annotation Example
@Component
public class ChatModule {
    @Autowired
    public ChatModule(SocketIOServer server) {}
}
1. "Attribute" in C# or "Decorator" in Python

Annotations in JUnit

JUnit 3 test cases are all methods from subclasses of `TestCase` starting with "test"
Figure 1. JUnit 3 test cases are all methods from subclasses of TestCase starting with "test"
JUnit 4 test cases are all methods decorated with `@Test`
Figure 2. JUnit 4 test cases are all methods decorated with @Test

Dependency Injection

Dependency Injection is a set of software design principles and patterns that enable us to develop loosely coupled code
«Dependecy Injection: Principles, Practices, and Patterns»
— Mark Seemann and Steven von Deursen

Dependency Injection and the Dependency Injection Principle

  • Dependency Injection helps developers to respect the Dependency Inversion Principle

  • It allows the choice of concrete classes to be made at run-time, rather than at compile time

The Dependency Problem

  • The Risk Server should only depend on the Board Repository

  • However, Risk Server must instantiate the class Hibernate Board Repository, creating a dependency to a concrete class.

The RiskServer class must instantiate a concrete class, breaking the DIP
Figure 3. The RiskServer class must instantiate a concrete class, breaking the DIP

The Injector to the Rescue

Diagram

The Injector Class

Responsibilities
  1. Find all the dependencies for Risk Server

  2. Find all implementation of Board Repository

  3. Instantiate Hibernate Board Repository and assign the instance to Risk Server

Diagram

It’s a Kind of Magic!

The Magic
  1. Use reflection to find fields with a specific decorator (e.g. @Inject) and get its type

  2. Use reflection to find an implementation of the previous type

  3. Instantiate the type and use reflection (again!) to assign the new instance to the field

A Toy Example[Greg Butler]

Domain

Bouncing-Bumping Games

bumpers domain

Class Diagram

bumpers framework

Template Methods

Game::makeWorld() {
	makeBouncer();
	makeControllers();
	makeObstacles();
	makeEventHandlerTable();
}
Game::run(){
	loop over event e in eventQueue {
		ehTable[e]-> handleEvent(e);
		refreshDisplay(); }
}

Correlated Concepts

Frameworks and Libraries

Library use case:
  • The developer designs the application, decomposes the problem and specifies the flow of control.

  • The application calls the library.

Frameworks and Libraries

Framework use case:
  • The developer extends the framework. The framework defines the flow of control and design decomposition.

  • The framework call the extension code.

Frameworks and Patterns

Design Patterns:
  • describe micro-architectures

  • are abstract

Software Frameworks:
  • have concrete architecture and code.

  • incorporate design patterns, often to provide extension points (variability).

  • are a rich field for design pattern mining.

Frameworks and Software Architectures

Software architectures:
  • describe abstract macro-architectures.

  • target whole systems, but can be used for a product line and single applications.

  • are design artifacts.

  • are designed to ensure software quality.

  • describe the guiding principles behind a given application.

Frameworks and Software Architectures

Software Frameworks:
  • are concrete implementation of abstract architectures.

  • are designed to be specialized/customized.

  • focus on reusability.

Real-World Examples

Application Frameworks

Implement the standard structure of an application.
  • Smalltalk MVC (Model View Controller). 1980

  • Microsoft Windows Presentation Foundation (WPF). 2006. Language: C#

  • macOS Cocoa AppKit. 1996. Languages: Objective C, Swift,

Technology Frameworks

  • Provide a standard and generic software foundation.

  • Examples: COM, CORBA, Java J2EE, ACE (Adaptive Communication Environment, Doug Schmidt et al).

Business Frameworks

Domain-specific, business solution that can be extended into an organization.
  • Baan: Enterprise Resource Planning (ERP) software written in Java.

  • San Francisco Business Objects (Taligent/IBM).

  • The Oracle Enterprise Architecture Framework.

Web Application Frameworks

Designed to support the development of dynamic websites, web applications, web services and web resources.
  • Zope (Zope Corporation) — Python.

  • Apache Struts — Java.

  • Django, Ruby on Rails, Symfony, Yii, Spring MVC, Stripes, Play, CodeIgniter, etc.

  • Angular, ViewJS, ReactJS

Conclusion

Framework Main Characteristics

  • Hotspots: planned extension points.

  • Inversion of control: the framework controls the application and not the opposite.

Main Issues

  • Learning curve.

  • Important initial investment.

  • Framework developers must be domain experts.

  • Framework evolution is complex.

Framework Benefits

  • Code and design reuse.

  • Perspective shift: programmers are forced to write reusable software.

  • Improvement of software quality and developer productivity.

References

  • M.E. Fayad, D.C. Schmidt, R.E. Johnson, “Building Application Frameworks”, Addison-Wesley, 1999.

  • Object Oriented Frameworks. Greg Butler. Ecoop 2001 Workshops.