ECE 449 OOP and Computer Simulation Lecture 11 Design Patterns

Similar documents
ECE 449 OOP and Computer Simulation Lecture 07 Class Design for Circuit Netlist

Laboratorio di Progettazione di Sistemi Software Design Pattern Creazionali. Valentina Presutti (A-L) Riccardo Solmi (M-Z)

Software Design COSC 4353/6353 D R. R A J S I N G H

ECE 449 OOP and Computer Simulation Lecture 14 Final Exam Review

Creational Patterns. Factory Method (FM) Abstract Factory (AF) Singleton (SI) Prototype (PR) Builder (BU)

ECE 449 OOP and Computer Simulation Lecture 12 Resource Management II

Design Pattern- Creational pattern 2015

Design Patterns. Manuel Mastrofini. Systems Engineering and Web Services. University of Rome Tor Vergata June 2011

ECE 449 OOP and Computer Simulation Lecture 09 Logic Simulation

Think of drawing/diagramming editors. ECE450 Software Engineering II. The problem. The Composite pattern

Object-Oriented Design

Modellistica Medica. Maria Grazia Pia, INFN Genova. Scuola di Specializzazione in Fisica Sanitaria Genova Anno Accademico

Topics in Object-Oriented Design Patterns

An Introduction to Patterns

What are the characteristics of Object Oriented programming language?

C++ Important Questions with Answers

CSCI 253. Overview. The Elements of a Design Pattern. George Blankenship 1. Object Oriented Design: Creational Patterns. George Blankenship

Singleton Pattern Creational

Creational Design Patterns

Object Oriented Programming. Solved MCQs - Part 2

Design Patterns Reid Holmes

Short Notes of CS201

Design Patterns. Comp2110 Software Design. Department of Computer Science Australian National University. Second Semester

Chapter 1: Object-Oriented Programming Using C++

4.1 Introduction Programming preliminaries Constructors Destructors An example... 3

CS201 - Introduction to Programming Glossary By

Singleton, Factory Method, Abstract Factory, Named Constructor. Using one or more base classes to hide details from the client

The Strategy Pattern Design Principle: Design Principle: Design Principle:

Design Pattern: Composite

Supporting Class / C++ Lecture Notes

COSC 3351 Software Design. Design Patterns Structural Patterns (I)

OBJECT ORIENTED PROGRAMMING USING C++ CSCI Object Oriented Analysis and Design By Manali Torpe

THOMAS LATOZA SWE 621 FALL 2018 DESIGN PATTERNS

Lecture 3. COMP1006/1406 (the Java course) Summer M. Jason Hinek Carleton University

Intro to OOP Visibility/protection levels and constructors Friend, convert constructor, destructor Operator overloading a<=b a.

ECE 449 OOP and Computer Simulation Lecture 08 Resource Management I

CHAPTER 6: CREATIONAL DESIGN PATTERNS

GoF Design Pattern Categories

ECE 3574: Dynamic Polymorphism using Inheritance

OOPS Viva Questions. Object is termed as an instance of a class, and it has its own state, behavior and identity.

Object-Oriented Oriented Programming

Keywords: Abstract Factory, Singleton, Factory Method, Prototype, Builder, Composite, Flyweight, Decorator.

Java Object Oriented Design. CSC207 Fall 2014

Tecniche di Progettazione: Design Patterns

SDC Design patterns GoF

Chapter 6. Object- Oriented Programming Part II

Object-Oriented Oriented Programming Factory Method Pattern Abstract Factory Pattern. CSIE Department, NTUT Woei-Kae Chen

Design of Software Systems (Ontwerp van SoftwareSystemen) Design Patterns Reference. Roel Wuyts

Zhifu Pei CSCI5448 Spring 2011 Prof. Kenneth M. Anderson

Common Misunderstandings from Exam 1 Material

OOPs Concepts. 1. Data Hiding 2. Encapsulation 3. Abstraction 4. Is-A Relationship 5. Method Signature 6. Polymorphism 7. Constructors 8.

What is Design Patterns?

