TDDB84: Lecture 09. SOLID, Language design, Summary. fredag 11 oktober 13

Similar documents
TDDB84. Lecture 2. fredag 6 september 13

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

Exam in TDDB84: Design Patterns,

TDDB84: Lecture 5. Singleton, Builder, Proxy, Mediator. fredag 27 september 13

TDDB84: Lecture 6. Adapter, Bridge, Observer, Chain of Responsibility, Memento, Command. fredag 4 oktober 13

SDC Design patterns GoF

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

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

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

TDDB84: Lecture 7. State, Visitor, Interpreter, DSL. fredag 4 oktober 13

CSCD01 Engineering Large Software Systems. Design Patterns. Joe Bettridge. Winter With thanks to Anya Tafliovich

Object-oriented Software Design Patterns

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

Design patterns. Jef De Smedt Beta VZW

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

Using Design Patterns in Java Application Development

Introduction to Software Engineering: Object Design I Reuse & Patterns

Trusted Components. Reuse, Contracts and Patterns. Prof. Dr. Bertrand Meyer Dr. Karine Arnout

UNIT I Introduction to Design Patterns

DESIGN PATTERN - INTERVIEW QUESTIONS

Design Pattern and Software Architecture: IV. Design Pattern

UNIT I Introduction to Design Patterns

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

Applying Design Patterns to SCA Implementations

CSCD01 Engineering Large Software Systems. Design Patterns. Joe Bettridge. Winter With thanks to Anya Tafliovich

Software Development Project. Kazi Masudul Alam

Ingegneria del Software Corso di Laurea in Informatica per il Management. Design Patterns part 1

C++ for System Developers with Design Pattern

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

Object-Oriented Oriented Programming

Design Patterns: Structural and Behavioural

Applying the Observer Design Pattern

Design Patterns Reid Holmes

OODP Session 4. Web Page: Visiting Hours: Tuesday 17:00 to 19:00

Lecture 4: Observer Pattern, Event Library and Componentization

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

Writing your own Java I/O Decorator p. 102 Tools for your Design Toolbox p. 105 Exercise Solutions p. 106 The Factory Pattern Baking with OO

Topics. Software Process. Agile. Requirements. Basic Design. Modular Design. Design Patterns. Testing. Quality. Refactoring.

Design Patterns. An introduction

Design Patterns. Dr. Rania Khairy. Software Engineering and Development Tool

What is Design Patterns?

A Primer on Design Patterns

SWEN425 DESIGN PATTERNS

SYLLABUS CHAPTER - 1 [SOFTWARE REUSE SUCCESS FACTORS] Reuse Driven Software Engineering is a Business

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

A few important patterns and their connections

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

Advanced C++ Programming Workshop (With C++11, C++14, C++17) & Design Patterns

Design Pattern What is a Design Pattern? Design Pattern Elements. Almas Ansari Page 1

1 Software Architecture

Ingegneria del Software Corso di Laurea in Informatica per il Management. Design Patterns part 1

Nat. Thomas Software Engineering Telephonics Inc. Long Island IEEE Lecture Series

The GoF Design Patterns Reference

Design patterns. OOD Lecture 6

Software Design Patterns. Aliaksei Syrel

Design Patterns. (and anti-patterns)

Lecture 20: Design Patterns II

Lectures 24 and 25 Introduction to Architectural Styles and Design Patterns

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

An Introduction to Patterns

Creational Design Patterns

Application Architectures, Design Patterns

Tuesday, October 4. Announcements

A Case Study of Gang of Four (GoF) Patterns: Part 3

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

Socket attaches to a Ratchet. 2) Bridge Decouple an abstraction from its implementation so that the two can vary independently.

INSTITUTE OF AERONAUTICAL ENGINEERING

Design Patterns. Observations. Electrical Engineering Patterns. Mechanical Engineering Patterns

Ownership in Design Patterns. Master's Thesis Final Presentation Stefan Nägeli

Patterns. Erich Gamma Richard Helm Ralph Johnson John Vlissides

Welcome to Design Patterns! For syllabus, course specifics, assignments, etc., please see Canvas

Design Patterns. SE3A04 Tutorial. Jason Jaskolka

CSCI Object Oriented Design: Frameworks and Design Patterns George Blankenship. Frameworks and Design George Blankenship 1

Software Reengineering Refactoring To Patterns. Martin Pinzger Delft University of Technology

