SlideShare a Scribd company logo
1 of 80
Download to read offline
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
SOLID C
James Grenning
Presented at ACCU 2014
Bristol, UK
1
Talk to me on Twitter
@jwgrenning
!
Connect with me on linkedin.com
http://www.linkedin.com/in/jwgrenning
Remind me how we met.
!
http://www.wingman-sw.com
http://blog.wingman-sw.com
http:// www.jamesgrenning.com
unpappd.com jwgrenning
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
2
When is Software
Design Finished?
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
3
A Complex system that
works is invariably
found to have evolved
from a simple system
that worked.
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
4
Red
Green
Refactor
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Rules of Simple Design
In Priority Order!
1. Passes all tests
2. No duplication
3. Expresses intent
4. Fewest classes and methods (no extra stuff)
5
Kent Beck [XP, TDD]
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
6
Why is SoftwareValuable?
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
!
• Functionality
!
!
!
• Malleability
7
The Two Values of Software
Red
Green
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
8
Red
Green
Refactor
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
9
www.renaissancesoftware.net
james@renaissancesoftware.net
Copyright ©2008-2013 James W. Grenning	

All Rights Reserved. For use by training attendees. The End
10
Become an expert in
your craft so you can
advise your boss
My Boss won’t let me
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Design for Maintenance
• Systems evolve, the design is NEVER done.
• Automated tests make evolution safer.
!
• Key technical practices for evolving design
– Test Driven development
– Refactoring
– Modularity, Loose Coupling, High Cohesion

(OO Design)
11
Donald Knuth Says
12
ACCU 2014
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees.
Let us change our
traditional attitude to the
construction of programs.
Instead of imagining that
our main task is to
instruct a computer what to
do, let us concentrate rather
on explaining to human
beings what we want a
computer to do.
Martin Fowler Says
13
ACCU 2014
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees.
Any fool can write code
that the compiler
understands, but it takes
real skill to write code
other programmers can
understand.
From “Refactoring - Improving the Design of Existing Code
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Three Critical Skills
14
Recognize what is wrong and fix it!
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
!
!
SOLID
15
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Spaghetti Slide
16
• Once a design problem is identified, you must
envision a better solution
• Look to apply the design principles
– SOLID
– DRY - Don’t Repeat Yourself
–from The Pragmatic Programmer
– Principle of Least Knowledge.
– Separation of Concerns (SoC).
Refactoring
www.renaissancesoftware.net
james@renaissancesoftware.net
Copyright © 2008-2013 James W. Grenning	

All Rights Reserved. For use by training attendees.
Envisioning
17
Refactoring
www.renaissancesoftware.net
james@renaissancesoftware.net
Copyright © 2008-2013 James W. Grenning	

