Il primo linguaggio ad oggetti è stato Smalltalk aveva alcune caratteristiche che quasi nessun linguaggio moderno possiede ancora.
Un'importante differenza è che la classe è un oggetto. Infatti per creare una nuova classe non ho un meccanismo speciale come in C#, ma semplicemento chiamo un metodo di un oggetto.
Esempio supponiamo di voler creare la classe Dog:
Object subclass: #Dog
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'PBE'
In questo caso viene mandato il messaggio subclass (analogo alla chiamata di un metodo) all'oggetto Object. Analogamente se voglio creare un oggetto di tipo Dog manderò il messaggio new all'oggetto classe Dog.
Anche in Ruby le classi sono oggetti. Quindi il linguaggio C# è un linguaggio Class Oriented proprio per questa limitazione.
Il video Ruby for .NET developers spiega bene queste differenze prendendo come linguaggio di riferimento Ruby.
Partirò da una citazione dell'articolo A Laboratory For Teaching Object-Oriented Thinking:
One of the distinguishing features of object design is that no object is an island. All objects stand in relationship to others, on whom they rely for services and control. The last dimension we use in characterizing object designs is the collaborators of an object. We name as collaborators objects which will send or be sent messages in the course of satisfying responsibilities. Collaboration is not necessarily a symmetric relation.
La parte iniziale è un concetto fondamentale: gli oggetti vanno considerati in relazione degli oggetti con cui collaborano e non come entità singole.
Purtroppo l'ambiente di sviluppo non aiuta in questo senso perchè visualizzando il sorgente di una classe per volta rendo difficile la visualizzazione degli oggetti con cui collabora.
Cercherò di chiarire questo concetto con una metafora: è come se volessi insegnare la geografia senza una cartina. Ovviamente posso scrivere che l'Italia confina con la Francia, L'Austria, ecc., ma senza una cartina non potrò mai dire di conoscere la geografia.
La domanda a questo punto sorge spontanea: negli oggetti qual è la cartina?
Come nella geografia ne esistono di diversi tipi. Quella che rende meglio l'idea di un oggetto che collabora con gli altri oggetti è il communication diagram introdotto in UML 2. Il communication diagram fa parte degli interaction diagram tra cui è ben più famoso il sequence diagram. Per approfondire l'argomento consiglio la lettura di questo pdf, tratto dal libro di Larman Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development.
Ne riporto un esempio:
L'idea che sta alla base del communication diagram è simile a quella che ebbe originariamente Alan Kay uno dei padri della programmazione ad ogggeti. In sintesi gli oggetti comunicano scambiandosi messaggi, nel caso di c# il messaggio è una chiamata ad un metodo.
Nel diagramma in figura il Controller collabora con il ListinoPrezzi, il Counter e il Display scambiandosi i messaggi GetPrice, IncrementBy, ecc. Come potete notare la collaborazione tra gli oggetti è evidente in questa schematizzazione.
Consiglio vivamente di usare i communication diagram per il design della propria architettura perchè aiuta a ragionare ad oggetti e non in modo procedurale.