Introduction to C++ Introduction to C++ Dr Alex Martin 2013 Slide 1

Object oriented programming. Encapsulation. Polymorphism. Inheritance OOP

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language

A Reconnaissance on Design Patterns

What is Design Patterns?

The GoF Design Patterns Reference

Instantiation of Template class

G Programming Languages - Fall 2012

Fast Introduction to Object Oriented Programming and C++

Singleton Pattern Creational. » Ensure a class has only one instance» Provide a global point of access

FINAL TERM EXAMINATION SPRING 2010 CS304- OBJECT ORIENTED PROGRAMMING

Information systems modelling UML and service description languages

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

C++ Inheritance and Encapsulation

CSE 303: Concepts and Tools for Software Development

M301: Software Systems & their Development. Unit 4: Inheritance, Composition and Polymorphism

Object Oriented Methods with UML. Introduction to Design Patterns- Lecture 8

Computer Systems Assignment 2: Fork and Threads Package

Object-Oriented Programming, Iouliia Skliarova

A few important patterns and their connections

Plan. A few important patterns and their connections. Singleton. Singleton: class diagram. Singleton Factory method Facade

G Programming Languages Spring 2010 Lecture 9. Robert Grimm, New York University

CS61, Fall 2012 Section 2 Notes

Design Pattern. CMPSC 487 Lecture 10 Topics: Design Patterns: Elements of Reusable Object-Oriented Software (Gamma, et al.)

CE221 Programming in C++ Part 1 Introduction

EPL 603 TOPICS IN SOFTWARE ENGINEERING. Lab 6: Design Patterns

3. Task Group & Applying Composite Pattern

Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub

The Lorax Programming Language

CS304 Object Oriented Programming Final Term

Object Oriented Software Design

CS304- Object Oriented Programming LATEST SOLVED MCQS FROM FINALTERM PAPERS. MC

Object Oriented Software Design II

Object-Oriented Concepts and Design Principles

QUIZ. How could we disable the automatic creation of copyconstructors

Produced by. Design Patterns. MSc in Communications Software. Eamonn de Leastar

Financial computing with C++

Lecture 20: Design Patterns II

What is Design Patterns?

CS250 Final Review Questions

Software Design Patterns. Background 1. Background 2. Jonathan I. Maletic, Ph.D.

COMP6771 Advanced C++ Programming

Factory Method. Comp435 Object-Oriented Design. Factory Method. Factory Method. Factory Method. Factory Method. Computer Science PSU HBG.

Design patterns. OOD Lecture 6

Tecniche di Progettazione: Design Patterns

September 10,

Modellistica Medica. Maria Grazia Pia, INFN Genova. Scuola di Specializzazione in Fisica Sanitaria Genova Anno Accademico

Programming, numerics and optimization