All Rights Reserved. For use by training attendees.
18
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
SOLID Design Principles
19
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
SOLID Design Principles
Single Responsibility Principle
Open/Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle
20
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Home Automation System
Light Scheduling Requirements
• The light scheduler maintains a schedule for lights that can
be turned on or off. Multiple schedules per light are supported
for each light.
• A light can be scheduled to turn on.
• A light can be scheduled to turn off.
• 32 lights can be addressed by their integer ID.
• It must support 128 separate scheduled events
• Schedules can be established by
– specific day of the week (M Tu W Th F Sa Su), or everyday.
• Lights can also be controlled though a UI on a front panel,
iPad, iPhone, Android device, or web enabled device.
21
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
22
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Spaghetti Slide
23
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Single Responsibility Principle
Bob Martin [AGILE]
• a.k.a. Cohesion
!
• A module should do one thing and do it well.
• A module should have a single reason to change.
!
• Test: a module can be described in 25 words or less.
24
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
25
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
A Module with Collaborators
• Every minute, the
RTOS wakes up
the Light
Scheduler.
• If it is time for one
of the lights to be
controlled, the
LightController is
told to turn on/off
the light.
26
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
+ScheduleTurnOn()
+RemoveSchedule()
+WakeUp()
Light Controller
+ On(id)
+ Off(id)
Hardware RTOS
<<anonymous callback>>
Admin
Console
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
27
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Open/Closed Principle
• A module is open for extension, and closed for
modification.
• A design adheres to the open closed principle when it
accommodates a certain kinds of changes without
having to change existing code.
• Changes just drop in.
!
• Say “X is open for extension for new kinds of Ys, but
closed for modification”
28
Thanks: Bertrand Meyers
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
OCP Applied
LightScheduler is
open for extension for
new kinds of
LightControllers and
TimeServices.
!
It is closed for
modification for those
extensions.
29
<<interface>>
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
+ ScheduleTurnOn()
+ RemoveSchedule()
+WakeUp()
<<interface>>
Light Controller
+ On(id)
+ Off(id)
X10 Light
Controller
Acme
Time Service
Admin
Console
Model 42
Light Controller
Linux
Time Service
<<implements>> <<implements>>
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
30
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Liskov Substitution Principle
• Modules with the same interface can be substituted
without the client knowing the difference.
– Modules must meet the contract of the client and
interface.
– Preconditions cannot be strengthened in a server.
– Postconditions cannot be weakened in a server.
31
Thanks: Barbara Liskov
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
32
© James Barrante. This file is licensed under the Creative Commons Attribution 3.0 Unported license.
OS Abstraction
typedef struct ThreadStruct * Thread;	
typedef void * (*ThreadEntryFunction)(void *);	
!
Thread Thread_Create(ThreadEntryFunction f, void * parameter);	
void Thread_Start(Thread);	
void Thread_Destroy(Thread);	
void Thread_Exit(void *);	
void Thread_Join(Thread, void **result);	
void * Thread_Result(Thread);	
33
ACCU 2014
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees.
OS Abstraction is Not Working
//Snip from some product code	
!
Thread thread = Thread_Create(threadEntry, 0);	
!
#if POSIX_OS	
//POSIX starts thread on create	
#else	
//AcmeOS does not start thread on create	
Thread_Start(thread);	
#endif
34
ACCU 2014
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees.
OCP/LSP Designs Don’t Burden the Client
//Snip from some product code	
!
Thread thread = Thread_Create(threadEntry, 0);	
Thread_Start(thread);	
35
ACCU 2014
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees.
POSIX Version Delays Thread Creation
typedef struct ThreadStruct	
{	
ThreadEntryFunction entry;	
void * parameter;	
pthread_t pthread;	
BOOL started;	
!
} ThreadStruct;	
!
Thread Thread_Create(ThreadEntryFunction f, void * parameter)	
{	
Thread self = calloc(1, sizeof(ThreadStruct));	
self->entry = f;	
self->parameter = parameter;	
self->started = FALSE;;	
return self;	
}	
!
void Thread_Start(Thread self)	
{	
self->started = TRUE;	
pthread_create(&self->pthread, NULL, self->entry, self->parameter);	
}	
36
ACCU 2014
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees.
Acme Does Not Need To Delay Create
typedef struct ThreadStruct	
{	
AcmeThreadStruct acmeThread;	
} ThreadStruct;	
!
Thread Thread_Create(ThreadEntryFunction entry, void * parameter)	
{	
Thread self = calloc(1, sizeof(ThreadStruct));	
AcmeThread_create(&self->acmeThread, entry, parameter, 5, 1000);	
return self;	
}	
!
void Thread_Start(Thread self)	
{	
AcmeThread_start(&self->acmeThread);	
}	
37
ACCU 2014
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees.
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Interface Segregation Principle
• Don’t depend on fat interfaces.
• Don’t depend on interfaces that have methods you
don’t care about.
• Tailor interfaces to client need.
• Split fat interfaces.
38
Thanks: Robert Martin
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Light Scheduler Design
• The TimeService
limits the
knowledge of the
RTOS
!
• Adapters are a form
of Interface
Segregations
39
<<interface>>
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
+ AddTurnOn()
+ RemoveSchedule()
+WakeUp()
<<interface>>
Light Controller
+ On(id)
+ Off(id)
Model 42 Hardware RTOS
<<anonymous callback>>
Model 42
Light Controller
RTOS
Time Service
<<implements>> <<implements>>
Admin
Console
Third
Party
Code
Your
Code
Your
Code Your
Code
Third
Party
Code
Your
Code
Your
Code Your
Code
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Manage Third Party Dependenices
40
Your Tailored
Service
Interface
Your
Code
Your
Code Your
Code
Third
Party
Code
Your adaptor
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Dependency Inversion Principle
• Invert dependencies from high level modules to low
level details.
• Break problem dependencies by inserting an
abstraction.
– High level detail depends on an interface
– Low level code depends on the interface
– Interface depends on neither
– Dependency cycle
• a.k.a. Depend on Abstractions
41
Thanks: Robert Martin
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Un-Managed Dependencies
• Transitive
dependencies make
the highest level of
this design depend
on the lowest level
details.
!
• Use DIP to break the
transitive
dependency chain.
42
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
+ScheduleTurnOn()
+RemoveSchedule()
+WakeUp()
Light Controller
+ On(id)
+ Off(id)
Hardware RTOS
<<anonymous callback>>
Admin
Console
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Invert Dependencies with Interfaces
43
<<interface>>
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
+ ScheduleTurnOn()
+ RemoveSchedule()
+WakeUp()
<<interface>>
Light Controller
+ On(id)
+ Off(id)
Model 42 Hardware RTOS
<<anonymous callback>>
Model 42
Light Controller
RTOS
Time Service
<<implements>> <<implements>>
Admin
Console
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Unmanaged Dependencies Lead
to Manual Testing
44
The Net
Core Software
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Substitutability Supports Testing
45
<<interface>>
Time Service
+ GetTime()
+ SetPeriodicAlarm()
Light
Scheduler
Test
Light
Scheduler
+ ScheduleTurnOn()
+ RemoveSchedule()
+wakeUp()
<<interface>>
Light Controller
+ On(id)
+ Off(id)
Light Controller
Spy
Fake
Time Service
<<implements>> <<implements>>
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Interfaces in C
• Containing just what is needed to interact with the
module
– Function declarations
– Constants needed for interacting with the module
– struct forward declaration
!
• Things not in the interface header file
– Data structure member definitions
– Data definitions
– Constants needed in the implementation
46
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Rules of Simple Design
In Priority Order!
1. Passes all tests
2. No duplication
3. Expresses intent
4. Fewest classes and methods (no extra stuff)*
47
Kent Beck [XP, TDD]
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
*Fewest Classes and Methods that
Move You Closer to A Workable
Architecture
48
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Architectural Vision
• Have an idea where you are going.
• Build slices of functionality that lets you try the
architecture.
• Don’t build architecture first, get features working
and refactor to a great architecture.
• Keep architectural view high level.
49
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Architectural Vision
The Big Picture
• Have a big picture in the developers’ minds.
• The vision shows
– the major boundaries
– the areas of concern
– the interfaces
• Likely fractal in nature
50
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
SOLID and Testable C
51
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Different Design Models in C
52
Model Purpose
Single-instance !
Abstract Data Type
Encapsulates a module’s internal state when only
a single instance of the module is needed
Multiple-instance !
Abstract Data Type
Encapsulates a module’s internal state and allows
multiple instances of the module’s data
Dynamic interface Allows a module’s interface functions to be
assigned at runtime
Per-type dynamic
Interface
Allows multiple types of modules with the same
interface to have unique interface functions
Barbara Liskov,
Programming with abstract data types. Proceedings of the
ACM SIGPLAN Symposium on Very High Level Languages, 1974.
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Single Instance Abstract Data Type
!
53
#ifndef D_LightScheduler_H	
#define D_LightScheduler_H	
!
#include "TimeService.h"	
!
enum Day {	
NONE=-1, EVERYDAY=10, WEEKDAY, WEEKEND,	
SUNDAY=1, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY	
};	
!
typedef enum Day Day;	
!
void LightScheduler_Create();	
void LightScheduler_Destroy();	
void LightScheduler_ScheduleTurnOn(int id, Day day, int minute);	
void LightScheduler_ScheduleTurnOff(int id, Day day, int minute);	
void LightScheduler_ScheduleRemove(int id, Day day, int minute);	
void LightScheduler_Wakeup(Time*);	
!
#endif // D_LightScheduler_H
Data hidden in C
file using file
scope
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Multiple Instance Abstract Data Type
Clients Only Interact Through the Interface
54
#ifndef D_CircularBuffer_H	
#define D_CircularBuffer_H	
!
typedef struct CircularBuffer CircularBuffer;	
!
CircularBuffer * CircularBuffer_Create(int capacity);	
void CircularBuffer_Destroy(CircularBuffer);	
int CircularBuffer_IsEmpty(CircularBuffer);	
int CircularBuffer_IsFull(CircularBuffer);	
int CircularBuffer_Put(CircularBuffer, int);	
int CircularBuffer_Get(CircularBuffer);	
int CircularBuffer_Capacity(CircularBuffer);	
#endif // D_CircularBuffer_H	
instance
passed in
Public name,
hidden internals
instance
returned
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Multiple Instance ADT - .c File
Structure Fields are Private
55
#include "CircularBuffer.h"	
#include "Utils.h"	
#include <stdlib.h>	
#include <string.h>	
!
typedef struct CircularBuffer	
{	
int count;	
int index;	
int outdex;	
int capacity;	
int * values;	
} CircularBuffer;	
!
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Multiple Instance ADT - .c File
Well Defined Initialization and
Cleanup
56
CircularBuffer * CircularBuffer_Create(int capacity)	
{	
CircularBuffer * self = calloc(capacity,	
sizeof(CircularBuffer));	
self->capacity = capacity;	
self->values = calloc(capacity + 1, sizeof(int));	
self->values[capacity] = BUFFER_GUARD;	
return self;	
}	
!
void CircularBuffer_Destroy(CircularBuffer * self)	
{	
free(self->values);	
free(self);	
}
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Simple Dynamic Implementation
57
#ifndef D_RandomMinuteGenerator_H	
#define D_RandomMinuteGenerator_H	
!
void RandomMinuteGenerator_Create(int bound);	
extern int (*RandomMinuteGenerator_Get)();	
!
#endif // D_RandomMinuteGenerator_H	
function pointer
interface
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Inverting a Dependency with a
Function Pointer
58
LightScheduler
Random Minute Get
int (*RandomMinute_Get)()
<<implements>>
Random Minute Get
LightScheduler
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
#if Abuse
59
void LightController_TurnOn(int id)	
{	
LightDriver driver = lightDrivers[id];	
if (NULL == driver) return;	
!
#if X10_LIGHTS	
X10LightDriver_TurnOn(driver);	
#elif ACME_LIGHTS	
AcmeWirelessLightDriver_TurnOn(driver);	
#elif MEMORY_MAPPED_LIGHTS	
MemMappedLightDriver_TurnOn(driver);	
#elif TESTING	
LightDriverSpy_TurnOn(driver);	
#endif	
}
Similar #if
statements litter
the code. This
does not look too
DRY
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
switch case Abuse
60
void LightController_TurnOn(int id)	
{	
LightDriver driver = lightDrivers[id];	
if (NULL == driver) return;	
!
switch (driver->type)	
{	
case X10:	
X10LightDriver_TurnOn(driver);	
break;	
case AcmeWireless:	
AcmeWirelessLightDriver_TurnOn(driver);	
break;	
case MemoryMapped:	
MemMappedLightDriver_TurnOn(driver);	
break;	
case TestLightDriver:	
LightDriverSpy_TurnOn(driver);	
break;	
default:	
/* now what? */	
break;	
}	
}
Similar switch
cases litter the
code when
switching on type
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
LightController depends on Each
Specific LightDriver
61
LightScheduler
LightController
+ TurnOn()
+ TurnOff()
<<interface>>
LightController
X10
LightDriver
Acme Wireless
LightDriver
Memory Mapped
LightDriver
<<implements>>
LightDriver Spy
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
LightController Depends on the
LightDriver Interface
62
LightScheduler
LightController
+ TurnOn()
+ TurnOff()
<<interface>>
LightController
+ TurnOn()
+ TurnOff()
<<interface>>
LightDriver
X10
LightDriver
Acme Wireless
LightDriver
Memory Mapped
LightDriver
<<implements>>
LightDriver Spy
<<implements>>
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
How Much Flexibility is Needed?
• Support for one LightDriver at compile time?
– use the linker
• Support for one LightDriver type determined at
runtime?
– Use a function pointer interface
• Support for multiple LightDriver types determined at
runtime?
– Use per-type dynamic interface
63
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
LightDriver.h
64
typedef struct LightDriverStruct * LightDriver;	
!
void LightDriver_Destroy(LightDriver);	
void LightDriver_TurnOn(LightDriver);	
void LightDriver_TurnOff(LightDriver);	
const char * LightDriver_GetType(LightDriver driver);	
int LightDriver_GetId(LightDriver driver);	
!
!
#include "LightDriverPrivate.h"
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
LightDriverPrivate.h
65
typedef struct LightDriverInterfaceStruct *
LightDriverInterface;	
!
typedef struct LightDriverStruct	
{	
LightDriverInterface vtable;	
const char * type;	
int id;	
} LightDriverStruct;	
!
typedef struct LightDriverInterfaceStruct	
{	
void (*TurnOn)(LightDriver);	
void (*TurnOff)(LightDriver);	
void (*Destroy)(LightDriver);	
} LightDriverInterfaceStruct;
function pointer
table
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
X10LightDriver.h
66
#include "LightDriver.h"	
!
typedef struct X10LightDriverStruct * X10LightDriver;	
!
typedef enum X10_HouseCode {	
X10_A,X10_B,X10_C,X10_D,X10_E,X10_F,	
X10_G,X10_H,X10_I,X10_J,X10_K,X10_L,	
X10_M,X10_N,X10_O,X10_P } X10_HouseCode;	
!
LightDriver X10LightDriver_Create(int id, 	
X10_HouseCode code, 	
int unit);
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Extending LightDriver struct
(X10LightDriver.c)
67
//snip... 	
!
typedef struct X10LightDriverStruct	
{	
LightDriverStruct base;	
X10_HouseCode house;	
int unit;	
} X10LightDriverStruct;	
!
//snip... 	
All
LightDriver
instances must
start with the base
struct
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Initializing the vtable
(X10LightDriver.c)
68
static void turnOn(LightDriver super)	
{	
X10LightDriver self = (X10LightDriver)super;	
formatTurnOnMessage(self);	
sendMessage(self);	
}	
static void turnOff(LightDriver super)	
{	
X10LightDriver self = (X10LightDriver)super;	
formatTurnOffMessage(self);	
sendMessage(self);	
}	
static LightDriverInterfaceStruct interface =	
{	
turnOn,	
turnOff,	
destroy	
};
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Initializing a Driver
(X10LightDriver.c)
69
static LightDriverInterfaceStruct interface =	
{	
turnOn,	
turnOff,	
destroy	
};	
!
LightDriver X10LightDriver_Create(int id, X10_HouseCode house,	
int unit)	
{	
X10LightDriver self = 	
calloc(1, sizeof(X10LightDriverStruct));	
self->base.vtable = &interface;	
self->base.type = "X10";	
/* snip */	
return (LightDriver)self;	
}	
!
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Simple Version of
LightDriver_TurnOn()
70
void LightDriver_TurnOn(LightDriver self)	
{	
if (self)	
self->vtable->TurnOn(self);	
}	
The call is a bit hard to look
at, so it’s hidden in delegating
function behind an API.
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
C99 struct Initialization
71
static LightDriverInterfaceStruct interface =	
{	
.Destroy = destroy,	
.TurnOn = turnOn,	
.TurnOff = turnOff,	
};
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Really Safe Version of
LightDriver_TurnOn()
72
void LightDriver_TurnOn(LightDriver self)	
{	
if (self && self->vtable && self->vtable->TurnOn)	
self->vtable->TurnOn(self);	
}	
Combining safe function
dispatch with C99 struct
initialization means that not all
drivers have to support all
interface functions.
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
LightController uses the
LightDriver
!
!
!
!
!
• The switch case statement is gone! As well as all its
duplicates.
• Code reads top to bottom
• Special cases are isolated
73
void LightController_TurnOn(int id)	
{	
if (isIdInBounds(id))	
LightDriver_TurnOn(lightDrivers[id]);	
}
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Creating a Specific LightDriver
Using it Generically
74
LightDriver lightDriver;	
!
lightDriver = X10LightDriver_Create(3, X10_A, 12);	
!
LightDriver_TurnOn(lightDriver);	
LightDriver_TurnOff(lightDriver);	
LightDriver_Destroy(lightDriver);	
Create parameters are
customized for the specific driver
type. It returns the abstract type
Clients of the driver have no
dependency on the concrete type
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Dynamic Interfaces are Very
Convenient for Inserting Test
Doubles
!
!
!
75
// From LightDriverSpy.c	
!
static LightDriverInterfaceStruct interface =	
{	
.Destroy = LightDriverSpy_Destroy	
.TurnOn = LightDriverSpy_TurnOn,	
.TurnOff = LightDriverSpy_TurnOff,	
};
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Production Code is
Unaware of the Indirection
!
!
!
!
!
• LightDriver_TurnOn() indirectly calls the spy
76
TEST(LightDriverSpy, On) 	
{	
	 LightDriver lightDriverSpy = LightDriverSpy_Create(1);	
	 LightDriver_TurnOn(lightDriverSpy); 	
	 LONGS_EQUAL(LIGHT_ON, 	LightDriverSpy_GetState(1));	
}
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Function Pointer APIs
• One module operates on another module through a
function pointer table.
• Allows a whole set of functions to be swapped with a
single pointer change.
• Good for large systems with component variations
• Also good for updating or patching single
components
!
• Choose the simplest approach. Keep code readable.
77
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
Testability
• The function pointer based APIs allow test doubles to
be inserted at runtime.
• Legacy code that has function pointer APIs can be
easier to get into a test harness.
– Fill the function pointers with NULLs
– Run until crash to see which functions are accessed
– Add stubs as runtime dependencies are discovered
!
• All these design models employ programming to
interfaces and encapsulation
78
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
C++
• The use of function pointers and function pointer
tables does lead some to look at C++.
• C++ has this capability built in.
• Maybe you should look at C++.
!
!
• Why are you still using C?
– http://renaissancesoftware.net/papers/14-papers/51-stillusingc.html
79
www.wingman-sw.com
james@wingman-sw.com
Copyright © 2008-2014 James W. Grenning	