The Design Patterns Matrix From Analysis to Implementation

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

Plan. Design principles: laughing in the face of change. What kind of change? What are we trying to achieve?

Design Patterns. Hausi A. Müller University of Victoria. Software Architecture Course Spring 2000

administrivia today UML start design patterns Tuesday, September 28, 2010

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

Applying Some Gang of Four Design Patterns CSSE 574: Session 5, Part 3

Chapter 8, Design Patterns Visitor

Overview of Patterns: Introduction

Applying Design Patterns to accelerate development of reusable, configurable and portable UVCs. Accellera Systems Initiative 1

Applying the Decorator Design Pattern

Trusted Components. Reuse, Contracts and Patterns. Prof. Dr. Bertrand Meyer Dr. Karine Arnout

CS251 Software Engineering Lectures 18: Intro to DP

Designing and Writing a Program. Divide and Conquer! The Design-Code-Debug Cycle. Documentation is Code. Pair Programming 3/8/2012

CS560. Lecture: Design Patterns II Includes slides by E. Gamma et al., 1995

Pro Objective-C Design Patterns for ios

DESIGNING, CODING, AND DOCUMENTING

Software Eningeering. Lecture 9 Design Patterns 2

MVC. Model-View-Controller. Design Patterns. Certain programs reuse the same basic structure or set of ideas

Design Patterns Lecture 2

Improve Your SystemVerilog OOP Skills

design patterns FOR B.tech (jntu - hyderabad & kakinada) (IV/I - CSE AND IV/II - IT) CONTENTS 1.1 INTRODUCTION TO DESIGN PATTERNS TTERNS... TTERN?...

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

What is Design Patterns?

Singleton Pattern Creational

A Reconnaissance on Design Patterns

Transcription:

TDDB84: Lecture 09 SOLID, Language design, Summary

SOLID Single responsibility principle Open/closed principle Liskov substitution principle Interface segregation principle Depency inversion principle

SOLID Single responsibility principle Open/closed principle Liskov substitution principle Interface segregation principle Depency inversion principle

Single responsibility Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Single responsibility Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Single responsibility Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Open/closed Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Open/closed Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Liskov substitution Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Liskov substitution Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Interface segregation Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Interface segregation Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Depency inversion Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Depency inversion Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Depency inversion Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Depency inversion Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Encapsulate what varies Strive for loosely-coupled design

Too general? Encapsulate what varies Strive for loosely-coupled design

Too general? Encapsulate what varies Strive for loosely-coupled design A consequence of applying SOLID?

Too general? Too trivial? Encapsulate what varies Strive for loosely-coupled design A consequence of applying SOLID?

Language Design vs Design Patterns

Language features Open classes: The ability to redefine classes Metaprogramming: The ability to inspect and manipulate programs and their processes from within the language Multiple dispatch: The ability to select a function based on the runtime types of all arguments First-order functions: The ability to use functions as objects

Open classes

C# Open classes public static class ObjectExtensions {!!! 1.ToXML ();!!! new Person ().ToXML (); public static string ToXML(this object objecttoserialize) { MemoryStream mem=new MemoryStream(); XmlSerializer ser=new XmlSerializer(objectToSerialize.GetType()); ser.serialize(mem,objecttoserialize); ASCIIEncoding ascii=new ASCIIEncoding(); return ascii.getstring(mem.toarray()); }

C# Open classes public static class ObjectExtensions {!!! 1.ToXML ();!!! new Person ().ToXML (); Ruby public static string ToXML(this object objecttoserialize) { MemoryStream mem=new MemoryStream(); XmlSerializer ser=new XmlSerializer(objectToSerialize.GetType()); ser.serialize(mem,objecttoserialize); ASCIIEncoding ascii=new ASCIIEncoding(); return ascii.getstring(mem.toarray()); } class Object def to_xml vars = instance_variables.map do var name=var.to_s.sub('@','') "<#{name}>#{instance_variable_get(var)}</#{name}>".join(" ") "<root>#{vars}</root>" irb(main):081:0> p.to_xml "<root><name>ola</name> <age>34</age></root>" class Person attr_accessor :name, :age p = Person.new p.name = "Ola" p.age = 34