Transcription:

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 1/60 ECE 449 OOP and Computer Simulation Lecture 11 Design Patterns Professor Jia Wang Department of Electrical and Computer Engineering Illinois Institute of Technology November 3, 2017

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 2/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 3/60 Reading Assignment This lecture: None Next lecture: 14

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 4/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 5/60 The Design Problem bool netlist::create(const evl_wires &wires, const evl_components &comps ); bool netlist::create_nets(const evl_wires &wires); bool netlist::create_gates(const evl_components &comps ); bool netlist::create_gate(const evl_component &c ); bool gate::create(const evl_component &c ); bool gate::create_pin(const evl_pin &p ); bool pin::create( const evl_pin &p ); There are two groups of objects participating in the creation of the netlist. The specification of the netlist: evl_xxxx The netlist data structure: netlist/gate/pin The creation of the netlist is closely coupled to EasyVL. What if we need to change either group of the objects? To adopt a new data structure? To support a new hardware description language? Can we design the classes in a way so the other group can remain unchanged?

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 6/60 The Builder Pattern A creational pattern Separate the construction of a complex object (the EasyVL specification) from its representation (the netlist data structure) Builder: an abstract interface for creating the complex object from its parts Director: construct the complex object using the Builder interface

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 7/60 The Builder Interface struct netlist_builder_i { virtual void add_net(std::string name) = 0; // return the ID# of the gate virtual size_t add_gate(std::string type, std::string name) = 0; // create a pin and append it to a gate virtual void gate_append_pin(size_t gate_id, std::string bus_name, int lsb, int msb) = 0; ; // struct netlist_builder_i Assume errors are handled through exceptions. An abstract interface without any implementation Define steps to construct the complex object from its parts independent of the specification How the complex object is constructed, is not specified. Even the classes for the complex object and the parts are not defined leaving great flexibility. In other words, only the responsibility itself is specified.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 7/60 The Builder Interface struct netlist_builder_i { virtual void add_net(std::string name) = 0; // return the ID# of the gate virtual size_t add_gate(std::string type, std::string name) = 0; // create a pin and append it to a gate virtual void gate_append_pin(size_t gate_id, std::string bus_name, int lsb, int msb) = 0; ; // struct netlist_builder_i Assume errors are handled through exceptions. An abstract interface without any implementation Define steps to construct the complex object from its parts independent of the specification How the complex object is constructed, is not specified. Even the classes for the complex object and the parts are not defined leaving great flexibility. In other words, only the responsibility itself is specified.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 7/60 The Builder Interface struct netlist_builder_i { virtual void add_net(std::string name) = 0; // return the ID# of the gate virtual size_t add_gate(std::string type, std::string name) = 0; // create a pin and append it to a gate virtual void gate_append_pin(size_t gate_id, std::string bus_name, int lsb, int msb) = 0; ; // struct netlist_builder_i Assume errors are handled through exceptions. An abstract interface without any implementation Define steps to construct the complex object from its parts independent of the specification How the complex object is constructed, is not specified. Even the classes for the complex object and the parts are not defined leaving great flexibility. In other words, only the responsibility itself is specified.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 7/60 The Builder Interface struct netlist_builder_i { virtual void add_net(std::string name) = 0; // return the ID# of the gate virtual size_t add_gate(std::string type, std::string name) = 0; // create a pin and append it to a gate virtual void gate_append_pin(size_t gate_id, std::string bus_name, int lsb, int msb) = 0; ; // struct netlist_builder_i Assume errors are handled through exceptions. An abstract interface without any implementation Define steps to construct the complex object from its parts independent of the specification How the complex object is constructed, is not specified. Even the classes for the complex object and the parts are not defined leaving great flexibility. In other words, only the responsibility itself is specified.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 8/60 The Director Implementation void evl_director(netlist_builder_i *builder, const evl_wires &wires, const evl_components &comps) { for each wire w in wires { for each net w[i] in w { builder->add_net(w[i]); create wires_table for each component c in comps { id = builder->add_gate(c.type, c.name); for each pin p in c.pins { resolve semantics of p using wires_table builder->gate_append_pin(id, p.name, p.lsb, p.msb); The director follows the specification to build the complex object through the builder interface. Without any knowledge of the complex object Program for the interface but not the implementation This is the first time we specify an interface without provide any implementation, while still being able to write a program.

Implement a Builder class netlist_builder : public netlist_builder_i { netlist_builder(const netlist_builder &); // no copy netlist_builder &operator=(const netlist_builder &); // no assignment netlist &nl_; // the netlist to be built void add_net(std::string name); size_t add_gate(std::string type, std::string name); void gate_append_pin(size_t gate_id, std::string bus_name, int lsb, int msb); public: netlist_builder(netlist &nl) : nl_(nl) { bool finalize_creation(); ; // class netlist_builder To implement the builder, we need to implement the pure virtual functions in a derived class and prepare classes for the complex object and its parts. Assume netlist_builder is friend of netlist, gate, etc., and thus can access their private members. Additional creation steps can be handled by finalize_creation. ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 9/60

Implement netlist builder void netlist_builder::add_net(std::string name) { assert(nl_.nets_table_.find(name) == nl_.nets_table_.end()); // append net and update nets_table size_t netlist_builder::add_gate(std::string type, std::string name) { if (type == "evl_dff") { nl_.gates_.push_back(new flip_flop(name)); else if (type == "and") { nl_.gates_.push_back(new and_gate(name)); return nl_.gates_.size()-1; void netlist_builder::gate_append_pin(int gate_id ) { assert(gate_id < nl_.gates_.size()); // append pin to gates_[gate_id] and make connections to nets bool netlist_builder::finalize_creation() { for each gate g in nl_.gates_ { if (!g.validate_structural_semantics()) return false; return true; ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 10/60

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 11/60 Put Everything Together int main(int argc, char *argv[]) { // validate arguments evl_wires wires; evl_components comps; parse_evl_file(argv[1], wires, comps); netlist nl; netlist_builder builder(nl); evl_director(&builder, wires, comps); builder.finalize_creation(); std::string nl_file = std::string(argv[1])+".netlist"; nl.save(nl_file); // save the netlist for Project 3 nl.simulate(1000); // simulate 1000 cycles for Project 4 return 0;

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 12/60 Summary of Participants of the Builder Pattern Builder (netlist_builder_i) Specifies an abstract interface for creating a complex object from its parts ConcreteBuilder (netlist_builder) Constructs and assembles parts of the product object by implementing the Builder interface Provides means for retrieving the product object and/or finalizing the creation Director (evl_director) Constructs a complex object using the Builder interface Can be a class to handle more complicated creation process Product (netlist, gate, etc.) Represent the complex object under construction Details are revealed to and only to ConcreteBuilder for creation.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 13/60 Benefits of the Builder Pattern It lets you vary a product s internal representation. The internal representation of the product, i.e. the product types, together with the method to assemble it, is hidden from the director. All you have to do to change the product s internal representation is to define a new kind of ConcreteBuilder. It isolates code for construction and representation. Code for creation from the specification is centralized in Director. Product types are no longer responsible for creation it s now the responsibility of ConcreteBuilder. Director and ConcreteBuilder can change independently. It gives you finer control over the construction process. The product is constructed step by step under the director s control.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 14/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 15/60 The Design Problem size_t netlist_builder::add_gate(std::string type, std::string name) { if (type == "evl_dff") { nl_.gates_.push_back(new flip_flop(name)); else if (type == "and") { nl_.gates_.push_back(new and_gate(name)); return nl_.gates_.size()-1; You have to modify this function for any new type of gates. netlist_builder knows too much about the gate implementations. What if you want your simulator to support other types of gates provided by a third-party at runtime? We need to create an object whose type is only known at runtime (as a string).

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 16/60 The Prototype Pattern A creational pattern Specify the kinds of objects (gate implementations) to create using a prototypical instance, and create new objects by copying this prototype Prototype: declare the interface for cloning itself Client: create objects by cloning the prototype

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 17/60 The Prototype Interface class gate { virtual gate *clone(std::string name) = 0; ; // class gate Since all gate implementations are derived from gate, it works as a common interface of the prototypes. The clone function is supposed to return a clone of the prototype. Let keep it private since only netlist_builder should be able to access it. Conceptually, the clone function should call the copy ctor when constructing the new object. However, for classes derived from gate, we choose to construct a gate without pins given its name, since the pins are handled by the Builder pattern.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 18/60 Implement a Prototype class flip_flip: public gate { gate *clone(std::string name) { return new flip_flop(name); ; // class flip_flop For this example, we can call the ctor to clone the object. In some sense, the prototype only provides the type information.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 19/60 Covariant Return Types class flip_flip: public gate { flip_flop *clone(std::string name) { return new flip_flop(name); ; // class flip_flop It is much more intuitive to let flip_flop::clone to return a flip_flop pointer. C++ allows unmatched function return types for virtual functions as long as they are covariant. The base pointer (or reference) as the function return type in the base class can be changed to the derived pointer (or reference) in the derived class.

Prototype Storage typedef std::map<std::string, gate *> gate_prototypes; class flip_flip: public gate { public: static void store_prototype(gate_prototypes &gps) { assert(gps.find("evl_dff") == gps.end()); gps["evl_dff"] = new flip_flop("prototype"); ; // class flip_flop We can store the prototypes in a container. Since we may need to search for a specific prototype by name, an associative container is necessary. By asking each prototype to register for itself, they can have all their ctors and dtors to be private perfect for hiding implementation details. The prototype won t be deleted, but that s not a concern. It should persist throughout the program execution, and the OS will reclaim the heap memory any way at the end. ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 20/60

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 21/60 The Client class netlist_builder : public netlist_builder_i { gate_prototypes &gps_; public: netlist_builder(netlist &nl, gate_prototypes &gps) : nl_(nl), gps_(gps) { ; // class netlist_builder size_t netlist_builder::add_gate(std::string type, std::string name) { if (gps_.find(type) == gps_.end()) ; // handling errors nl_.gates_.push_back(gps_[type]->clone(name)); return nl_.gates_.size()-1; netlist_builder knows nothing about the gate implementations. A corresponding clone function will be called to generate a object as specified by the string type.

Put Everything Together void store_standard_gate_prototypes(gate_prototypes &gps) { flip_flop::store_prototype(gps); and_gate::store_prototype(gps); int main(int argc, char *argv[]) { // validate arguments and prepare wires and comps gate_prototypes gps; store_standard_gate_prototypes(gps); store_third_party_prototypes(gps); netlist nl; netlist_builder builder(nl, gps); evl_director(&builder, wires, comps); builder.finalize_creation(); // save the netlist nl or perform simulation The use of the Builder pattern enables us to modify netlist_builder without affecting evl_director and the netlist constructed in main. ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 22/60

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 23/60 Summary of Participants of the Prototype Pattern Prototype (gate) Declare an interface for cloning itself ConcretePrototype (flip_flop, and_gate, etc) Implement an operation for cloning itself Client (netlist_builder::add_gate) Create a new object by asking a prototype to clone itself

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 23/60 Summary of Participants of the Prototype Pattern Prototype (gate) Declare an interface for cloning itself ConcretePrototype (flip_flop, and_gate, etc) Implement an operation for cloning itself Client (netlist_builder::add_gate) Create a new object by asking a prototype to clone itself

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 23/60 Summary of Participants of the Prototype Pattern Prototype (gate) Declare an interface for cloning itself ConcretePrototype (flip_flop, and_gate, etc) Implement an operation for cloning itself Client (netlist_builder::add_gate) Create a new object by asking a prototype to clone itself

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 24/60 Benefits of the Prototype Pattern Hide concrete product classes from the client Greatly reduce the number of names the client know about less coupling Add and remove products at runtime, or even configure an application with classes dynamically Specify new types of objects by varying values or structure without introducing new class types In the bonus project, can you create prototypes for different types of modules? Reduce the necessity of inheritance for other creational patterns In our original netlist_builder design, introducing a new gate type without modifying it would require to derive a new ConcreteBuilder from it.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 25/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 26/60 The Design Problem void store_standard_gate_prototypes(gate_prototypes &gps); void store_third_party_prototypes(gate_prototypes &gps); netlist_builder::netlist_builder(netlist &nl, gate_prototypes &gps); void flip_flip::store_prototype(gate_prototypes &gps); void and_gate::store_prototype(gate_prototypes &gps); When calling these functions, all the parameters gps should refer to the same gate_prototypes object. How to enforce the requirement? People familiar with C may propose to use a global variable gps. However, there is no guarantee all these functions will use that gps object.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 27/60 The Singleton Pattern A creational pattern Ensure a class only has one instance, and provide a global point of access to it Unlike previous patterns, the Singleton pattern won t rely on polymorphism.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 28/60 The Singleton Interface // gate_prototypes.h class gate_prototypes { gate_prototypes(const gate_prototypes &) = delete; gate_prototypes &operator=(const gate_prototypes &) = delete; gate_prototypes() { ~gate_prototypes() { // use private ctor and dtor to prevent // the creation of additional instances std::map<std::string, gate *> prototypes_; public: void store(std::string name, gate *g); gate *locate(std::string name); static gate_prototypes &instance(); // access the only instance ; // class gate_prototypes Use static member function to provide access to the only class instance.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 29/60 The Singleton Implementation // gate_prototypes.cpp gate_prototypes &gate_prototypes::instance() { static gate_prototypes instance; // the only instance return instance; static variable in a function is constructed the first time when the function is called. Will persist throughout the program execution. Most importantly, the C++ runtime guarantees that the variable is constructed exactly once even in a multi-threading environment. A static member function can access all private members.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 30/60 Use Singleton // netlist_builder.h class netlist_builder : public netlist_builder_i { public: netlist_builder(netlist &nl) : nl_(nl) { ; // class netlist_builder // netlist_builder.cpp #include "gate_prototypes.h" size_t netlist_builder::add_gate(std::string type, std::string name) { gate *prototype = gate_prototypes::instance().locate(type); if (prototype == NULL) ; // handling errors nl_.gates_.push_back(prototype->clone(name)); return nl_.gates_.size()-1; To access the only instance, one just need to make sure the Singleton class type is available.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 31/60 Use Singleton: Another Example // gate_implementations.h class flip_flip: public gate { public: static void store_prototype(); ; // class flip_flop void store_standard_gate_prototypes(); // gate_implementations.cpp #include "gate_prototypes.h" void flip_flip::store_prototype() { gate_prototypes::instance().store("evl_dff", new flip_flop("prototype")); void store_standard_gate_prototypes() { flip_flop::store_prototype(); and_gate::store_prototype();

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 32/60 Put Everything Together int main(int argc, char *argv[]) { // validate arguments and prepare wires and comps store_standard_gate_prototypes(); store_third_party_prototypes(); netlist nl; netlist_builder builder(nl); evl_director(&builder, wires, comps); builder.finalize_creation(); // save the netlist nl or perform simulation The prototype storage is completely hidden.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 33/60 Benefits of the Singleton Pattern Controlled access to sole instance The compiler will enforce the controlled access via protections. Reduced name space A global variable would provide global access but will pollute the global name space since you have to name it. The singleton, on the other hand, simply requires a type. Permit refinement of operations and representation Since accesses are centralized, it is easy to refine/replace the singleton with an updated implementation. Permit a variable number of instances You may extend the pattern to provide more instances and controlled accesses to them.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 34/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 35/60 The Design Problem Our netlist is consisting of nets and predefined gates. What if we allow the hardware designer to specify their own types of gates, i.e. modules? These modules can then be reused to construct larger modules, eventually become a very complicated system. Usually known as the hierarchical design methodology, and is used for any practical hardware design How to represent such hierarchical structure?

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 36/60 The Composite Pattern A structural pattern Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. Component: the interface of objects in the composition Leaf: primitive objects in the composition Composite: objects constructed from leaves and composites

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 37/60 The Component Interface class gate { ; // class gate Since conceptually a netlist is consisting of nets and gates, it is intuitive to use gate as the common interface to the objects in the hierarchy. The gate class allows to access behavior of derived classes through virtual functions.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 38/60 The Leaves class flip_flop: public gate { ; // class flip_flop class and_gate: public gate { ; // class and_gate The primitive objects are the predefined gates in our design. Leaves are defined using public inheritance.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 39/60 The Composite class module: public gate { public: module(std::string type, std::string name) : gate(type, name) { ; // class module Since the composite should also be accessed from the component interface, it should be derived from it.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 40/60 The Composite: Child Components class module: public gate { module *parent_; // optional, will be NULL for top module std::list<gate *> children_; public: module(std::string type, std::string name, module *parent); ; // class module The composite is made up of child components. They could be primitive objects or other composites. There is only one class type for the composite. Different types of composite differ in their child components. As usual, the child components are managed by a container. It is optional for the composite to have a pointer to its parent, initialized when constructing the object.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 41/60 Updated Composite Implementation class module : public gate { netlist nl_; // internal structure std::vector<port *> ports_; // should match pins_ bool validate_structural_semantics() override; void compute_next_state_or_output() override; char compute_signal(int pin_index) override; module *clone() override; public: module(std::string type, std::string name); ~module(); ; // class module For module, in addition to gates, there are nets. So it is more convenient to use netlist as the container. An additional benefit is we can use a builder to construct nl_.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 42/60 Issues Is there any cyclic type dependency between module and netlist? No. Because the type netlist only depends on the type gate. However, the whole system should be a tree this should be verified and guaranteed when constructing the system. How to construct the whole system?

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 43/60 Summary of Participants of the Composite Pattern Component (gate) Declare the interface for objects in the composition Implement default behavior for the interface common to all classes, as appropriate Optionally, it may declare interfaces for accessing and managing its child components, and accessing its parent. Leaf (flip_flop, add_gate, etc.) Represent leaf objects in the composition, which have no children Define behavior for primitive objects in the composition Composite (module) Define behavior for components having children Store child components Implement child-related operations in the Component interface Client: any code that access objects in the composition through the Component interface

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 44/60 Benefits of the Composite Pattern Define class hierarchies consisting of primitive objects and composite objects Primitive objects can be composed into more complex objects, which in turn can be composed, and so on recursively and hierarchically. Wherever client code expects a primitive object, it may also take a composite object. Make the client simple Clients can treat composite structures and individual objects uniformly. Clients normally don t know (and shouldn t care) whether they re dealing with a leaf or a composite component this forces programmers to write code for the interface instead of for the implementation. Make it easier to add new kinds of components

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 45/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 46/60 The Design Problem size_t netlist_builder::add_gate(std::string type, std::string name) { gate *prototype = gate_prototypes::instance().locate(type); if (prototype == NULL) ; // handling errors nl_.gates_.push_back(prototype->clone(name)); return nl_.gates_.size()-1; void netlist_builder::add_net(std::string name) { nl_.nets_.push_back(new net); void netlist_builder::gate_append_pin(int gate_id ) { nl_.gates_[gate_id]->pins_.push_back(new pin); What if we want to bypass the prototypes for specific gate types? What if we want to replace net/pin with other types? Can we extend how parts are created but reuse the code for assembling them?

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 47/60 The Factory Patterns Two creational patterns that are closely related Define an interface to create objects, usually parts of a complex object Factory Methods The process to construct a complex object actually follows an algorithm. Therefore, we can apply the Template Method pattern to define parts creation as primitive operations. To emphasize that such primitive operations do create objects, we call them factory methods. Abstract Factory Alternatively, it is also possible to follow the Builder pattern to separate the parts creation from parts assembling by using an abstract interface.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 48/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 49/60 The Factory Methods class netlist_builder : public netlist_builder_i { virtual gate *make_gate(std::string type, std::string name); virtual net *make_net(); virtual pin *make_pin(); ; // class netlist_builder gate *netlist_builder::make_gate(std::string type, std::string name) { gate *prototype = gate_prototypes::instance().locate(type); if (prototype == NULL) ; // handling errors return prototype->clone(name); net *netlist_builder::make_net() {return new net; pin *netlist_builder::make_pin() {return new pin; The factory methods are only responsible for parts creation but not parts assembling.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 50/60 Products class netlist_builder : public netlist_builder_i { virtual gate *make_gate(std::string type, std::string name); virtual net *make_net(); virtual pin *make_pin(); ; // class netlist_builder gate serves as an interface to the products created by the factory method make_gate. For this example, net/pin serve as both the interfaces and the implementations of the products. To use new product classes, They should be derived from the corresponding product interfaces. Derive a new class from netlist_builder and override only the factory methods (make_xxxx)

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 51/60 Use Factory Methods in Builder size_t netlist_builder::add_gate(std::string type, std::string name) { nl_.gates_.push_back(make_gate(type, name)); void netlist_builder::add_net(std::string name) { nl_.nets_.push_back(make_net()); void netlist_builder::gate_append_pin(int gate_id ) { nl_.gates_[gate_id]->pins_.push_back(make_pin()); Follow the Template Method pattern to implement the algorithms using primitive operations, which are the factory methods

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 52/60 Summary of Participants of the Factory Method Pattern Product (gate, net, pin) Interfaces to parts, which are created by factory methods ConcreteProduct (flip_flop, net, pin, etc) Implements the Product interface Creator (netlist_builder) Declare the factory methods that return objects accessed from Product interfaces Provide default implementations of the factory methods if necessary Call factory methods to create objects ConcreteCreator Override the factory methods to return instances of ConcreteProduct types.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 53/60 Outline Builder Prototype Singleton Composite Factory Factory Methods Abstract Factory

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 54/60 The Factory Interface struct netlist_factory_i { virtual gate *make_gate(std::string type, std::string name) = 0; virtual net *make_net() = 0; virtual pin *make_pin() = 0; ; // struct netlist_factory_i Abstract factory is an abstract interface defining how parts are created. It returns products through Product interfaces.

size_t netlist_builder::add_gate(std::string type, std::string name) { nl_.gates_.push_back(factory_->make_gate(type, name)); void netlist_builder::add_net(std::string name) { nl_.nets_[name] = factory_->make_net(); void netlist_builder::gate_append_pin(int gate_id ) { nl_.gates_[gate_id]->pins_.push_back(factory_->make_pin()); Parts creations in the client (netlist_builder) are ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 55/60 The Client class netlist_builder : public netlist_builder_i { netlist_factory_i *factory_; public: netlist_builder(netlist &nl, netlist_factory_i *factory) : nl_(nl), factory_(factory) { ; // class netlist_builder

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 56/60 Implement a Factory class netlist_factory : public netlist_factory_i { virtual gate *make_gate(std::string type, std::string name); virtual net *make_net(); virtual pin *make_pin(); ; // class netlist_factory gate *netlist_factory::make_gate(std::string type, std::string name) { gate *prototype = gate_prototypes::instance()->locate(type); if (prototype == NULL) ; // handling errors return prototype->clone(name); net *netlist_factory::make_net() {return new net; pin *netlist_factory::make_pin() {return new pin; Similar to Builder, a ConcreteFactory is derived from the abstract interface and the pure virtual functions are implemented.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 57/60 Put Everything Together using Abstract Factory int main(int argc, char *argv[]) { // validate arguments and prepare wires and comps store_standard_gate_prototypes(); store_third_party_prototypes(); netlist nl; netlist_factory factory; netlist_builder builder(nl, &factory); evl_director(&builder, wires, comps); builder.finalize_creation(); // save the netlist nl or perform simulation Can you design a new factory hier_factory to make module objects for hierarchical designs?

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 58/60 A Factory for Hierarchical Design gate *hier_factory::make_gate(std::string type, std::string name) { gate *prototype = gate_prototypes::instance().locate(type); if (prototype!= NULL) return prototype->clone(name); find ports, wires, and comps for the module type // create a module with type type and name name module *p = new module(type, name); p->create_ports(ports); // create the internal netlist using builder and factory netlist_builder builder(p->nl_, this); evl_director(&builder, wires, comps); builder.finalize_creation(); return p; By reusing the factory to build internal netlist, the hierarchical design is created recursively.

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 59/60 Summary of Participants of the Abstract Factory Pattern Factory (or Abstract Factory, netlist_factory_i) Declare an interface for operations that create product objects ConcreteFactory (netlist_factory) Implement the operations to create concrete product objects Product (or AbstractProduct, gate, net, etc.) Declare an interface for a kind of product object ConcreteProduct (flip_flop, net, etc.) Define a product object to be created by the corresponding concrete factory Implement the Product interface Client (netlist_builder) Use only interfaces declared by Factory and Product classes

ECE 449 Object-Oriented Programming and Computer Simulation, Fall 2017, Dept. of ECE, IIT 60/60 Summary and Advice Behavioral pattern: Template Method Define the skeleton of an algorithm in an operation, deferring some steps to subclasses A fundamental technique for code reuse in class libraries Creational pattern: Singleton Ensure a class only has one instance, and provide a global point of access to it Additional creational patterns Factory: separate parts creation from parts assembling Builder: separate system specification from system creation Prototypes: hide part types for parts creation Structural pattern: Composite Compose objects into tree structures to represent part-whole hierarchies Component as an interface for leaves and composites