All Rights Reserved. For use by training attendees. ACCU 2014
80
Talk to me on Twitter
@jwgrenning
!
Connect with me on linkedin.com
http://www.linkedin.com/in/jwgrenning
Remind me how we met.
!
http://www.wingman-sw.com
http://blog.wingman-sw.com
http:// www.jamesgrenning.com
unpappd.com jwgrenning
Ask me for the
pragprog.com
discount code

More Related Content

What's hot

Exploratory Testing with JIRA | QASymphony Webinar
Exploratory Testing with JIRA | QASymphony WebinarExploratory Testing with JIRA | QASymphony Webinar
Exploratory Testing with JIRA | QASymphony WebinarQASymphony
 
Cultural learnings of testing for make benefit glorious nation of startup
Cultural learnings of testing for make benefit glorious nation of startupCultural learnings of testing for make benefit glorious nation of startup
Cultural learnings of testing for make benefit glorious nation of startupGil Tayar
 
What is quality, and how do we build it in
What is quality, and how do we build it in What is quality, and how do we build it in
What is quality, and how do we build it in Maryam Umar
 
How To Review The Sprints Efficiently
How To Review The Sprints EfficientlyHow To Review The Sprints Efficiently
How To Review The Sprints EfficientlyLemi Orhan Ergin
 