Metaprogramming C# public class FieldMappingConfigurator<T> where T: class, new() { private Configurator Configurator { get; set; } private string FieldName { get; set; } internal FieldMappingConfigurator(string fieldname, Configurator configurator) { Configurator = configurator; FieldName = fieldname; } } public void To<T1>(Expression<Func<T,T1>> propertyselector) { var selectorexpression = (MemberExpression) propertyselector.body; var prop = (PropertyInfo) selectorexpression.member; Configurator.CustomFieldsToPropertiesMap[FieldName]=prop; } GenericDAO<DomainObject>.Configure("some_StoredProcedure").Map("AFieldInTheResultSetReturned").To(s => s.id);

Metaprogramming C# public class FieldMappingConfigurator<T> where T: class, new() { private Configurator Configurator { get; set; } private string FieldName { get; set; } internal FieldMappingConfigurator(string fieldname, Configurator configurator) { Configurator = configurator; FieldName = fieldname; } } public void To<T1>(Expression<Func<T,T1>> propertyselector) { var selectorexpression = (MemberExpression) propertyselector.body; var prop = (PropertyInfo) selectorexpression.member; Configurator.CustomFieldsToPropertiesMap[FieldName]=prop; } GenericDAO<DomainObject>.Configure("some_StoredProcedure").Map("AFieldInTheResultSetReturned").To(s => s.id);

Metaprogramming C# public class FieldMappingConfigurator<T> where T: class, new() { private Configurator Configurator { get; set; } private string FieldName { get; set; } internal FieldMappingConfigurator(string fieldname, Configurator configurator) { Configurator = configurator; FieldName = fieldname; } } public void To<T1>(Expression<Func<T,T1>> propertyselector) { var selectorexpression = (MemberExpression) propertyselector.body; var prop = (PropertyInfo) selectorexpression.member; Configurator.CustomFieldsToPropertiesMap[FieldName]=prop; } GenericDAO<DomainObject>.Configure("some_StoredProcedure").Map("AFieldInTheResultSetReturned").To(s => s.id);

Metaprogramming GenericDAO<DomainObject>.Configure("some_StoredProcedure").Map("AFieldInTheResultSetReturned").To(s => s.id); C# public class FieldMappingConfigurator<T> where T: class, new() { private Configurator Configurator { get; set; } private string FieldName { get; set; } internal FieldMappingConfigurator(string fieldname, Configurator configurator) { Configurator = configurator; FieldName = fieldname; } } public void To<T1>(Expression<Func<T,T1>> propertyselector) { var selectorexpression = (MemberExpression) propertyselector.body; var prop = (PropertyInfo) selectorexpression.member; Configurator.CustomFieldsToPropertiesMap[FieldName]=prop; } Program analysis

Metaprogramming class SetupProjectBuilder class << self def setup_classes @setup_classes = [] Ruby def inherited(sub_class) setup_classes << sub_class def setup_project?(project_file)!setup_class(project_file).nil? def setup_class(project_file) setup_classes.find { c c.project_file_pattern =~ project_file } class VDProjBuilder < SetupProjectBuilder def self.project_file_pattern /\.vdproj$/ [... ]

Metaprogramming class SetupProjectBuilder class << self def setup_classes @setup_classes = [] Ruby def inherited(sub_class) setup_classes << sub_class def setup_project?(project_file)!setup_class(project_file).nil? Process analysis def setup_class(project_file) setup_classes.find { c c.project_file_pattern =~ project_file } class VDProjBuilder < SetupProjectBuilder def self.project_file_pattern /\.vdproj$/ [... ]

Metaprogramming class SetupProjectBuilder class << self Method-related hooks Ruby def setup_classes @setup_classes = [] def inherited(sub_class) setup_classes << sub_class def setup_project?(project_file)!setup_class(project_file).nil? Process analysis def setup_class(project_file) setup_classes.find { c c.project_file_pattern =~ project_file } method_missing method_added singleton_method_added method_removed singleton_method_removed method_undefined singleton_method_undefined Class & Module Hooks inherited app_features included ext_object exted initialize_copy const_missing class VDProjBuilder < SetupProjectBuilder def self.project_file_pattern /\.vdproj$/ [... ]

Metaprogramming class SetupProjectBuilder class << self Method-related hooks Ruby def setup_classes @setup_classes = [] def inherited(sub_class) setup_classes << sub_class def setup_project?(project_file)!setup_class(project_file).nil? Process analysis def setup_class(project_file) setup_classes.find { c c.project_file_pattern =~ project_file } method_missing method_added singleton_method_added method_removed singleton_method_removed method_undefined singleton_method_undefined Class & Module Hooks inherited app_features included ext_object exted initialize_copy const_missing class VDProjBuilder < SetupProjectBuilder def self.project_file_pattern /\.vdproj$/ [... ]

