The Object Oriented Paradigm in perspective
-
Upload
ruben-gonzalez-blanco -
Category
Software
-
view
176 -
download
0
Transcript of The Object Oriented Paradigm in perspective
The Object Oriented Paradigm in perspec2ve :
From Plato and Aristotle to Alan Kay.. and beyond
Ruben Gonzalez Blanco Nov 2013
Most of our OOP soPware is “Platonic”
CLASS
Object1 Object2 Object3
Create Object
INTERFACE
Run4me World
Design&Coding World
First the Code, then the Objects
Interface Shape { draw(Canvas c); move(int x, int y); }
class Circle implements Shape { // a:ributes int cx; int cy; int radius; // implementa>on draw(Canvas c) { c.drawEllipse(cx,cy, r); } move(int x, int y) { cx = cx+x; cy =cy+y } setC(int x, int y) { cx=x; cy=y; } setR(int radious) { r=radious; } }
Main() { Circle s1 = new Circle(); s1.setC(100,50) s1.setR(20); Canvas c = new DefaultCanvas(); c.addShape(s1); // registered as Shape c.show(); }
���$��� ������
������
a"rributes*
memory&
'�
'�
'�
�����������$��������!�� ����#� ����#��
draw()*implementa3on*
�%� ����&�
��������
��#����
�!���!�����
�!�����" ���
���� ������
������
opera3ons*table*
'�
����"����������� ����
Design& Coding World Run4me World
The Forms Theory from Aristotle Only 1 World = Sensi4ve World
Concepts or Forms = Abstrac4ons
Horse Form
Mammal Form
Abstrac4on
(extract the general from the par2cular)
(in our minds)
Form Theory from Aristotle
Substance
Form Physical Ma`er
Accidents
(Thing)
(Idea)
(thing proper4es varia4ons)
• Forms can have different levels of abstrac2ons • Ma`er can disappear, Forms persist
OOP and Form Theory
Substance
Form Physical Ma`er
Accidents
(Thing)
(Idea)
Object
Class “Electronic” Ma`er (Object in the Computer Memory, processed
by the CPU)
State (Object aKributes=status varia4ons)
Interface
(thing proper4es varia4ons)
code
code
(Abstrac4on) (Abstrac4on)
(Abstrac4on)
Sensible World Run4me World
“Aristotelic” view of OOP: What it really ma`ers are the Objects
Interface Shape {
draw(Canvas c);
move(int x, int y);
}
class Circle implements Shape {
// a$ributes
int cx;
int cy;
int radius;
// implementa0on
draw(Canvas c) {
c.drawEllipse(cx,cy, r);
}
move(int x, int y) {
cx = cx+x;
cy =cy+y
}
setC(int x, int y) {
cx=x;
cy=y;
}
setR(int radious) {
r=radious;
}
}
draw()
move()
_Line_draw()
_Line_move()
X1=100
Y1=100
X2=100
Y2=200
draw()
move()
_Circle_draw()
_Circle_move()
Cx=80
Cy=90
R=50
show()
addShape()
removeShape()
_DefaultCanvas_show()
…
shapes=[s1]
c1:DefaultCanvas
onMousePressed()
onMouseMoved()
onMouseReleased()
_CircleTool_onMouseReleased()
…
canvas=c1
..
:CircleTool
draw()
move()
_Circle_draw()
_Circle_move()
Cx=80
Cy=90
R=50
draw()
move()
_Circle_draw()
_Circle_move()
Cx=80
Cy=90
R=50
onMouseReleased(MouseEvent mevent) {
//..get radious from mevent posi3on
r = ….
Circle circle = new Circle();
circle.setC(x,y);
circle.setR(r);
// registered as Shape
canvas.addShape(circle);
}
App=Run4me World Design & Coding World
OOP by Alan Kay
"OOP to me means only messaging, local reten4on and protec4on and hiding of state-‐process, and extreme late-‐binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them." -‐ Dr. Alan Kay
Objects in OOP are “like” Cells
I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages (so messaging came at the very beginning -‐-‐ it took a while to see how to do messaging in a programming language efficiently enough to be useful).
h`p://www.purl.org/stefan_ram/pub/doc_kay_oop_en
A “primi2ve” form of object
h`p://www.smalltalk.org/smalltalk/TheEarlyHistoryOfSmalltalk_Abstract.html
Dr. Alan Kay OOP realiza2on : Smalltalk Smalltalk is a founda2onal programming language that is based on pervasive message passing, pervasive dynamic and strong typing, pervasive reflec4on and pervasive object orienta4on.
h`p://www.smalltalk.org/ar2cles/ar2cle_20100320_a3_Gekng_The_Message.html
Smalltalk is one of the first object-‐oriented programming languages. Its design was influenced by Lisp, Logo, Sketchpad, Flex and Simula. Smalltalk was developed as a research project at Xerox PARC in the 1970s by a team whose members included Dr. Alan Kay, Dan Ingalls, Adele Goldberg, Ted Kaehler, [Dianna Merry-‐Shipiro], Sco` Wallace and others.
An Object is a run4me en4ty that processes messages using dynamic binding
Message
Dynamic Binding = Late Binding
Binding mechanism
Message
Object
Message processor Implementa2on
Data A`ributes=State
Opera2ons Realiza2on
A`ributes Interface Opera2ons Specifica2on
Class
Data
Dynamic Binding
Message
Binding mechanism
Binding mechanism
Message processor Implementa4on
Data A`ributes=State
Data
At run-‐2me 1
2
3
Dynamic Binding = Late Binding
Binding mechanism
Message processor Implementa4on
Data A`ributes=State
Data
Not Bound 1
Dynamic Binding = Late Binding
Binding mechanism
Message processor Implementa4on
Data A`ributes=State
Data
Binding mechanism
Message processor Implementa4on
Data A`ributes=State
Data
Message
Not Bound
Linked when the message is received
1
2
• Implementa2on is bound in the last moment • (when a message is received)
The same object can change its implementa2on between messages recep2on
Binding mechanism
Object2
Message processor Implementa2on
Data A`ributes=State
Data
Object1
1
The same object can change its implementa2on between messages recep2on
Binding mechanism
Object2
Message processor Implementa2on
Data A`ributes=State
Data
Binding mechanism
Object2
Message processor Implementa2on
Data A`ributes=State
Data
Object1
Object1
1
2
An object can interact with different Implementa2ons of the same interface
Binding mechanism
Object2
Message processor Implementa2on
Data A`ributes=State
Binding mechanism
Object3
Message processor Implementa2on
Data A`ributes=State
Data
Data
Object1
• Same “Interface” and different implementa2on • Implementa2on can vary at run2me • Flexibility = easily recombine exis2ng objects into new configura2ons • Extensibility = easily add new behaviours
Polymorphism and Encapsula2on
Binding mechanism
Message processor Implementa4on
Data A`ributes=State
Data
INTERFACE (specifica2on)
Mul2ple muta2ons of the same “Thing” Same object instance with varia2ons in its implementa2on Same specifica2on (interface) with different instances realiza2ons
IMPLEMENTATION1 (realiza2on)
Binding mechanism
Message processor Implementa4on
Data A`ributes=State
Data
IMPLEMENTATION2 (realiza2on)
Hidden
The “P” in OOP is misleading
OOP is a Computa4onal Model Not a Programming Model
Can be implemented in different programming languages
Most of the “modern” so called OO languages (C++, Java, …) are more focused on the Programming part than the Computa2onal part (the run2me objects)
Interface Class Inheritance
Messages Object Late Binding
Design & Coding Time Run4me Processing
Plato Aristotle
The Post-‐World
aPostboxObject
Ann
aPostBoxObject
Teacher Postbox (abstract or representa>on box)
slot Interface
How it is seen by other postBoxObjects (only the interface is seen, not the implementa>on)
As a Teacher implementa>on
Abstract Form
slot
teachLesson
Dynamic binding
A C++,Java like “Typed” Post-‐World would be also possible, but would be “less” OO (less polymorphic) and more complicated to deal with
Teacher
answerQues2on
teachLesson
Teacher
aTapeRecorder exposed/referenced as a Teacher
TapeRecorderTeacher
teachLesson
answerQues2on
play
stop
forward
rewind
aTapeRecorder exposed/referenced as TapeRecoderTeacher
teachLesson
answerQues2on
play
stop
forward
rewind
concrete slots are hidden Referenced as Teacher
Teacher
• Type=“slots Interface” is hardcoded. • Different slots are presented in different situa2ons (type cas2ng) • To be “more” OO polymorphic, objects always try to present themselves as the most abstract type possible
Dynamic Binding is present in many places
• func2on pointers in C and C++
• DLLs and Shared Objects
• “CGI” like mechanism in HTTP servers
• GUIs
…
For origins of dynamic binding: “Fundamental Concepts in Programming Languages”. CHRISTOPHER STRACHEY -‐ 1967
Dynamic Binding is present in many places a basic example in C
typedef int (*foo)(int i);!
int fooImp1(int i ) {! return 2*i;!}!!int fooImp2(int i ) {! return i/2;!}!!void doFoo(int i,foo afoo) {!! int r = afoo(i);!! printf (“result=%d\n”,r);!
!!}!!int main (int argc, char** argv){!! foo myfoo = &fooImp1;! ! doFoo (4, myfoo); !}!
//foo is polymorphic
2A10F
memory
…
…
…
_fooImp2(int i)
fooImp2() implementa2on
…
afoo 1A001
1A001 _fooImp1(int i)
fooImp1() implementa2on
i 4
//sets the concrete “instance”
OOP applica2ons are executed as a set of collabora2ng objects
:User
object
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
Anatomy of an object in C, C++, Java…
draw() move()
_Circle_draw() _Circle_move()
cx=100 cy=50 r=0
s1:Shape
s1:Circle
Opera>ons specifica>on
Opera>ons realiza>on
a:ributes
draw() move()
s1:Shape
How it is seen by other objects
s1 referenced as a Shape
Dynamic Binding
s1 is a Circle class instance that implements the Shape interface
Anatomy of an object in C, C++, Java…
draw() move()
_Circle_draw() _Circle_move()
…
cx=100 cy=50 r=20
s1:Shape
s1:Circle Dynamic binding
Interface
Implementa>on
data
Opera>ons specifica>on
Opera>ons realiza>on
a:ributes
Interface Shape { draw(Canvas c); move(int x, int y); }
class Circle implements Shape { // a:ributes int cx; int cy; int radius; // implementa>on draw(Canvas c) { c.drawEllipse(cx,cy, r); } move(int x, int y) { cx = cx+x; cy =cy+y } setC(int x, int y) { cx=x; cy=y; } setR(int radious) { r=radious; } }
s1 Instan>a>on (new)
Main() { Circle s1 = new Circle(); s1.setC(100,50) s1.setR(20); Canvas c = new DefaultCanvas(); c.addShape(s1); // registered as Shape c.show(); }
Object s1 shown as “Shape” interface while its implementa>on is class “Circle”
Instan&a&on Code
Defini&on Code
A basic implementa2on in C (not C++)
���$��� ������
������
a"rributes*
Shape*
����
���
memory&
'�
'�
'�
�����������$��������!�� ����#� ����#��
draw()*implementa5on*
�%� ����&�
��������
��#����
�!���!�����
�!�����" ���
���� ������
������
opera5ons*table*
'�
typedef struct tShape Shape;!typedef struct tCanvas Canvas;!!// SHAPE INTERFACE DECLARATION!struct tShape {! void (*draw) (Shape * this, Canvas * canvas);! void (*move) (Shape * this , int x, int y);!
!!};!!!// CIRCLE CLASS DECLARATION!!typedef struct tCircle Circle;!!struct tCircle {! void (*draw) (Circle * this, Canvas * canvas);! void (*move) (Circle * this, int x, int y);! ! double (*circunference) (Circle * this );!
!! int cx;! int cy;! int r;!!};!!// CIRCLE CLASS OPERATIONS!!void _Circle_draw(Circle * this, Canvas* canvas) {! // code for drawing a circle!}!!double _Circle_circunference(Circle * this) {! return 2*M_PI*this->r;!}!!// code for allocating a Circle in memory!!Circle * newCircle (int cx, int cy, int r) {! Circle * circle = malloc(sizeof(Circle));! ! circle->cx = cx;! circle->cy = cy;! circle-> r= r;!! // filling function pointer members!! circle->draw = &_Circle_draw;! circle->move = &_Circle_move;! circle->circunference = &_Circle_circunference;!! return circle;! !}!
����"����������� ����
Shape**shape*Circle**shape*
draw()'move()'
_Circle_draw()'_Circle_move()'
…'
cx=100'cy=50'r=20'
s1:Shape'
s1:Circle'
show()'
s1,s2'referenced'as'a'Shape.'Implementa9on'is'bound'dynamically'at'run9me.''Line'and'Circle'implementa9on'is'not'known'by'Canvas'object'
show()'
_DefaultCanvas_show()'…'
shapes=[s1,s2]'
c1:DefaultCanvas'
GUI'OS'
c1:Canvas'
draw()'
draw()'move()'
_Line_draw()'_Line_move()'
…'
x0=0'y0=0'x1=20'y1=20'
s2:Shape'
s2:Line'
draw()'
Dynamic'binding'
Dynamic'binding'
Dynamic'binding'
class%DefaultCanvas()'{'''''''Shape[]'shapes;'''''''addShape(Shape's)'{'''''''''shapes.add(s);'''''}'''''show(){''''''''for's'in'shapes'{'''''''''''''s.draw(this);''''''''}''''}'}'
Dynamic binding in ac2on
Fine…But….
Messages are synchronous (like “func2on calls”) Classes are defined at coding 2me, can not be changed at run2me. Too much focus on coding the Hierarchies (aaarg..) No Reflec2on (yes in Java) Late binding limited to message processing
In Java, C++ like languages , inheritance is a coding mechanism, for reusing both specifica2on (interface) and realiza2on (implementa2on)
Basic Advise for java,c++ like programmers
• Programing to an interface not an Implementa4on
• Composi4on and Delega4on over inheritance
Basic Advise for java,c++ like programmers I
Interface!!Shape!{!!!!!!!!draw(Canvas!c);!!!!!!!!move(int!x,!int!y);!}!
class!Circle!implements!Shape!{!!!!!!//!a$ributes!!!!!!!int!cx;!!!!!!!int!cy;!!!!!!!int!radius;!!!!!!!!!!!!!!!!!!//!implementa0on!!!!!!!draw(Canvas!c)!{!!!!!!!!!!!!!!c.drawEllipse(cx,cy,!r);!!!!!!!}!!!!!!!move(int!x,!int!y)!{!!!!!!!!!!!!!!cx!=!cx+x;!!!!!!!!!!!!!!cy!=cy+y!!!!!!!}!!!!!!!setC(int!x,!int!y)!{!!!!!!!!!!!!!!!cx=x;!!!!!!!!!!!!!!!cy=y;!!!!!!!}!!!!!!!setR(int!radious)!{!!!!!!!!!!!!!!!r=radious;!!!!!}!}!
draw()!move()!setC()!setR()!
_Circle_draw()!_Circle_move()!_Circle_setC()!_Circle_setR()!
cx=100!cy=50!r=20!
s1:Circle!
Shape!instanceShape()!{!!!!!Circle!s1!=!new!Circle();!!!!!s1.setC(100,50)!!!!!s1.setR(20);!!!!!return!s1;!}!
draw()!move()!setC()!setR()!
_Circle_draw()!_Circle_move()!_Circle_setC()!_Circle_setR()!
cx=100!cy=50!r=20!
s1:Shape!
draw()!move()!
s1:Shape!dra
w()!
How!it!is!seen!by!other!objects!
s1!referenced!as!a!Shape!s1!referenced!as!a!Circle!
Instan0a0on!
Object!allocated!and!running!in!memory!Programmed!code!
Reference an Object (class Circle) as its most abstract form possible (Shape)
Basic Advise for java,c++ like programmers II • new operator is hardcode
– Instan2a2on should be encapsulated and done via scrip2ng or declara2ve like mechanisms (xml, proper2es file, json…)
• Never instan2ate a concrete object from other object methods – (inject dependencies via abstract refs)
class CircleDrawingTool extends DrawingTool { DefaultCanvas canvas; CircleDrawingTool(){ this.canvas = new DefaultCanvas(); } …. }
class CircleDrawingTool extends DrawingTool { Canvas canvas; CircleDrawingTool(Canvas c){ this.canvas = c; } …. }
void instantiation (File configurationFile) { Configuration cfg = parse(configurationFile); Canvas canvas; CircleDrawingTool ctool; if (cfg.property(“canvas.type”)== DEFAULT_CANVAS) { Canvas = new DefaultCanvas(); //… set canvas attributes } // canvas injected through constructor ctool = new CircleDrawingTool(canvas) … }
Or se:er injec>on
Basic Advise for java,c++ like programmers III
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
collabora2on alloca2on
op1()
op2()
op3()
…
_class_Imp_op1()
_class_Imp_op2()
…
a11=v1
a12=v2
…
:Imp
concrete object referenced through abstract forms
Circle Shape
Shape
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
CircleDrawingTool
Canvas
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
Canvas
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
op1()
op2()
…
_class_Imp_op1()
_class_Imp_op2()
…
a01=v1
a02=v2
…
:Imp
CircleDrawingTool
dependency injec2on
Shape
new
addShape
show
draw
draw
Clearly Separate object Alloca4on and Set up (aKributes, rela4onships) from objects Collabora4on (message passing)
Instan4a4on Execu4on
Basic Advise for java,c++ like programmers IV
• A switch-‐case by type (if object instanceof ) it is a symptom of bad polymorphic interface-‐class design
void handle(Shape* shape) { if (shape instanceof Circle) { Circle c = (Circle) shape; // handling a circle } else if (shape instanceof Line) { Line l = (Line) shape; // handling a line } else if … }
void handle(Shape* shape) { shape->doHandle(); }
Or more sophis2cated pa`ern (i.e Visitor, Chain of Reponsabili2es)
Basic Advise for java,c++ like programmers V Use Design PaKerns
– Help you to have polymorphic designs (Composite, Builder, Prototype, Visitor, Chain of Responsibili2es, Decorator, Observer….)
• Composi4on and Delega4on over inheritance: – Favor extending the behavior of an object by delega2ng its message processing to a
collabora2ng object that are part of it (they compose it)
• Programing to an interface not an Implementa4on: – Make the applica2on work through a set of objects that collaborate between them
through interfaces or abstrac2ons that hide the concrete implementa2ons or concrete classes.
h`p://www.amazon.com/Design-‐Pa`erns-‐Elements-‐Reusable-‐Object-‐Oriented/dp/0201633612/ref=sr_1_1?s=books&ie=UTF8&qid=1383378933&sr=1-‐1&keywords=design+pa`erns
h`p://en.wikipedia.org/wiki/Design_Pa`erns
Gang of Four
Ward Cunningham
Basic Advise for java,c++ like programmers VI Follow SOLID principles in your Design
• Single Responsibility Principle – A class should have one, and only one, reason to change
• Open Closed Principle – You should be able to extend a classes behavior, without modifying it. Classes should be open for
extension, but closed for modifica2on.
• Liskov Subs2tu2on Principle – Derived classes must be subs4tutable for their base classes and vice versa as long as they are referenced
by the same abstract interface. The base abstrac2ons must be really polymorphic.
• Interface Segrega2on Principle – Make fine grained interfaces that are client specific. Many client specific interfaces are be`er than one
general purpose interface
• Dependency Inversion Principle – Depend on abstrac4ons, not on concre4ons. Never have references or directly instan2ate concrete classes
from the class that collaborates with them, just have a references to abstrac2ons. Let other part of the program do the concrete instan2a2on and control the injec2on of the dependency object referenced as an abstrac2on.
h`p://butunclebob.com/Ar2cleS.UncleBob.PrinciplesOfOod “Uncle Bob” Robert Cecil Mar2n
But … (c++, java like languages)
• S2ll separa2on between Coding&Design Time vs Run2me – Should be the same : interac2ve programming
• Once classes and interfaces are “wired” they can not be (easily) altered at run2me
• “Cumbersome” and complex mechanisms for separa2ng instan2a2on part from execu2on part – like spring framework, xml coding, more than 2100 classes!!
Smalltalk and its dialects
A dialect of Smalltalk based on the concept of Prototypes
Opensource Smalltalk
…..Only in academic environments
| myButton |!! myButton := Button new.! myButton label: 'press me'.! myButton action: [ myButton destroy ].! myButton open.!
JavaScript object model
h`p://www.ecma-‐interna2onal.org/publica2ons/files/ECMA-‐ST/Ecma-‐262.pdf
prototype-‐based language objects are Associa2ve Arrays than can vary at run2me
Being closer to OOP Alan Kay
• Objec2ve C, Java, C# provide dynamic mechanisms, most of them inherited from smalltalk language and its tools – java.lang.reflect, garbage collector, refactoring…
@implementation GSTimeSliderCell! !- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag!{! if (flag) {! [[NSNotificationCenter defaultCenter] postNotificationName:GSMouseUpNotification object:self];! }! [super stopTracking:lastPoint at:stopPoint inView:controlView mouseIsUp:flag];!}! !@end!
Being closer to OOP Alan Kay
• Actors model – Proposed by by Carl HewiK in 1973 – Actors are ac2ve objects which communicate by message passing
• Erlang, Scala
Conclusions
• We have been too platonic and having imperfect realiza2ons of the OOP idea
• We should try to be more aristotlelic, focusing on objects as message processors with late binding
• Be aware of the Compu2ng Science History – Most of what we think is modern was invented in the 70s