System-Level Test Automation: Ensuring a Good Start
System-Level Test Automation: Ensuring a Good StartSystem-Level Test Automation: Ensuring a Good Start
System-Level Test Automation: Ensuring a Good StartTechWell
 
Using JIRA for Risk Based Testing - QASymphony Webinar
Using JIRA for Risk Based Testing  - QASymphony WebinarUsing JIRA for Risk Based Testing  - QASymphony Webinar
Using JIRA for Risk Based Testing - QASymphony WebinarQASymphony
 
The Agile PMP - Pillar Technology
The Agile PMP - Pillar TechnologyThe Agile PMP - Pillar Technology
The Agile PMP - Pillar TechnologyMike Cottmeyer
 
Agile and Scrum for Video Game Development
Agile and Scrum for Video Game DevelopmentAgile and Scrum for Video Game Development
Agile and Scrum for Video Game DevelopmentMike Cohn
 
SLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.io
SLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.ioSLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.io
SLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.ioDevOpsDays Tel Aviv
 
Test Estimation Hacks: Tips, Tricks and Tools Webinar
Test Estimation Hacks: Tips, Tricks and Tools WebinarTest Estimation Hacks: Tips, Tricks and Tools Webinar
Test Estimation Hacks: Tips, Tricks and Tools WebinarQASymphony
 
Instill a DevOps Testing Culture in Your Team and Organization
Instill a DevOps Testing Culture in Your Team and Organization Instill a DevOps Testing Culture in Your Team and Organization
Instill a DevOps Testing Culture in Your Team and Organization TechWell
 
Agile and the Seven Sins of Project Management
Agile and the Seven Sins of Project ManagementAgile and the Seven Sins of Project Management
Agile and the Seven Sins of Project ManagementMike Cohn
 
Evolve or Die: Healthcare IT Testing | QASymphony Webinar
Evolve or Die: Healthcare IT Testing | QASymphony WebinarEvolve or Die: Healthcare IT Testing | QASymphony Webinar
Evolve or Die: Healthcare IT Testing | QASymphony WebinarQASymphony
 
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019Agile India
 
Continuous Delivery in a Legacy Shop - One Step at a Time
Continuous Delivery in a Legacy Shop - One Step at a TimeContinuous Delivery in a Legacy Shop - One Step at a Time
Continuous Delivery in a Legacy Shop - One Step at a TimeGene Gotimer
 
STARCANADA 2015: Lightning Strikes the Keynotes
STARCANADA 2015: Lightning Strikes the KeynotesSTARCANADA 2015: Lightning Strikes the Keynotes
STARCANADA 2015: Lightning Strikes the KeynotesTechWell
 
Build the Right Product Right: Transitioning Test from Critiquing to Defining
Build the Right Product Right: Transitioning Test from Critiquing to DefiningBuild the Right Product Right: Transitioning Test from Critiquing to Defining
Build the Right Product Right: Transitioning Test from Critiquing to DefiningTechWell
 
How testers add value to the organization appium conf
How testers add value to the organization  appium confHow testers add value to the organization  appium conf
How testers add value to the organization appium confCorina Pip
 
Bringing Continuous Delivery to the Enterprise: It's all about the Mindset
Bringing Continuous Delivery to the Enterprise: It's all about the MindsetBringing Continuous Delivery to the Enterprise: It's all about the Mindset
Bringing Continuous Delivery to the Enterprise: It's all about the MindsetGene Gotimer
 

What's hot (20)

Exploratory Testing with JIRA | QASymphony Webinar
Exploratory Testing with JIRA | QASymphony WebinarExploratory Testing with JIRA | QASymphony Webinar
Exploratory Testing with JIRA | QASymphony Webinar
 
Cultural learnings of testing for make benefit glorious nation of startup
Cultural learnings of testing for make benefit glorious nation of startupCultural learnings of testing for make benefit glorious nation of startup
Cultural learnings of testing for make benefit glorious nation of startup
 
What is quality, and how do we build it in
What is quality, and how do we build it in What is quality, and how do we build it in
What is quality, and how do we build it in
 
How To Review The Sprints Efficiently
How To Review The Sprints EfficientlyHow To Review The Sprints Efficiently
How To Review The Sprints Efficiently
 
System-Level Test Automation: Ensuring a Good Start
System-Level Test Automation: Ensuring a Good StartSystem-Level Test Automation: Ensuring a Good Start
System-Level Test Automation: Ensuring a Good Start
 
Using JIRA for Risk Based Testing - QASymphony Webinar
Using JIRA for Risk Based Testing  - QASymphony WebinarUsing JIRA for Risk Based Testing  - QASymphony Webinar
Using JIRA for Risk Based Testing - QASymphony Webinar
 
The Agile PMP - Pillar Technology
The Agile PMP - Pillar TechnologyThe Agile PMP - Pillar Technology
The Agile PMP - Pillar Technology
 
Agile and Scrum for Video Game Development
Agile and Scrum for Video Game DevelopmentAgile and Scrum for Video Game Development
Agile and Scrum for Video Game Development
 
SLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.io
SLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.ioSLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.io
SLO DRIVEN DEVELOPMENT, ALON NATIV, Tomorrow.io
 
Test Estimation Hacks: Tips, Tricks and Tools Webinar
Test Estimation Hacks: Tips, Tricks and Tools WebinarTest Estimation Hacks: Tips, Tricks and Tools Webinar
Test Estimation Hacks: Tips, Tricks and Tools Webinar
 
Instill a DevOps Testing Culture in Your Team and Organization
Instill a DevOps Testing Culture in Your Team and Organization Instill a DevOps Testing Culture in Your Team and Organization
Instill a DevOps Testing Culture in Your Team and Organization
 
Agile and the Seven Sins of Project Management
Agile and the Seven Sins of Project ManagementAgile and the Seven Sins of Project Management
Agile and the Seven Sins of Project Management
 
Evolve or Die: Healthcare IT Testing | QASymphony Webinar
Evolve or Die: Healthcare IT Testing | QASymphony WebinarEvolve or Die: Healthcare IT Testing | QASymphony Webinar
Evolve or Die: Healthcare IT Testing | QASymphony Webinar
 
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019
 