Metaprogramming class SetupProjectBuilder class << self Method-related hooks Ruby def setup_classes @setup_classes = [] def inherited(sub_class) setup_classes << sub_class def setup_project?(project_file)!setup_class(project_file).nil? Process analysis def setup_class(project_file) setup_classes.find { c c.project_file_pattern =~ project_file } method_missing method_added singleton_method_added method_removed singleton_method_removed method_undefined singleton_method_undefined Class & Module Hooks inherited app_features included ext_object exted initialize_copy const_missing class VDProjBuilder < SetupProjectBuilder Factory Method def self.project_file_pattern /\.vdproj$/ [... ]

Metaprogramming in Ruby class YamlConf def conf @conf = load(self.class.simple_name+".yml") # Look up keys in the configuration hash def method_missing(method,*args) method_name=method.to_s conf[method_name]

Metaprogramming in Ruby class YamlConf def conf @conf = load(self.class.simple_name+".yml") # Look up keys in the configuration hash def method_missing(method,*args) method_name=method.to_s conf[method_name] class Mail < YamlConf;

Metaprogramming in Ruby class YamlConf def conf @conf = load(self.class.simple_name+".yml") # Look up keys in the configuration hash def method_missing(method,*args) method_name=method.to_s conf[method_name] class Mail < YamlConf; config/mail.yml from: "john.appleseed@apple.com" to: - "ola.leifler@liu.se" - "tommy.farnqvist@liu.se" host: "smtp.somehost.com"

Metaprogramming in Ruby class YamlConf def conf @conf = load(self.class.simple_name+".yml") # Look up keys in the configuration hash def method_missing(method,*args) method_name=method.to_s conf[method_name] class Mail < YamlConf; mail = Mail.new do from Conf::Mail.from to Conf::Mail.to subject s body b config/mail.yml from: "john.appleseed@apple.com" to: - "ola.leifler@liu.se" - "tommy.farnqvist@liu.se" host: "smtp.somehost.com"

Metaprogramming in Ruby class YamlConf def conf @conf = load(self.class.simple_name+".yml") # Look up keys in the configuration hash def method_missing(method,*args) method_name=method.to_s conf[method_name] class Mail < YamlConf; mail = Mail.new do from Conf::Mail.from to Conf::Mail.to subject s body b config/mail.yml from: "john.appleseed@apple.com" to: - "ola.leifler@liu.se" - "tommy.farnqvist@liu.se" host: "smtp.somehost.com"

Metaprogramming in Ruby class YamlConf def conf @conf = load(self.class.simple_name+".yml") # Look up keys in the configuration hash def method_missing(method,*args) method_name=method.to_s conf[method_name] class Mail < YamlConf; mail = Mail.new do from Conf::Mail.from to Conf::Mail.to subject s body b config/mail.yml from: "john.appleseed@apple.com" to: - "ola.leifler@liu.se" - "tommy.farnqvist@liu.se" host: "smtp.somehost.com"

Metaprogramming in Ruby class YamlConf def conf @conf = load(self.class.simple_name+".yml") # Look up keys in the configuration hash def method_missing(method,*args) method_name=method.to_s conf[method_name] class Mail < YamlConf; mail = Mail.new do from Conf::Mail.from to Conf::Mail.to subject s body b config/mail.yml from: "john.appleseed@apple.com" to: - "ola.leifler@liu.se" - "tommy.farnqvist@liu.se" host: "smtp.somehost.com" Proxy

Metaprogramming in Java public State() { ClassWithState obj = ClassWithState.this; manipulatefields(obj, new FieldManipulator() { @Override public void manipulatefield(object obj, Field field) throws IllegalAccessException { } getstate().put(field.getname(), field.get(obj)); } }); private void manipulatefields(object obj, FieldManipulator fieldmanipulator) { Class<?> cl = obj.getclass(); for (Field field : cl.getdeclaredfields()) { field.setaccessible(true); try { fieldmanipulator.manipulatefield(obj, field); } catch (IllegalArgumentException e) { e.printstacktrace(); } catch (IllegalAccessException e) { e.printstacktrace(); } } }

