6/7/2010
Instructor: Robert Martin
a discussion on determining the size of the galaxy using globular clusters and variable stars
a discussion on programming languages
C > Java > ruby > functional languages (f#, scala, closure)
functional languages: scalable/multiple threads: moore's law has died
no locking problems
why are all our languages OO?
What can OO do that C cant?
OO is a way to manage dependencies between pieces of source code
polymorphism allows us to invert the dependency of modules
you can do this in C with function pointers, but it's dangerous
Structured Programming - Djikstra "goto may be considered harmful"
discipline applied to direct forms of control - structured
discipline applied to indirect forms of control - OO
What causes rotten software? Complexity
Fragility: breaks easily, can't anticipate consequences of a change
Rigidity: Every change forces a host of other changes
Reusability: desirable things that a module does cant be untangled from the undesirable things. It's too easy to make dependencies on things we don't need
All these things are brought about by bad dependencies
Case study: copy routine
copy characters from the keyboard to the printer
copy depends on keyboard/printer
flow of control flows with dependencies:
void copy() {
int c;
while((c=kbd()!=EOF) print(c);
}
later... add support for other input/output devices
flow of control goes opposite of dependencies:
void copy() {
int c;
while(c=getchar()!=eof) putchar(c);
}
getchar/putchar uses stdin/stdout by default
it can be maintained because "the code can already do that"
Single Responsibility Principle
A class should only have 1 reason to change
Group together things that change for the same reasons
Separate things that change for different reasons
Open/Closed Principle
Add new functionality by adding new code, not editing old code
A module should be open for extension but closed for modification
A discussion on measuring the distance to the sun
What do you do when your abstractions get in the way?
the wrong abstractions cannot protect you from unanticipated changes
Agility can be a strategy to protect you: put in almost no abstractions at first
Show code to customer as early as possible and reactively add abstractions
This is a strategy but it is not perfect
One of the keys to making OO software work is TDD
Nothing makes a system more flexible than a suite of tests (by an order of magnitude)
If you have a bad design, and a suite of tests, you are not afraid to improve the design
Therefore tests are more important than a good design
QA should be writing acceptance tests at a high level (at the frontend of the dev process)
Developers should be writing unit tests at a lower level as development progresses
Liskov Substitution Principle
All derived classes must be substitutable for their base classes
Every substitution violation eventually leads to an open/closed violation
Inheritance does not mean "is a"
Inheritance means the variables/functions of the base class are redefined in the inherited class
The fact that a square is a rectangle does not mean that the square inherits from a rectangle
Taking behavior away from the base class is the core problem. The user has a right to expect that behavior.
Dependency Inversion Principle
OO programs are programs where the flow of control is opposed by the source code dependencies
OO programs protect you from the creation of new derivative types
When you add new functions to the hierarchy, the user is not protected
When you add new data structures/types to the hierarchy, the user is protected
Procedural programs protect you from the creation of new functions
When you add new functions to the hierarchy, the user is not protected
When you add new data structures/types to the hierarchy, the user is protected
Dependency Inversion principle:
If A depends on B: B should be abstract
Java: interfaces
C++: pure virtual functions
Can you really do that all the time? no. (for example can't "new" an abstract class.)
Discussion of smalltalk vs C++ re:type-safety
TDD can replace type-safety (dont need the compiler to check, the tests can check)
This led to Ruby/Python
Whats bad about overriding a function that has an implementation?
Should be adding functionality, not taking away
If you depend on a derived class, you depend on everything the base class depends on
Inheritance is a very strong relationship: use with care
But inheritance is what gives us polymorphism, which allows this dependency inversion
This is why you should inherit from abstract classes to reduce the dependencies
Other languages (python/ruby) can do polymorphism without inheritance. This makes python/ruby code much easier to write.
A definition of a programmer is someone who is constantly learning. Every programmer should learn a new language every year just on principle.
This class is actually principles for statically typed OO languages (java/C++). The same principles apply in other languages, but in different ways.
"All solutions are short term"
Thinks Ruby is the next language to crest, then closure
Discussion on where gold comes from? Supernovas
Interface Segregation Principle
A fat class is a class with many methods and many users. A new user comes along and wants to add a new function to the fat class. All the other users get the new function too, so you have a massive recompilation and deployment.
Find groupings of methods that are only used by certain users. Create abstract interface clsses for each grouping. Have the fat class multiply inherit from the abstract interface classes.
Design is about manipulating code: if you can't envision the code you are not doing design
Comments are lies: they are far away from the things that they describe
Comments: only write them if you have to. Comments are a failure to make yourself clear in the code.
The worst kind of comment is commented-out code. The old code is in the VCS, if you need it you can go get it.
Functions should be max 4-5 lines long
Journalists work with the rule that the most important stuff should be at the top. Each line is more and more detailed. Code should be organized the same way so that it is easy to read/understand.
How many arguments should be passed into a function? Zero is best. Three is getting tough. If you are passing 5 things, you should probably be passing an object.
The worst thing you can pass into a function is a bool: you are announcing that the function does two things. Split it into two functions
Catching output in arguments is also bad, forces reader to do a doubletake
Subscribe to:
Post Comments (Atom)
"QA should be writing acceptance tests at a high level (at the frontend of the dev process). Developers should be writing unit tests at a lower level as development progresses."
ReplyDeleteAmen
"A definition of a programmer is someone who is constantly learning. Every programmer should learn a new language every year just on principle."
Amen x 2
"The worst kind of comment is commented-out code. The old code is in the VCS, if you need it you can go get it."
Amen x 3 million