Continuous Delivery in a Legacy Shop - One Step at a Time
Continuous Delivery in a Legacy Shop - One Step at a TimeContinuous Delivery in a Legacy Shop - One Step at a Time
Continuous Delivery in a Legacy Shop - One Step at a Time
 
STARCANADA 2015: Lightning Strikes the Keynotes
STARCANADA 2015: Lightning Strikes the KeynotesSTARCANADA 2015: Lightning Strikes the Keynotes
STARCANADA 2015: Lightning Strikes the Keynotes
 
Build the Right Product Right: Transitioning Test from Critiquing to Defining
Build the Right Product Right: Transitioning Test from Critiquing to DefiningBuild the Right Product Right: Transitioning Test from Critiquing to Defining
Build the Right Product Right: Transitioning Test from Critiquing to Defining
 
How testers add value to the organization appium conf
How testers add value to the organization  appium confHow testers add value to the organization  appium conf
How testers add value to the organization appium conf
 
Bringing Continuous Delivery to the Enterprise: It's all about the Mindset
Bringing Continuous Delivery to the Enterprise: It's all about the MindsetBringing Continuous Delivery to the Enterprise: It's all about the Mindset
Bringing Continuous Delivery to the Enterprise: It's all about the Mindset
 
Year Zero
Year ZeroYear Zero
Year Zero
 

Similar to Designing SOLID C - ACCU Conference 2014

20210428 - Sustainable Engineering practices & API Communities: Adoption Best...
20210428 - Sustainable Engineering practices & API Communities: Adoption Best...20210428 - Sustainable Engineering practices & API Communities: Adoption Best...
20210428 - Sustainable Engineering practices & API Communities: Adoption Best...Angel Alberici
 
Mq light For Guide Share Europe 2014
Mq light For Guide Share Europe 2014Mq light For Guide Share Europe 2014
Mq light For Guide Share Europe 2014Robert Nicholson
 
Introduction to lean and agile
Introduction to lean and agileIntroduction to lean and agile
Introduction to lean and agileTerry Bunio
 
Se for cross industry presentation #1
Se for cross industry presentation #1Se for cross industry presentation #1
Se for cross industry presentation #1AIMFirst
 
Se for cross industry presentation #1
Se for cross industry presentation #1Se for cross industry presentation #1
Se for cross industry presentation #1AIMFirst
 
TCUK 2013 Presentation Adrian Warman
TCUK 2013 Presentation Adrian WarmanTCUK 2013 Presentation Adrian Warman
TCUK 2013 Presentation Adrian WarmanAdrian Warman
 
Bringing Partners, Teams & Systems Together through APIs
Bringing Partners, Teams & Systems Together through APIsBringing Partners, Teams & Systems Together through APIs
Bringing Partners, Teams & Systems Together through APIsApigee | Google Cloud
 
Streaming media east a204 lurie final
Streaming media east a204 lurie finalStreaming media east a204 lurie final
Streaming media east a204 lurie finalPeter Lurie
 
Automating "Network Ready for Use" with pytest
Automating "Network Ready for Use" with pytestAutomating "Network Ready for Use" with pytest
Automating "Network Ready for Use" with pytestJeremy Schulman
 
Starting out with Scrum
Starting out with ScrumStarting out with Scrum
Starting out with ScrumJoshua Partogi
 
SaltConf14 - Thomas Jackson, LinkedIn - Safety with Power Tools
SaltConf14 - Thomas Jackson, LinkedIn - Safety with Power ToolsSaltConf14 - Thomas Jackson, LinkedIn - Safety with Power Tools
SaltConf14 - Thomas Jackson, LinkedIn - Safety with Power ToolsSaltStack
 
Migration & upgrades best practice upgrade pathways to emc documentum 7
Migration & upgrades   best practice upgrade pathways to emc documentum 7Migration & upgrades   best practice upgrade pathways to emc documentum 7
Migration & upgrades best practice upgrade pathways to emc documentum 7Haytham Ghandour
 
Powersoft19 Overview - 2013
Powersoft19 Overview - 2013Powersoft19 Overview - 2013
Powersoft19 Overview - 2013Huzaifa Saadat
 
プロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメ
プロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメプロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメ
プロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメKeisuke Todoroki
 
Dave Kellogg Keynote at Host Analytics World 2013
Dave Kellogg Keynote at Host Analytics World 2013Dave Kellogg Keynote at Host Analytics World 2013
Dave Kellogg Keynote at Host Analytics World 2013Dave Kellogg
 
Strategies for Implementing Aras Innovator
Strategies for Implementing Aras InnovatorStrategies for Implementing Aras Innovator
Strategies for Implementing Aras InnovatorAras
 

Similar to Designing SOLID C - ACCU Conference 2014 (20)

20210428 - Sustainable Engineering practices & API Communities: Adoption Best...
20210428 - Sustainable Engineering practices & API Communities: Adoption Best...20210428 - Sustainable Engineering practices & API Communities: Adoption Best...
20210428 - Sustainable Engineering practices & API Communities: Adoption Best...
 
Mq light For Guide Share Europe 2014
Mq light For Guide Share Europe 2014Mq light For Guide Share Europe 2014
Mq light For Guide Share Europe 2014
 
Introduction to lean and agile
Introduction to lean and agileIntroduction to lean and agile
Introduction to lean and agile
 
Se for cross industry presentation #1
Se for cross industry presentation #1Se for cross industry presentation #1
Se for cross industry presentation #1
 
Se for cross industry presentation #1
Se for cross industry presentation #1Se for cross industry presentation #1
Se for cross industry presentation #1
 
TCUK 2013 Presentation Adrian Warman
TCUK 2013 Presentation Adrian WarmanTCUK 2013 Presentation Adrian Warman
TCUK 2013 Presentation Adrian Warman
 
IBM Agile ALM Overview
IBM Agile ALM OverviewIBM Agile ALM Overview
IBM Agile ALM Overview
 
Bringing Partners, Teams & Systems Together through APIs
Bringing Partners, Teams & Systems Together through APIsBringing Partners, Teams & Systems Together through APIs
Bringing Partners, Teams & Systems Together through APIs
 
Streaming media east a204 lurie final
Streaming media east a204 lurie finalStreaming media east a204 lurie final
Streaming media east a204 lurie final
 
Neil Potter Presentation
Neil Potter Presentation Neil Potter Presentation
Neil Potter Presentation
 
Vtug hybrid cloud
Vtug   hybrid cloudVtug   hybrid cloud
Vtug hybrid cloud
 
Automating "Network Ready for Use" with pytest
Automating "Network Ready for Use" with pytestAutomating "Network Ready for Use" with pytest
Automating "Network Ready for Use" with pytest
 
Starting out with Scrum
Starting out with ScrumStarting out with Scrum
Starting out with Scrum
 
SaltConf14 - Thomas Jackson, LinkedIn - Safety with Power Tools
SaltConf14 - Thomas Jackson, LinkedIn - Safety with Power ToolsSaltConf14 - Thomas Jackson, LinkedIn - Safety with Power Tools
SaltConf14 - Thomas Jackson, LinkedIn - Safety with Power Tools
 
Migration & upgrades best practice upgrade pathways to emc documentum 7
Migration & upgrades   best practice upgrade pathways to emc documentum 7Migration & upgrades   best practice upgrade pathways to emc documentum 7
Migration & upgrades best practice upgrade pathways to emc documentum 7
 
Powersoft19 Overview - 2013
Powersoft19 Overview - 2013Powersoft19 Overview - 2013
Powersoft19 Overview - 2013
 
プロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメ
プロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメプロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメ
プロトタイプでWeb制作の手戻りを減らせ!アドビ初のUI/UXデザインツール、Adobe XDのススメ
 
Dave Kellogg Keynote at Host Analytics World 2013
Dave Kellogg Keynote at Host Analytics World 2013Dave Kellogg Keynote at Host Analytics World 2013
Dave Kellogg Keynote at Host Analytics World 2013
 
Strategies for Implementing Aras Innovator
Strategies for Implementing Aras InnovatorStrategies for Implementing Aras Innovator
Strategies for Implementing Aras Innovator
 
AgileCamp 2015: Scrum for Full Scale Manufacturing, Joe Justice
AgileCamp 2015: Scrum for Full Scale Manufacturing, Joe JusticeAgileCamp 2015: Scrum for Full Scale Manufacturing, Joe Justice
AgileCamp 2015: Scrum for Full Scale Manufacturing, Joe Justice
 

Recently uploaded

Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 

Recently uploaded (20)

Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 

Designing SOLID C - ACCU Conference 2014

  • 1. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 SOLID C James Grenning Presented at ACCU 2014 Bristol, UK 1 Talk to me on Twitter @jwgrenning ! Connect with me on linkedin.com http://www.linkedin.com/in/jwgrenning Remind me how we met. ! http://www.wingman-sw.com http://blog.wingman-sw.com http:// www.jamesgrenning.com unpappd.com jwgrenning
  • 2. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 2 When is Software Design Finished?
  • 3. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 3 A Complex system that works is invariably found to have evolved from a simple system that worked.
  • 4. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 4 Red Green Refactor
  • 5. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Rules of Simple Design In Priority Order! 1. Passes all tests 2. No duplication 3. Expresses intent 4. Fewest classes and methods (no extra stuff) 5 Kent Beck [XP, TDD]
  • 6. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 6 Why is SoftwareValuable?
  • 7. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 ! • Functionality ! ! ! • Malleability 7 The Two Values of Software
  • 8. Red Green www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 8 Red Green Refactor
  • 9. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 9
  • 10. www.renaissancesoftware.net james@renaissancesoftware.net Copyright ©2008-2013 James W. Grenning All Rights Reserved. For use by training attendees. The End 10 Become an expert in your craft so you can advise your boss My Boss won’t let me
  • 11. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Design for Maintenance • Systems evolve, the design is NEVER done. • Automated tests make evolution safer. ! • Key technical practices for evolving design – Test Driven development – Refactoring – Modularity, Loose Coupling, High Cohesion
 (OO Design) 11
  • 12. Donald Knuth Says 12 ACCU 2014 www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. Let us change our traditional attitude to the construction of programs. Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.
  • 13. Martin Fowler Says 13 ACCU 2014 www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. Any fool can write code that the compiler understands, but it takes real skill to write code other programmers can understand. From “Refactoring - Improving the Design of Existing Code
  • 14. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Three Critical Skills 14 Recognize what is wrong and fix it!
  • 15. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 ! ! SOLID 15
  • 16. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Spaghetti Slide 16
  • 17. • Once a design problem is identified, you must envision a better solution • Look to apply the design principles – SOLID – DRY - Don’t Repeat Yourself –from The Pragmatic Programmer – Principle of Least Knowledge. – Separation of Concerns (SoC). Refactoring www.renaissancesoftware.net james@renaissancesoftware.net Copyright © 2008-2013 James W. Grenning All Rights Reserved. For use by training attendees. Envisioning 17
  • 18. Refactoring www.renaissancesoftware.net james@renaissancesoftware.net Copyright © 2008-2013 James W. Grenning All Rights Reserved. For use by training attendees. 18
  • 19. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 SOLID Design Principles 19
  • 20. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 SOLID Design Principles Single Responsibility Principle Open/Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle 20
  • 21. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Home Automation System Light Scheduling Requirements • The light scheduler maintains a schedule for lights that can be turned on or off. Multiple schedules per light are supported for each light. • A light can be scheduled to turn on. • A light can be scheduled to turn off. • 32 lights can be addressed by their integer ID. • It must support 128 separate scheduled events • Schedules can be established by – specific day of the week (M Tu W Th F Sa Su), or everyday. • Lights can also be controlled though a UI on a front panel, iPad, iPhone, Android device, or web enabled device. 21
  • 22. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 22
  • 23. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Spaghetti Slide 23
  • 24. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Single Responsibility Principle Bob Martin [AGILE] • a.k.a. Cohesion ! • A module should do one thing and do it well. • A module should have a single reason to change. ! • Test: a module can be described in 25 words or less. 24
  • 25. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 25
  • 26. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 A Module with Collaborators • Every minute, the RTOS wakes up the Light Scheduler. • If it is time for one of the lights to be controlled, the LightController is told to turn on/off the light. 26 Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler +ScheduleTurnOn() +RemoveSchedule() +WakeUp() Light Controller + On(id) + Off(id) Hardware RTOS <<anonymous callback>> Admin Console
  • 27. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 27
  • 28. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Open/Closed Principle • A module is open for extension, and closed for modification. • A design adheres to the open closed principle when it accommodates a certain kinds of changes without having to change existing code. • Changes just drop in. ! • Say “X is open for extension for new kinds of Ys, but closed for modification” 28 Thanks: Bertrand Meyers
  • 29. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 OCP Applied LightScheduler is open for extension for new kinds of LightControllers and TimeServices. ! It is closed for modification for those extensions. 29 <<interface>> Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler + ScheduleTurnOn() + RemoveSchedule() +WakeUp() <<interface>> Light Controller + On(id) + Off(id) X10 Light Controller Acme Time Service Admin Console Model 42 Light Controller Linux Time Service <<implements>> <<implements>>
  • 30. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 30
  • 31. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Liskov Substitution Principle • Modules with the same interface can be substituted without the client knowing the difference. – Modules must meet the contract of the client and interface. – Preconditions cannot be strengthened in a server. – Postconditions cannot be weakened in a server. 31 Thanks: Barbara Liskov
  • 32. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 32 © James Barrante. This file is licensed under the Creative Commons Attribution 3.0 Unported license.
  • 33. OS Abstraction typedef struct ThreadStruct * Thread; typedef void * (*ThreadEntryFunction)(void *); ! Thread Thread_Create(ThreadEntryFunction f, void * parameter); void Thread_Start(Thread); void Thread_Destroy(Thread); void Thread_Exit(void *); void Thread_Join(Thread, void **result); void * Thread_Result(Thread); 33 ACCU 2014 www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees.
  • 34. OS Abstraction is Not Working //Snip from some product code ! Thread thread = Thread_Create(threadEntry, 0); ! #if POSIX_OS //POSIX starts thread on create #else //AcmeOS does not start thread on create Thread_Start(thread); #endif 34 ACCU 2014 www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees.
  • 35. OCP/LSP Designs Don’t Burden the Client //Snip from some product code ! Thread thread = Thread_Create(threadEntry, 0); Thread_Start(thread); 35 ACCU 2014 www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees.
  • 36. POSIX Version Delays Thread Creation typedef struct ThreadStruct { ThreadEntryFunction entry; void * parameter; pthread_t pthread; BOOL started; ! } ThreadStruct; ! Thread Thread_Create(ThreadEntryFunction f, void * parameter) { Thread self = calloc(1, sizeof(ThreadStruct)); self->entry = f; self->parameter = parameter; self->started = FALSE;; return self; } ! void Thread_Start(Thread self) { self->started = TRUE; pthread_create(&self->pthread, NULL, self->entry, self->parameter); } 36 ACCU 2014 www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees.
  • 37. Acme Does Not Need To Delay Create typedef struct ThreadStruct { AcmeThreadStruct acmeThread; } ThreadStruct; ! Thread Thread_Create(ThreadEntryFunction entry, void * parameter) { Thread self = calloc(1, sizeof(ThreadStruct)); AcmeThread_create(&self->acmeThread, entry, parameter, 5, 1000); return self; } ! void Thread_Start(Thread self) { AcmeThread_start(&self->acmeThread); } 37 ACCU 2014 www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees.
  • 38. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Interface Segregation Principle • Don’t depend on fat interfaces. • Don’t depend on interfaces that have methods you don’t care about. • Tailor interfaces to client need. • Split fat interfaces. 38 Thanks: Robert Martin
  • 39. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Light Scheduler Design • The TimeService limits the knowledge of the RTOS ! • Adapters are a form of Interface Segregations 39 <<interface>> Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler + AddTurnOn() + RemoveSchedule() +WakeUp() <<interface>> Light Controller + On(id) + Off(id) Model 42 Hardware RTOS <<anonymous callback>> Model 42 Light Controller RTOS Time Service <<implements>> <<implements>> Admin Console
  • 40. Third Party Code Your Code Your Code Your Code Third Party Code Your Code Your Code Your Code www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Manage Third Party Dependenices 40 Your Tailored Service Interface Your Code Your Code Your Code Third Party Code Your adaptor
  • 41. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Dependency Inversion Principle • Invert dependencies from high level modules to low level details. • Break problem dependencies by inserting an abstraction. – High level detail depends on an interface – Low level code depends on the interface – Interface depends on neither – Dependency cycle • a.k.a. Depend on Abstractions 41 Thanks: Robert Martin
  • 42. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Un-Managed Dependencies • Transitive dependencies make the highest level of this design depend on the lowest level details. ! • Use DIP to break the transitive dependency chain. 42 Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler +ScheduleTurnOn() +RemoveSchedule() +WakeUp() Light Controller + On(id) + Off(id) Hardware RTOS <<anonymous callback>> Admin Console
  • 43. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Invert Dependencies with Interfaces 43 <<interface>> Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler + ScheduleTurnOn() + RemoveSchedule() +WakeUp() <<interface>> Light Controller + On(id) + Off(id) Model 42 Hardware RTOS <<anonymous callback>> Model 42 Light Controller RTOS Time Service <<implements>> <<implements>> Admin Console
  • 44. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Unmanaged Dependencies Lead to Manual Testing 44 The Net Core Software
  • 45. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Substitutability Supports Testing 45 <<interface>> Time Service + GetTime() + SetPeriodicAlarm() Light Scheduler Test Light Scheduler + ScheduleTurnOn() + RemoveSchedule() +wakeUp() <<interface>> Light Controller + On(id) + Off(id) Light Controller Spy Fake Time Service <<implements>> <<implements>>
  • 46. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Interfaces in C • Containing just what is needed to interact with the module – Function declarations – Constants needed for interacting with the module – struct forward declaration ! • Things not in the interface header file – Data structure member definitions – Data definitions – Constants needed in the implementation 46
  • 47. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Rules of Simple Design In Priority Order! 1. Passes all tests 2. No duplication 3. Expresses intent 4. Fewest classes and methods (no extra stuff)* 47 Kent Beck [XP, TDD]
  • 48. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 *Fewest Classes and Methods that Move You Closer to A Workable Architecture 48
  • 49. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Architectural Vision • Have an idea where you are going. • Build slices of functionality that lets you try the architecture. • Don’t build architecture first, get features working and refactor to a great architecture. • Keep architectural view high level. 49
  • 50. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Architectural Vision The Big Picture • Have a big picture in the developers’ minds. • The vision shows – the major boundaries – the areas of concern – the interfaces • Likely fractal in nature 50
  • 51. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 SOLID and Testable C 51
  • 52. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Different Design Models in C 52 Model Purpose Single-instance ! Abstract Data Type Encapsulates a module’s internal state when only a single instance of the module is needed Multiple-instance ! Abstract Data Type Encapsulates a module’s internal state and allows multiple instances of the module’s data Dynamic interface Allows a module’s interface functions to be assigned at runtime Per-type dynamic Interface Allows multiple types of modules with the same interface to have unique interface functions Barbara Liskov, Programming with abstract data types. Proceedings of the ACM SIGPLAN Symposium on Very High Level Languages, 1974.
  • 53. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Single Instance Abstract Data Type ! 53 #ifndef D_LightScheduler_H #define D_LightScheduler_H ! #include "TimeService.h" ! enum Day { NONE=-1, EVERYDAY=10, WEEKDAY, WEEKEND, SUNDAY=1, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }; ! typedef enum Day Day; ! void LightScheduler_Create(); void LightScheduler_Destroy(); void LightScheduler_ScheduleTurnOn(int id, Day day, int minute); void LightScheduler_ScheduleTurnOff(int id, Day day, int minute); void LightScheduler_ScheduleRemove(int id, Day day, int minute); void LightScheduler_Wakeup(Time*); ! #endif // D_LightScheduler_H Data hidden in C file using file scope
  • 54. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Multiple Instance Abstract Data Type Clients Only Interact Through the Interface 54 #ifndef D_CircularBuffer_H #define D_CircularBuffer_H ! typedef struct CircularBuffer CircularBuffer; ! CircularBuffer * CircularBuffer_Create(int capacity); void CircularBuffer_Destroy(CircularBuffer); int CircularBuffer_IsEmpty(CircularBuffer); int CircularBuffer_IsFull(CircularBuffer); int CircularBuffer_Put(CircularBuffer, int); int CircularBuffer_Get(CircularBuffer); int CircularBuffer_Capacity(CircularBuffer); #endif // D_CircularBuffer_H instance passed in Public name, hidden internals instance returned
  • 55. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Multiple Instance ADT - .c File Structure Fields are Private 55 #include "CircularBuffer.h" #include "Utils.h" #include <stdlib.h> #include <string.h> ! typedef struct CircularBuffer { int count; int index; int outdex; int capacity; int * values; } CircularBuffer; !
  • 56. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Multiple Instance ADT - .c File Well Defined Initialization and Cleanup 56 CircularBuffer * CircularBuffer_Create(int capacity) { CircularBuffer * self = calloc(capacity, sizeof(CircularBuffer)); self->capacity = capacity; self->values = calloc(capacity + 1, sizeof(int)); self->values[capacity] = BUFFER_GUARD; return self; } ! void CircularBuffer_Destroy(CircularBuffer * self) { free(self->values); free(self); }
  • 57. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Simple Dynamic Implementation 57 #ifndef D_RandomMinuteGenerator_H #define D_RandomMinuteGenerator_H ! void RandomMinuteGenerator_Create(int bound); extern int (*RandomMinuteGenerator_Get)(); ! #endif // D_RandomMinuteGenerator_H function pointer interface
  • 58. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Inverting a Dependency with a Function Pointer 58 LightScheduler Random Minute Get int (*RandomMinute_Get)() <<implements>> Random Minute Get LightScheduler
  • 59. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 #if Abuse 59 void LightController_TurnOn(int id) { LightDriver driver = lightDrivers[id]; if (NULL == driver) return; ! #if X10_LIGHTS X10LightDriver_TurnOn(driver); #elif ACME_LIGHTS AcmeWirelessLightDriver_TurnOn(driver); #elif MEMORY_MAPPED_LIGHTS MemMappedLightDriver_TurnOn(driver); #elif TESTING LightDriverSpy_TurnOn(driver); #endif } Similar #if statements litter the code. This does not look too DRY
  • 60. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 switch case Abuse 60 void LightController_TurnOn(int id) { LightDriver driver = lightDrivers[id]; if (NULL == driver) return; ! switch (driver->type) { case X10: X10LightDriver_TurnOn(driver); break; case AcmeWireless: AcmeWirelessLightDriver_TurnOn(driver); break; case MemoryMapped: MemMappedLightDriver_TurnOn(driver); break; case TestLightDriver: LightDriverSpy_TurnOn(driver); break; default: /* now what? */ break; } } Similar switch cases litter the code when switching on type
  • 61. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 LightController depends on Each Specific LightDriver 61 LightScheduler LightController + TurnOn() + TurnOff() <<interface>> LightController X10 LightDriver Acme Wireless LightDriver Memory Mapped LightDriver <<implements>> LightDriver Spy
  • 62. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 LightController Depends on the LightDriver Interface 62 LightScheduler LightController + TurnOn() + TurnOff() <<interface>> LightController + TurnOn() + TurnOff() <<interface>> LightDriver X10 LightDriver Acme Wireless LightDriver Memory Mapped LightDriver <<implements>> LightDriver Spy <<implements>>
  • 63. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 How Much Flexibility is Needed? • Support for one LightDriver at compile time? – use the linker • Support for one LightDriver type determined at runtime? – Use a function pointer interface • Support for multiple LightDriver types determined at runtime? – Use per-type dynamic interface 63
  • 64. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 LightDriver.h 64 typedef struct LightDriverStruct * LightDriver; ! void LightDriver_Destroy(LightDriver); void LightDriver_TurnOn(LightDriver); void LightDriver_TurnOff(LightDriver); const char * LightDriver_GetType(LightDriver driver); int LightDriver_GetId(LightDriver driver); ! ! #include "LightDriverPrivate.h"
  • 65. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 LightDriverPrivate.h 65 typedef struct LightDriverInterfaceStruct * LightDriverInterface; ! typedef struct LightDriverStruct { LightDriverInterface vtable; const char * type; int id; } LightDriverStruct; ! typedef struct LightDriverInterfaceStruct { void (*TurnOn)(LightDriver); void (*TurnOff)(LightDriver); void (*Destroy)(LightDriver); } LightDriverInterfaceStruct; function pointer table
  • 66. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 X10LightDriver.h 66 #include "LightDriver.h" ! typedef struct X10LightDriverStruct * X10LightDriver; ! typedef enum X10_HouseCode { X10_A,X10_B,X10_C,X10_D,X10_E,X10_F, X10_G,X10_H,X10_I,X10_J,X10_K,X10_L, X10_M,X10_N,X10_O,X10_P } X10_HouseCode; ! LightDriver X10LightDriver_Create(int id, X10_HouseCode code, int unit);
  • 67. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Extending LightDriver struct (X10LightDriver.c) 67 //snip... ! typedef struct X10LightDriverStruct { LightDriverStruct base; X10_HouseCode house; int unit; } X10LightDriverStruct; ! //snip... All LightDriver instances must start with the base struct
  • 68. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Initializing the vtable (X10LightDriver.c) 68 static void turnOn(LightDriver super) { X10LightDriver self = (X10LightDriver)super; formatTurnOnMessage(self); sendMessage(self); } static void turnOff(LightDriver super) { X10LightDriver self = (X10LightDriver)super; formatTurnOffMessage(self); sendMessage(self); } static LightDriverInterfaceStruct interface = { turnOn, turnOff, destroy };
  • 69. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Initializing a Driver (X10LightDriver.c) 69 static LightDriverInterfaceStruct interface = { turnOn, turnOff, destroy }; ! LightDriver X10LightDriver_Create(int id, X10_HouseCode house, int unit) { X10LightDriver self = calloc(1, sizeof(X10LightDriverStruct)); self->base.vtable = &interface; self->base.type = "X10"; /* snip */ return (LightDriver)self; } !
  • 70. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Simple Version of LightDriver_TurnOn() 70 void LightDriver_TurnOn(LightDriver self) { if (self) self->vtable->TurnOn(self); } The call is a bit hard to look at, so it’s hidden in delegating function behind an API.
  • 71. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 C99 struct Initialization 71 static LightDriverInterfaceStruct interface = { .Destroy = destroy, .TurnOn = turnOn, .TurnOff = turnOff, };
  • 72. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Really Safe Version of LightDriver_TurnOn() 72 void LightDriver_TurnOn(LightDriver self) { if (self && self->vtable && self->vtable->TurnOn) self->vtable->TurnOn(self); } Combining safe function dispatch with C99 struct initialization means that not all drivers have to support all interface functions.
  • 73. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 LightController uses the LightDriver ! ! ! ! ! • The switch case statement is gone! As well as all its duplicates. • Code reads top to bottom • Special cases are isolated 73 void LightController_TurnOn(int id) { if (isIdInBounds(id)) LightDriver_TurnOn(lightDrivers[id]); }
  • 74. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Creating a Specific LightDriver Using it Generically 74 LightDriver lightDriver; ! lightDriver = X10LightDriver_Create(3, X10_A, 12); ! LightDriver_TurnOn(lightDriver); LightDriver_TurnOff(lightDriver); LightDriver_Destroy(lightDriver); Create parameters are customized for the specific driver type. It returns the abstract type Clients of the driver have no dependency on the concrete type
  • 75. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Dynamic Interfaces are Very Convenient for Inserting Test Doubles ! ! ! 75 // From LightDriverSpy.c ! static LightDriverInterfaceStruct interface = { .Destroy = LightDriverSpy_Destroy .TurnOn = LightDriverSpy_TurnOn, .TurnOff = LightDriverSpy_TurnOff, };
  • 76. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Production Code is Unaware of the Indirection ! ! ! ! ! • LightDriver_TurnOn() indirectly calls the spy 76 TEST(LightDriverSpy, On) { LightDriver lightDriverSpy = LightDriverSpy_Create(1); LightDriver_TurnOn(lightDriverSpy); LONGS_EQUAL(LIGHT_ON, LightDriverSpy_GetState(1)); }
  • 77. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Function Pointer APIs • One module operates on another module through a function pointer table. • Allows a whole set of functions to be swapped with a single pointer change. • Good for large systems with component variations • Also good for updating or patching single components ! • Choose the simplest approach. Keep code readable. 77
  • 78. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 Testability • The function pointer based APIs allow test doubles to be inserted at runtime. • Legacy code that has function pointer APIs can be easier to get into a test harness. – Fill the function pointers with NULLs – Run until crash to see which functions are accessed – Add stubs as runtime dependencies are discovered ! • All these design models employ programming to interfaces and encapsulation 78
  • 79. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 C++ • The use of function pointers and function pointer tables does lead some to look at C++. • C++ has this capability built in. • Maybe you should look at C++. ! ! • Why are you still using C? – http://renaissancesoftware.net/papers/14-papers/51-stillusingc.html 79
  • 80. www.wingman-sw.com james@wingman-sw.com Copyright © 2008-2014 James W. Grenning All Rights Reserved. For use by training attendees. ACCU 2014 80 Talk to me on Twitter @jwgrenning ! Connect with me on linkedin.com http://www.linkedin.com/in/jwgrenning Remind me how we met. ! http://www.wingman-sw.com http://blog.wingman-sw.com http:// www.jamesgrenning.com unpappd.com jwgrenning Ask me for the pragprog.com discount code