Metaprogramming in Java public State() { ClassWithState obj = ClassWithState.this; manipulatefields(obj, new FieldManipulator() { @Override public void manipulatefield(object obj, Field field) throws IllegalAccessException { } getstate().put(field.getname(), field.get(obj)); } }); Memento private void manipulatefields(object obj, FieldManipulator fieldmanipulator) { Class<?> cl = obj.getclass(); for (Field field : cl.getdeclaredfields()) { field.setaccessible(true); try { fieldmanipulator.manipulatefield(obj, field); } catch (IllegalArgumentException e) { e.printstacktrace(); } catch (IllegalAccessException e) { e.printstacktrace(); } } }

Metaprogramming in Java @Override public Object invoke(object arg0, Method m, Object[] arg2) throws Throwable { Object result = m.invoke(instance, arg2); if (m.getname().equals("getemployments") && result == null) { } System.out.println(MessageFormat.format( "Trying to access uninstantiated field {0}", m.getname().substring(3))); [ some magic happens ] Method setter = m.getdeclaringclass().getmethod( "setemployments", Collection.class); System.out.println(MessageFormat.format( "Instantiated field {0}", m.getname().substring(3))); setter.invoke(instance, employments); } return m.invoke(instance, arg2);

Metaprogramming in Java @Override public Object invoke(object arg0, Method m, Object[] arg2) throws Throwable { Object result = m.invoke(instance, arg2); if (m.getname().equals("getemployments") && result == null) { } System.out.println(MessageFormat.format( "Trying to access uninstantiated field {0}", m.getname().substring(3))); [ some magic happens ] Method setter = m.getdeclaringclass().getmethod( "setemployments", Collection.class); System.out.println(MessageFormat.format( "Instantiated field {0}", m.getname().substring(3))); setter.invoke(instance, employments); } return m.invoke(instance, arg2); Proxy

Multiple dispatch (defclass duck () ((name :initarg :name :accessor name))) (defclass mallard-duck (duck) ()) (defclass red-duck (duck) ()) (defclass rubber-duck (duck) ()) ;; In another file, we can add flying behavior ;; What design pattern is this an implementation of? (defclass fly-behavior () ()) (defclass fly-with-wings (fly-behavior) ()) (defclass no-fly (fly-behavior) ()) (defgeneric fly (duck fly-behavior) (:documentation "A method to allow ducks to fly") (:method ((d mallard-duck) (b fly-with-wings)) (format t "The mallard duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b fly-with-wings)) (format t "Rubber duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b no-fly)) (format t "Rubber duck ~A is not flying at all" (name d))) )

Multiple dispatch (defclass duck () ((name :initarg :name :accessor name))) (defclass mallard-duck (duck) ()) (defclass red-duck (duck) ()) (defclass rubber-duck (duck) ()) ;; In another file, we can add flying behavior ;; What design pattern is this an implementation of? (defclass fly-behavior () ()) (defclass fly-with-wings (fly-behavior) ()) (defclass no-fly (fly-behavior) ()) (defgeneric fly (duck fly-behavior) (:documentation "A method to allow ducks to fly") (:method ((d mallard-duck) (b fly-with-wings)) (format t "The mallard duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b fly-with-wings)) (format t "Rubber duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b no-fly)) (format t "Rubber duck ~A is not flying at all" (name d))) ) Method description

Multiple dispatch (defclass duck () ((name :initarg :name :accessor name))) (defclass mallard-duck (duck) ()) (defclass red-duck (duck) ()) (defclass rubber-duck (duck) ()) ;; In another file, we can add flying behavior ;; What design pattern is this an implementation of? (defclass fly-behavior () ()) (defclass fly-with-wings (fly-behavior) ()) (defclass no-fly (fly-behavior) ()) (defgeneric fly (duck fly-behavior) (:documentation "A method to allow ducks to fly") (:method ((d mallard-duck) (b fly-with-wings)) (format t "The mallard duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b fly-with-wings)) (format t "Rubber duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b no-fly)) (format t "Rubber duck ~A is not flying at all" (name d))) ) Method description ;; CL-USER> (fly (make-instance 'rubber-duck :name "Ducky") (make-instance 'fly-with-wings)) ;; Rubber duck Ducky is flying with wings! ;; NIL ;; CL-USER> (fly (make-instance 'rubber-duck :name "Ducky") (make-instance 'no-fly)) ;; Rubber duck Ducky is not flying at all

Multiple dispatch (defclass duck () ((name :initarg :name :accessor name))) (defclass mallard-duck (duck) ()) (defclass red-duck (duck) ()) (defclass rubber-duck (duck) ()) ;; In another file, we can add flying behavior ;; What design pattern is this an implementation of? (defclass fly-behavior () ()) (defclass fly-with-wings (fly-behavior) ()) (defclass no-fly (fly-behavior) ()) (defgeneric fly (duck fly-behavior) (:documentation "A method to allow ducks to fly") (:method ((d mallard-duck) (b fly-with-wings)) (format t "The mallard duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b fly-with-wings)) (format t "Rubber duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b no-fly)) (format t "Rubber duck ~A is not flying at all" (name d))) ) Method description Method dispatch ;; CL-USER> (fly (make-instance 'rubber-duck :name "Ducky") (make-instance 'fly-with-wings)) ;; Rubber duck Ducky is flying with wings! ;; NIL ;; CL-USER> (fly (make-instance 'rubber-duck :name "Ducky") (make-instance 'no-fly)) ;; Rubber duck Ducky is not flying at all

Multiple dispatch (defclass duck () ((name :initarg :name :accessor name))) (defclass mallard-duck (duck) ()) (defclass red-duck (duck) ()) (defclass rubber-duck (duck) ()) ;; In another file, we can add flying behavior ;; What design pattern is this an implementation of? (defclass fly-behavior () ()) (defclass fly-with-wings (fly-behavior) ()) (defclass no-fly (fly-behavior) ()) (defgeneric fly (duck fly-behavior) (:documentation "A method to allow ducks to fly") (:method ((d mallard-duck) (b fly-with-wings)) (format t "The mallard duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b fly-with-wings)) (format t "Rubber duck ~A is flying with wings!" (name d))) (:method ((d rubber-duck) (b no-fly)) (format t "Rubber duck ~A is not flying at all" (name d))) ) Method description Method dispatch ;; CL-USER> (fly (make-instance 'rubber-duck :name "Ducky") (make-instance 'fly-with-wings)) ;; Rubber duck Ducky is flying with wings! ;; NIL ;; CL-USER> (fly (make-instance 'rubber-duck :name "Ducky") (make-instance 'no-fly)) ;; Rubber duck Ducky is not flying at all Strategy

(defclass expression () ()) (defclass compound-expression (expression) ((left :initarg :left :accessor left) (operator :initarg :operator :accessor operator) (right :initarg :right :accessor right))) (defclass atomic (expression) ((value :initarg :value :accessor value))) compoundexpression expression atomic ;;;;;;;; Indepently of the classes above, we define a way to ;;;;;;;; perform different operations on the objects of each class ;; What pattern would this correspond in the GoF book? (defgeneric get-value (Expression) (:documentation "Calculates the value of the expression ") (:method ((self compound-expression)) (funcall (operator self)! (get-value (left self))! (get-value (right self)))) (:method ((self atomic)) (value self))) (defvar expression (make-instance 'compound-expression!!! :left (make-instance 'atomic :value 3)!!! :operator #'*!!! :right (make-instance 'atomic :value 4))) (defvar expression2 (make-instance 'compound-expression!!! :left expression!!! :operator #'+!!! :right (make-instance 'atomic :value 5)!!! )) expression2 + expression * 5 (get-value expression2) 3 4

(defclass expression () ()) (defclass compound-expression (expression) ((left :initarg :left :accessor left) (operator :initarg :operator :accessor operator) (right :initarg :right :accessor right))) (defclass atomic (expression) ((value :initarg :value :accessor value))) compoundexpression expression atomic ;;;;;;;; Indepently of the classes above, we define a way to ;;;;;;;; perform different operations on the objects of each class ;; What pattern would this correspond in the GoF book? (defgeneric get-value (Expression) (:documentation "Calculates the value of the expression ") (:method ((self compound-expression)) (funcall (operator self)! (get-value (left self))! (get-value (right self)))) (:method ((self atomic)) (value self))) (defvar expression (make-instance 'compound-expression!!! :left (make-instance 'atomic :value 3)!!! :operator #'*!!! :right (make-instance 'atomic :value 4))) (defvar expression2 (make-instance 'compound-expression!!! :left expression!!! :operator #'+!!! :right (make-instance 'atomic :value 5)!!! )) expression2 + expression * 5 (get-value expression2) 3 4 Visitor

First-order functions C# new List<int> () { 1, 2, 3 }.Select (x => x +2); => { 3, 4, 5 } Ruby [1,2,3].collect { x x+2 } => [3,4,5] Lisp (mapcar #'(lambda (x) (+ x 2)) '(1 2 3)) => (3 4 5)

First-order functions C# new List<int> () { 1, 2, 3 }.Select (x => x +2); => { 3, 4, 5 } Ruby [1,2,3].collect { x x+2 } => [3,4,5] Lisp (mapcar #'(lambda (x) (+ x 2)) '(1 2 3)) => (3 4 5)

First-order functions C# new List<int> () { 1, 2, 3 }.Select (x => x +2); => { 3, 4, 5 } Ruby [1,2,3].collect { x x+2 } => [3,4,5] Lisp (mapcar #'(lambda (x) (+ x 2)) '(1 2 3)) => (3 4 5)

First-order functions C# new List<int> () { 1, 2, 3 }.Select (x => x +2); => { 3, 4, 5 } Ruby [1,2,3].collect { x x+2 } => [3,4,5] Lisp (mapcar #'(lambda (x) (+ x 2)) '(1 2 3)) => (3 4 5)

First-order functions C# new List<int> () { 1, 2, 3 }.Select (x => x +2); => { 3, 4, 5 } Ruby [1,2,3].collect { x x+2 } => [3,4,5] Lisp (mapcar #'(lambda (x) (+ x 2)) '(1 2 3)) => (3 4 5) Strategy

Open classes vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

Open classes vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

Metaprogramming vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

Metaprogramming vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

Multiple dispatch vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

Multiple dispatch vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

First-order functions vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

First-order functions vs Design Patterns Creational Factory method Abstract Factory Singleton Prototype Strategy Builder Structural Decorator Facade Composite Proxy Flyweight Bridge Adapter Behavioral State Command Template method Iterator Visitor Interpreter Mediator Chain of responsibility Observer Memento Highlighted patterns simplified

Summary

What is Good Design?

Encapsulate what varies Program to an interface, not to an implementation Favor composition over inheritance Classes should be open for extension but closed for modification Don t call us, we ll call you Dep on abstractions, do not dep on concrete classes Classes should only have one reason to change Strive for loosely-coupled design

Or...

Or... Testable programs

Or... Testable programs Changeable programs

Or... Testable programs Changeable programs

Or... Testable programs Changeable programs Test Change

What is a Design Pattern?

What is a Design Pattern? Why are there Design Patterns?

What is a Design Pattern? Why are there Design Patterns? How are Design Patterns used/recognized?

Why

Why 1. There are OO Programming Languages

Why 1. There are OO Programming Languages 2. There are Common Problems

Why 1. There are OO Programming Languages 2. There are Common Problems 3. There are Design Principles

Why 1. There are OO Programming Languages 2. There are Common Problems 3. There are Design Principles 1+2+3 = Design Pattern

How

How 1. There are Structure Diagrams

How 1. There are Structure Diagrams 2. There are A Bunch of Other Attributes

How 1. There are Structure Diagrams 2. There are A Bunch of Other Attributes 1+2 = Design Pattern

Other Patterns

Other Patterns Simpleton The Simpleton Pattern is an extremely complex pattern used for the most trivial of tasks. The Simpleton is an accurate indicator of the skill level of its creator.

Other Patterns Simpleton The Simpleton Pattern is an extremely complex pattern used for the most trivial of tasks. The Simpleton is an accurate indicator of the skill level of its creator. Commando The Commando Pattern is used to get in and out quick, and get the job done. This pattern can break any encapsulation to accomplish its mission. It takes no prisoners.

Other Patterns Simpleton The Simpleton Pattern is an extremely complex pattern used for the most trivial of tasks. The Simpleton is an accurate indicator of the skill level of its creator. Commando The Commando Pattern is used to get in and out quick, and get the job done. This pattern can break any encapsulation to accomplish its mission. It takes no prisoners. http://franksworld.com/blog/archive/2005/01/04/600.aspx

The Exam

Oct 25th 8-12 Bring written notes & the books. Justify all your reasoning. Good luck!

Thank you!