Upload
marco-parenzan
View
156
Download
0
Embed Size (px)
DESCRIPTION
Writing good C# code for good cloud applications
Citation preview
Writing good C# code
for good cloud applications
2014 Edition
Marco Parenzan
WARNING
This document is currently in draft
and many aspects have to be refined!
Marco Parenzan
Marco ParenzanFormazione & Divulgazione con 1nn0va
Microsoft MVP 2014 for Microsoft Azure
Formazione & Progettazione con ITS Kennedy
Ricerca e Innovazione con Servizi Cgn
www.slideshare.net/marco.parenzan
marco [dot] parenzan [at] libero/live [dot] it
www.innovazionefvg.net
Developer e Architect in .NET e Web
Cloud Developer
Loves functional programming
Some videogames for fun
Code and Modeling
Modeling is the activity of translating some requirements, results of an analysis activity
Code is a way to model «intentions» with «responsibilities» through a programming language
Modeling is the activity of undestanding and specificating “the real world”
Coding is the activity of representing the modeling activity in a software with a language
Cloud code
Cloud Computing is not a specific environment
CC encourages writing good code to improve Application Lifetime
Management
CC require agile approach to coding because of an evolving
context
C# code
C# is a statically typed, strongly typed language
That guarantees benefits in a modern development environment
like Visual Studio
C# is a great language to write Domain-oriented code
C#, alone, does not guarantee a writing a good application,
without some other principles
C#
co
de
The evolution of C#
• C# 1.x (.NET 1.0 – VS2002/3)
• C# 2.0 (.NET 2.0 – VS2005)
• C# 3.0 (.NET 3.5 – VS2008)
• C# 4.0 (.NET 4.0 – VS2010)
• C# 5.0 (.NET 4.5.1 – VS2012)
• Roslyn
• C# 6.0 (.NET 4.5.2 – VS2014)
2.0Modeling
1.xManaged Code
3.0Functional
4.0Dynamic
5.0Asyncronous & Parallel
6.0Roslyn
The path through modeling
Domain
We speak about a business (domain) and we need to represent things in
business as code
Imperative
Write what is in your mind (that will live in your mind forever!). No one will understand what you have written
Intention and Responsibility
Why are you coding? Which is the intention inside every line you write?
The path through modeling [2]
Object Modeling
Classes are the way to describe model into a domain
Functional Modeling
Declare you intention first! not implement it!
Contract Modeling
Class is not just encapsulation. It’s also declaration of a contract
The path through modeling [3]
Interface Modeling
Class should be implementation only. Interfaces are a better way to describe
a contract
Blueprints for objects: patterns
Feel free to express yourself…or not? Please refer to some work done by
experts!
Domain Modeling
Principles
Domain Model Drives
Design.
Focus on Model of the
Domain, rather than Technology
Domain Model is a
Backbone of a Domain Language
Speak a Ubiquitous Language
within a boundedcontext
UbiquitousLanguage used
in all project aspects
discipline
understanding
Domain (Driven Design)
Domain
A sphere of knowledge (ontology), influence, or activity. The subject area to which the user applies a program is the domain of the software.
Model
A system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain.
Ubiquitous Language
A language structured around the domain model and used by all team members to connect all the activities of the team with the software.
Context
The setting in which a word or statement appears that determines its meaning.
Ubiquitous Language
Common Language given by domain experts for describing system entities.
Model based language.
Structured around the domain model and used by all team members to connect all the activities within a bounded context.
Universal vocabulary that can be used in every aspect of the project (diagrams, source code, documentation, discussions and correspondence).
May include concepts that are not currently computerized.
Consistent logical model and a shared glossary of terminology.
Starting point for more detailed analysis.
Validates I.T. understanding of the business domain and its concepts.
The vocabulary of that UBIQUITOUS LANGUAGE includes the names of classes and prominent operations
The LANGUAGE includes terms to discuss rules that have been made explicit in the model and model relationships.
The model-based language should be used among developers to describe not only artifacts in the system, but tasks and functionality. This same model should supply the language for the developers and domain experts to communicate with each other, and for the domain experts to communicate among themselves about requirements, development planning, and features. The more pervasively the language is used, the more smoothly understanding will flow
Vocabulary has to be continuously refined.
Domain experts use it in discussions with developers.
Areas of model inadequacy quickly discovered. (where model seems wrong to the domain expert).
Developers and domain experts walk through scenarios, using model objects to deepen each other's understanding and refine concepts as they go
Domain Types
Abstraction
A domain that models the real BUSINESS domain
Technology
A domain that models the technology specific parts of a domain
Common
A domain that models the common parts between many abstractions
Host
A domain that contains the deployment parts of an application, coordinating all the other domains
Domain Model
Extracts domain essential elements, relevant to a specific use.
Layer of abstractions representing selected aspects of a domain.
Contains concepts of importance and their relationships in a certain domain.
Not concerned with physical data storage or processing.
May include concepts that are not currently computerized.
Consistent logical model and a shared glossary of terminology.
Starting point for more detailed analysis.
Validates I.T. understanding of the business domain and its concepts
Avoid a
big,
unified,
centralized
model
They have to freely evolve separately
Bounded Context
Multiple models are in play on any large project. ... It is often
unclear in what context a model should not be applied.
…Explicitly set boundaries in terms of team organization, usage
within specific parts of the application, and physical manifestations
such as code bases and database schemas
Not distracted or confused by issues outside
You have responsibility only inside your Bounded Context, not
outside
Domain Bounded Context
Different models apply in different contexts.
Same entity appears in different contexts with different shapes.
Context boundaries are a set of conditions (business functionality - application layer – database).
Model shall be strictly consistent within a specific bound.
Bounded contexts are not modules.
A bounded context can enfold other bounded contexts.
Name of a bounded context is part of the Ubiquitous Language
Explicitly define the context within which a model applies. Explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don't be distracted or confused by issues outside.
A BOUNDED CONTEXT delimits the applicability of a particular model so that team members have a clear and shared understanding of what has to be consistent and how it relates to other CONTEXTS. Within that CONTEXT, work to keep the model logically unified, but do not worry about applicability outside those bounds. In other CONTEXTS, other models apply, with differences in terminology, in concepts and rules, and in dialects of the UBIQUITOUS LANGUAGE. By drawing an explicit boundary, you can keep the model pure, and therefore potent, where it is applicable. At the same time, you avoid confusion when shifting your attention to other CONTEXTS. Integration across the boundaries necessarily will involve some translation, which you can analyze explicitly.
The names of the BOUNDED CONTEXTS will themselves enter that LANGUAGE so that you can speak unambiguously about the model of any part of the design by making your CONTEXT clear
Seeing same thing differently
Different bounded contexts or use cases may have different
perceptions about the same physical entity.
Different perceptions may be complementary or contradictory.
Depending on their goals in interacting with the elephant, the
various blind men may still be able to make progress, even if they
don't fully agree on the nature of the elephant. If no integration is
required, then it doesn't matter that the models are not unified. If
they require some integration, they may not actually have to agree
on what an elephant is, but they will get a lot of value from merely
recognizing that they don't agree. This way, at least they don't
unknowingly talk at cross-purposes
Seeing same thing differently
Complementary perceptions:
Common parts Shared kernel
Each context extends (inherits/aggregates) the core part and enrich it with his own perception.
Parts of a larger whole
Common parts Shared kernel
Contradictory perceptions:
Bounded contexts doesn’t accept each other’s model
Nothing to share in common Agree on not to agree (Separate Ways)
Something to share in common Adapt to each other (Context Map)
Strongly Typed, Statically Typed
If you decide EARLY what a class can do, you:
Are explicit in your intention
Allow tools helping you on your work
Strongly typed
Type declare an intention, about declaration and usage
Statically Typed
Help compiler ensure your intention, based on declaration and usage
Imperative Modeling
We start with a problem to solve…
…typically with a divide and conquer technics
In traditional programming, we figure out how to break the problem into smaller parts, then each part into smaller parts still…with an emphasis on doing.
In the object-oriented approach we then try to figure out what objects the system has, what their responsibility is, and how they interact
Alec Sharp, Sharp, “Smalltalk By Example”, page 10, McGraw-Hill, 1997
Imperative Programming
http://en.wikipedia.org/wiki/Programming_paradigm
imperative programming is a programming paradigm that describes computation in terms of statements that change a program state
No assumptions are done…
…where state is…
…who can change state…
…protect state…
Focus is on statements
Origin of algorithms
Evolution of Von Neumann model (not so different from Machine Language, Assembly model)
The notion of algorithm!
Express how to do…what?
You express the single lines of code without explaining the intention
How do you organize statements?
You organize statements through grouping blocks of statements
Creating distinct blocks of statements means encapsulation
Encapsulation is represented by giving this block a name
Name reflects intention of the block to the state
What is a «good» encapsulation?
Is a state that is used only from a single, encapsulated, block of code
Responsibility Modeling
Intention
An intention is a piece of code with a role (in your entire code)
Less roles (best: one!) better is the intention
So you need many intentions!
“Why have you wrote that code?”
“Which was your intention?”
Tell, don’t Ask
Procedural code gets information then makes decisions.
Object-oriented code tells objects to do things.
Alec Sharp, Sharp, “Smalltalk By Example”, page 67, McGraw-Hill, 1997
Smalltalk, where objects born…
“Any intention has a
consequence”
Are you responsible about your intention?
Encapsulation
Encapsulation is assigning a name to an intention
A program in a (un)ordered set of intentions
More detailed is the name of the intentions, better is the result
Less detailed are intentions, more work is for you
Why Encapsulation
Give a Name («define a message») to an ability
From the implementer Point of View
Invoke a Name («send a message») to ask for an ability
From the consumer Point of View
Encapsulation has an important consequence
Encapsulation in OOP
Encapsulation, inheritance, and polymorphism are the three pillars of object-oriented programming.
Encapsulation is the packing of data and functions into a single component.
The features of encapsulation are supported using classes. It allows selective hiding of properties and methods in a class by building an impenetrable wall to protect the code from accidental corruption.
In programming languages, encapsulation is used to refer to one of two related but distinct notions, and sometimes to the combination thereof:
A language mechanism for restricting access to some of the object's components.
A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.
Give me some examples of
encapsulated intentions!
Good
CreateAnOrderForCustomer
CalculateTotalAmountToPay
GenerateSummaryReport
Bad
CreateAnOrderWithTotalForCus
tomerAndGenerateSummaryR
eport
Responsibility
The intention is a boundary of responsibility
Responsibility has many definitions. For example:
A responsibility is an obligation to perform a task or know information
http://en.wikipedia.org/wiki/Responsibility-driven_design#objects
Responsibility for what?
Program «calculate» a result
A result is a fact, but is not always «instantly» calculated
A result is the end of a «path» that goes through a «state» that changes asprogram go on
In math terms, sequence of values must «converge» to the result
Wrong manipulation of state (values) creates side effects and arrival to a wrong result
Responsibility is the guarantee of the intention of correct state management to arrive to correct result
How do you describe the responsibility? Through code
It’s not your responsibility!
The problem is that, as the caller, you should not be making
decisions based on the state of the called object that result in you
then changing the state of the object.
The logic you are implementing is probably the called object’s
responsibility, not yours. For you to make decisions outside the
object violates its encapsulation.
Tell just “what you want to do”
Don’t ask something (state) so you can decide
It’s all about
“Handling Complexity”
C#
co
de
Assembly
• Assembly is unit of distribution in .NET
• It’s a boundary!!!!
• A project in Visual Studio generate an assembly
• An assembly is a good container for a Bounded Context
• Assembly name corresponds to root Namespace in the form of <companyname>.<domainname>
• Contained namespaces are good to organize code by usage
C#
co
de
Namespace
• Qualificano un insieme di classi sotto un unico nome contenitore
Nome COMPLETO della classe: nome del namespace + nome della classe
Livelli>1
Si definiscono in namespace {}
• Permettono di disambiguare classi con lo stesso nome
• È possibile usare sempre i nomi qualificati
• È possibile importare un namespace con la parola chiave using
Permette di definire alias sul namespace: using <alias> = <namespace>
<alias>.<nome classe>
Permette di definire alias sulla classe: using <aliasclasse> = <namespace>.<classe>
<aliasclasse>
• È possibile usare la parola using sia dentro che fuori del namespace
La differenza diventa “importante” nel caso nello stesso file ci siano più definizioni di namespace
Spesso non succede
• Esiste un “global” namespace
C#
co
de
Static Classes
• Contengono solo metodi statici
• Non membri di istanza
• Serviranno per gli Extension Methods
C#
co
de
Tipi primitivi
• I tipi primitivi sono strutturedefinite nel namespace System
• È possibile usare il loro nome o illoroalias C#
Int32 i = 4;
int j;
j = i;
structure name
C# alias
bool Boolean
char Char
sbyte SByte
byte Byte
short Int16
ushort UInt16
int Int32
uint UInt32
long Int64
ulong UInt64
float Single
double Double
decimal Decimal
Boolean
character
integer
floating point
same type so
can interoperate
C#
co
de
An example: Int vs. Enum
• StateId model a state (in a Finite State Machine manner)
• StateId is int
• StateId (from model) can assume values as 1,2,3
• Int says all numbers are valid, from -231231-1
• What ensures StateId having 1,2,3 only?
You
Guard code (imperative)
Type (declarative)
C#
co
de
Enum
• La parola chiave enum è usata per definire il nuovo tipo
Contiene un insieme di costanti simboliche
• È possibile definire variabili di un tipo enum, usando I valori definiti in essa
• Di default usa (implicitamente) il tipo int
È possibile fare il cast (esplicito) da/verso il tipo implicito
È possibile specificare un altro tipo primitivo (a parte char)
• È possibile assegnare dei valori diretti
È possibile modificare la sequenza dei numeri
C#
co
de
Eccezioni
• Un’eccezione è un evento sincrono
È prevedibile il punto in cui può avvenire, non il momento
• Un’eccezione è un pattern utilizzato per notificare errori
• Un’eccezione può essere gestita con un blocco try…catch…finally
Try: blocco che può generare eccezione
Catch: blocco eseguito subito dopo all’istruzione nel blocco try che ha generato l’eccezione
Finally: blocco eseguito comunque dopo il blocco try e l’eventuale blocco catch
• Un’eccezione, per essere gestita dal blocco try prende forma di un oggetto che deriva dalla classe exception
• La notifica di un’eccezione si basa sullo stack
Un blocco try…catch…finally viene registrato nello stack
• Non è detto che un metodo che chiama un altro metodo che genera una eccezione debba “trappare” una eccezione
Viene fatto uno “stack walk” per trovare il primo blocco disponibile
Eventualmente quello di default fornito dal framework
• È possibile definire una eccezione derivando una nuova classe dal tipo Exception
Si usa l’istruzione throw per sollevare una nuova eccezione
• Ci sono delle eccezioni di uso comune
C#
co
de
Delegate
• La parola riservata delegate serve a definire un tipo in grado di puntare a un metodo e gestire indirettamente la sua invocazione.
Possiamo vedere un delegate come un "puntatore a funzione“
• Garantisce che il metodo abbia una specifica firma
Lista ordinata dei tipi dei parametri formali
Non include il tipo di ritorno (ma due funzioni non possono distinguersi per il solo tipo di ritorno)
• Offrono la possibilità di chiamare un metodo (anche) in modo asincrono tramite BeginInvoke e EndInvoke
Un delegato ha dei metodi (è una classe)
<delegate>() è la sintassi contratta di <delegate>.Invoke()
• I delegati sono multicast
È possibile assegnare ad un delegate più puntamenti a metodi diversi
Un invocazione sul delegato implica la chiamata a tutti i metodi referenziati
• Vengono utilizzati principalmente per:
la gestione degli eventi
L’uso come callback (passare un metodo come “valore” ad un altro metodo)
C#
co
de
Anonymous Methods
• Permettono di definire direttamente il codice dove è necessario un delegato
• Il tipo dei delegati viene automaticamente inferenziato (non serve istanziare esplicitamente il delegato, ma scrivere solo il corpo)
• I blocchi di codice possono accedere alle variabili locali
Non possono però accedere a parametri (di un metodo in cui sono definiti) ref o out
Ovvio, in quanto la loro esecuzione non è legata all’invocazione del metodo di definizione
• La vita delle variabili locali è “estesa” fino a che il delegato che le referenzia non è eligibile di garbage collection
Tutto è dovuto a generazione nascosta di classi
C#
co
de
Lambda expressions
• Permettono di definire delle funzioni “inline”, associando direttamente un blocco di codice
• Permettono di creare un metodo “stand-alone” all’interno del codice (utilizzando gli anonymous methods)
• Sono un’ulteriore semplificazione rispetto l’uso dei delegate
• Dal calcolo lambda
x . x + 1
• In C# 3.0
x => x + 1
• Dalla sintassi delle anonymous functions
delegate(int x) { return x + 1;}
• Possono usare variabili implicitamente tipizzate
• Possono avere più di una variabile
• Il corpo può contenere espressioni o istruzioni
C#
co
de
Extension methods
• È possibile aggiungere metodi a classi già definite
È possibile aggiungere metodi a classi già compilate, in assembly diversi
Non sono mixin (dai dynamic languages)
Sono “syntactic sugar”
Readability
• Solo metodi
Non per properties, events, operators (almeno per adesso)
• Metodi statici in classi statiche
La chiamata esplicita al metodo statico avviene sempre (e rimuove ambiguità)
Nel caso di sovrapposizione con metodi locali
I metodi locali hanno la precedenza
• L’inserimento degli extension method avviene al momento dell’importazione del namespace
C#
co
de
Enumeratori
• Un enumeratore è un cursore read-only forward only
Permette di visitare una collezione di elementi
• Si basa su due interfacce
IEnumerator: l’enumeratore vero e proprio
IEnumerable: permette di richiedere ad una collezione un enumeratore per
visitare la stessa
• Usato dal costrutto foreach
Object Modeling
Objects and Classes
Objects is a structure that encapsulates state and behavior that
evolve that state
Class is a mechanism to declare the encapsulation of state and
and behavior
Class-based languages implements these principles with many
options on principle enforcement (strong, wake)
Note. There are also other paradigms to define objects (ex. Prototyping, as for Javascript)
C#
co
de
Classes vs. Components
• Class is made up of (is the expression of an implementation)
variables
functions
• Component is made up of (is the expression of a contract)
Methods
Properties
Events
• Methods are functions
Intention of an action (theory calls them «messages»)
• Properties are syntactic sugar for special functions (accessors) around variables
• Events are special Properties
Notify the happening of an action
C#
co
de
Reference Types
• Una qualsiasi dichiarazione di tipo fatta con la parola class indica un Reference Type
• Il riferimento è a una istanza di quel tipo
L’istanza viene creata con l’operatore new
Allocazione nel managed heap
• L’assegnazione tra variabili di tipo Reference implica la copia del riferimento, non dell’oggetto riferito
• Una variabile di un reference type accetta null
Invalida il riferimento
Valore di default per una variabile
Non distrugge l’oggetto (Garbage Collection)
Far riferimento ad una variabile null solleva una NullReferenceException
• Gli array e le stringhe sono reference types
C#
co
de
Properties
• Le proprietà combinano la sintassi delle variabili membro con il controllo delle funzioni membro
Permettono di associare ad un nome (con un tipo) le due funzioni accessorie
• Syntactic Sugar
• Permettono di definire
Readonly properties
Guarded properties
Calculated properties
C#
co
de
Eventi
• Un evento caratterizza un componente
Qualcosa che succede all’interno del componente e che lo stesso notifica
Un oggetto esterno può sottoscrivere l’evento per essere notificato quando succede
Un evento è una specializzazione di un delegato
• event è una parola chiave da associare ad una proprietà di un tipo delegato
• event impedisce l’uso dell’assegnazione (“=“) ma solo la sottoscrizione (“+=“) o la cancellazione (“-=“)
Il mancato uso dell’assegnazione impedisce ad un consumatore generico di rimuovere la sottoscrizione a qualche altro componente
• Qualsiasi delegato può essere usato per un evento
È convenzione usare un delegato del tipodelegate void <event handler>(object sender, <event args> e)dove <event args> è una classe che deriva da EventArgs
• È possibile creare una variabile membro di tipo evento
• È possibile creare una proprietà di tipo evento
Rispetto alle proprietà le funzioni accessorie sono add e remove
C#
co
de
Generics
• Polimorfismo Parametrico
• Funziona sia con reference and value types
• Controllo dei tipi in fase di dichiarazione
No boxing (value types)
No downcasts (no object)
• Supporto completo a runtime
• Reduced code bloat
Non bisogna scrivere classi wrapper tipizzate
Functional Coding and Modeling
Imperative vs. Declarative
Imperative==(you) ASK to DO (yourself)
And you DON’T SAY what you need
Declarative=(you) TELL to MAKE it DONE (by someone else)
You SAY what you need
You don’t know how it is done
Declarative Code
Describe what you want to obtain (the result)
Then there is the topic about (how to obtain)
It can be that tool (the language, the compiler) can do that work
or you
The most common example of this is SQL
Functional Code: a declarative approach solved using functions
Functional
You express the intention on how state change (relation before-
after)
You enforce this with invariants (values that doesn’t change)
C#
co
de
Some examples in C#
• If
Alternative (Option)
Guard
Constraints
• While
Loop
Aggregate
Map/Reduce
Recursion
C#
co
de
Some examples [2]
• Int
Integer
Option
State
• Decimal
Fixed point
Currency
• Double
Scientific
Temperature
Conversion
C#
co
de
Value Types
• Nel caso di local variables, parameters, loop counters, un programma ne può fare un uso intensivo
• Problemi
Allocazione
Accesso
Rilascio
• Uso dello stack
Allocazione e rilascio automatico
Accesso alla memoria efficiente
• I value types contengono i valori direttamente, non i riferimenti
• Int, char, byte, TimeSpan sono value types primitivi
• Se ne possono definire di custom tramite struct
C#
co
de
struct
• Possono avere proprietà, metodi, costruttori, membri, implementare interfacce
• Non possono:
Ereditarietà per classe
Valori inizializzati alla definizione
Non possono avere un custom default constructor (senza parametri)
Un costruttore deve esplicitamente inizializzare tutte le variabili
C#
co
de
Anonymous Types
• È una “tupla” le cui proprietà specifiche sono inferenziate tramite Object Initializer
• Viene fatto a compile time, quindi è sempre comunque statically/strongly typed
Internamente viene creata una classe nascosta
• var x = new {p1 = 10, p2 = “name”};
Il tipo di x è anonimo
Non è possibile referenziarlo “per nome” da codice
• structural type equivalence
Due tipi anonimi possono essere compatibili
Viene ricostruita la “compatibilità” a compile time
• Viene definito un solo nuovo tipo (anonimo)
La classe verrà generata automaticamente in fase di compilazione, e deriverà da System.Object
• implicitly typed arrays
var a = new[] { 1, 10, 100, 1000 };
Devono avere tipi compatibili
O conversioni implicite
C#
co
de
Implicitly typed variables
• E’ possibile dichiarare le variabili in modo implicito, utilizzando la parola chiave “var”
var i = 5;var s = "Hello";var d = 1.0;var orders = new Dictionary<int,Order>();
• Il tipo delle variabili è indotto dalla espressione che lo inizializza
DEVE INCLUDERE L’INIZIALIZZAZIONE
“var” non è variant o object
È comunque statically typed
• Non può essere null
• Var può essere usata SOLO nei metodi
Non può essere usata a livello di classe
Attenzione all’abuso
Bisogna capire il contesto dell’esecuzione per capire cosa c’è dentro
E’ possibile utilizzare la keywork “var” anche all’interno di cicli for e foreach
C#
co
de
Object Initializers
• È possibile inizializzare variabili membro e proprietà, senza richiamare il costruttore in modo esplicito
new C(1, 2, name=“my class”);
Valgono le regole di visibilità
È possibile fare annidamento
Initializzare grafi
• Collection initializers
List<int> digits = new List<int> { 0, 1};
Deve implementare System.Generic.ICollection<T>
• Object initializers
var a = new Point { X = 0, Y = 1 };
C#
co
de
Autoimplemented Properties
• Permettono di specificare una proprietà senza doverne specificare il field privato
• Velocizza il processo di creazione di proprietà all’interno delle classi
• Il membro privato viene generato a compile-time
• Per vedere il nome del field privato generato, è necessario utilizzare ildasm.exe o Reflector.exe
• Non è possibile utilizzarle per specificare proprietà in read-only o write-only
E’ possibile limitare l’accesso al get o al set di una proprietà, specificandone la visibilità
• Non è possibile specificare un valore di default a causa del membro privato che non è presente
Nel costruttore della classe si può intervenire impostando il valore di default
C#
co
de
Tipi parziali (Partial Types)
• È possibile spezzare una dichiarazione in più files
Utile quando c’è un designer/generatore di codice
Ottimo anche per organizzare il codice
Una partial class per ogni interfaccia implementata
• Tipi supportati
Classes (Partial Classes)
Struct
Interface
• Divisi a design time, “fusi insieme” a compile time
C#
co
de
Partial Methods
• E’ stata aggiunta la possibilità di definire un metodo come “partial”
• Permette di definire un metodo in una parte della classe, e poterlo implementare in un’altra parte della classe
Utile in caso di uso dei generatori di codice
Non necessità di ereditarietà di metodi virtuali
• I metodi dichiarati come “partial” hanno delle limitazioni:
Devono essere definiti all’interno di una partial class
Devono sempre ritornare void
Possono avere argomenti, ma non con clausula “out”
Sono sempre implicitamente privati
• Se un metodo partial non viene implementato, questo non compare nel codice compilato (nemmeno la chiamata del metodo)
Contract Modeling
Type as a Contract
Class Declaration is useful to compiler during coding activity
Compiler ensure classes respecting Contract implementation
Contract is expressed in terms of Interface and Class members
Class Model=Contract
Every class express completly a contract
What is not expressed cannot be in the contract
Every class implements a contract. Possibilities:
completly
partially
extendibly
nothing
Polymorphysm
Contract implementation is not limited to ONE IMPLEMENETATION
Contract can have multiple implementations (or POLY MORPHS)
Many implementantions are different to give different
performances to the same contract
Polymorphism is implemented via inheritance
C#
co
de
Decorating contracts
• Statically typing and strong typing is a way to enforce intentions
• Methods can be decorated to better describe intentions
• Abstract: partial implementation
• Virtual: extendible implementation
• Sealed: complete implementation
• Public: contract
• Private: implementation
• Side effects
Protected: contract for inheritance implementation
Internal: contract for boundary implementation
Public and private
Public means contract
Private means implementation
Public and private definitions
Public class is a shared contract
Private class is an reserved implementation
A private implementation assolve at the end to a public contract
A contract cannot be private!
Not shared
It’s unuseful an object that doesn’t have a public function
A public implementation is a loose of encapsulation and responsibility
Completely implement a contract
A class that completly implements its contract can be instantiated
Side effect:
Languages allows a completly defined class not bein instantiated
No factory MethodsBah!
Factory MethodsOK!
Partially implement a contract
Class must be inherited
Some implementation details are missing
Contract detail are not missing
…to complete its implementation
Many “combination” of details can generate many implementations
Opportunity!
Side effect
Inheritance can extend contract, not change!
Extendibly implement a contract
(partial) implementation of the contract can be extended
Extension is done through override
Side effect
Implementation can change the behavior, not extend
Is a responsibility of the implementer
Language cannot ensure that
You are building a taxonomy
Polymorphysm implemented via
Inheritance
Inheritance is not functional to code reuse
There are many other ways to reuse code
Inheritance is functional to Polymorphysm
Single inheritance, not multiple (only C++ has)
“..is a…” relation
Being
No ambiguities
Inheritance is implementation hiding
«Less (you know) is better»
X is a class that inherits from A
Inheritance says:
X «derives from» A
X «is» A
X is able to do everything A is able to do
X can do the work in place where A is requested
Inheritance is reuse
«Inheritance is not functional to code reuse «
X and Y are two classes that inherits from A
X and Y can (not HAVE TO) extend contract
X and Y HAVE TO do work in place where A is requested, but…
…if X and Y are use independently you don’t need inheritance!
…writing a good contract…
Anemic Objects
Objects that contains just data, not behavior
This kind of objects have increased because of OR/M adoption
Business logic is just Entities manipulation, without any specification
Definition of object is not well defined if objects define the database or viceversa
These objects are typically serializable
ypically this object have no particular dependencies
Many consider this an anti-pattern!
http://www.martinfowler.com/bliki/AnemicDomainModel.html
Fluent Interfaces
Fluent interface become visible in objects that are made up of
public “empty”-returning methods
Each method is an action that change/evolve object state
Consequent invocations of that method become an awful,
unreadable code
The sequence of invocations is a sequence of states in which
object evolve
Better expressed with a chain of invocations
Interface Modeling
Law of Demeter
The Law of Demeter tries to restrict class interaction in order to minimize coupling among classes.
What that means is that the more objects you talk to, the more you run the risk of getting broken when one of them changes
In fact, according to the Law of Demeter for Methods, any method of an object should only call methods belonging to:
itself.
any parameters that were passed in to the method.
any objects it created.
any composite objects.
Cyclomatic Complexity
Cyclomatic complexity is a software metric (measurement). It was developed by Thomas J. McCabe, Sr. in 1976 and is used to indicate the complexity of a program. It is a quantitative measure of the complexity of programming instructions. It directly measures the number of linearly independent paths through a program's source code(http://en.wikipedia.org/wiki/Cyclomatic_complexity)
In all of our topics, «responsibility» is one of our strategies to lower cyclomaticcomplexity, closing decisions in lower levers of the application tree
A low CC:
Lower number of defects, because…
…allow better testability of software
«SOLID» apps
An app is «SOLID» when handles «well» changes during its lifetime
Maintainability have to be our first focus
Apps change and have not to be rewritten every time there is a
new specification
SOLID Principles
S SRP
Single responsibility principle “a class should have only a
single responsibility (i.e. only one potential change in the
software's specification should be able to affect the
specification of the class)
O OCPOpen/closed principle “software entities … should be open
for extension, but closed for modification.”
L LSP
Liskov substitution principle “objects in a program should be
replaceable with instances of their subtypes without
altering the correctness of that program.”
I ISPInterface segregation principle “many client-specific
interfaces are better than one general-purpose interface.”
D DIP
Dependency inversion principle one should “Depend upon
Abstractions. Do not depend upon concretions.”
Dependency injection is one method of following this
principle.
Coupling
You have two objects, a and b, of type A and B respectively
a «consume» b
Responsibility implies how much a knows about b
What does «knows» mean?
Contract
Instantiation
Lifetime
Contract … is good
Instantiation and Lifetime…are bad
Always?
Two different situations
A and B are classes from the same Domain
Not so much an issue
Probably you have control of the entire Domain
A and B comes from different Domains!
THAT’S AN ISSUE!!!!!!
Class not implement a contract
Extreme condition for a class
All members are abstract
Code-based inheritance for classes with all abstract members is wrong
At least, not so useful or a lost of opportunity
Use interfaces
Is an encapsulation of some method in a responsibility
Interface is declaration of some kind of responsibility
Interface implementation can be implicit or explicit
Side effect
Multiple interfaces can violate SOLID principles
C#
co
de
Interface based inheritance
• Multiple inheritanceimplementation
• “…has a…” relation
• Having
No doubt
Inheritance, Interaces, Reflection
and language
Inheritance is done via reflection
Is the invariant part of the state of an object
Implemented through v-tables
In C#, is operator have to be used
Is operator is statically typed, strongly typed
Reflection is runtime object introspection
Reflection “engine” is loosely typed, dynamically typed
Flexible…
…but not maintainable…
n-Tier layered architecture
A tier is a responsibility container
Tiers are «stacked»
A tier communicate with two layers, at most!
Tier-2
Tier-1
Tier-n
…
n-Tier
A tier is a responsibility container
Tiers are «stacked»
A tier communicate with two layers, at most!
Ok, not always true
Tier-2
Tier-1
Tier-n
…
n-Tier layered architecture
Concentrate domain code in one layer, isolated from user interface, application, and
infrastructure code.
Clean separation of concerns keeps the design of each layer easy to understand,
maintain and extend.
Domain objects (models and services) becomes focused on expressing the business
domain.
Three Tier
Three is the most famous standard
n-Tier configuration
How do tiers communicate each other?
Define responsibility between layers
Have responsibility for «lower» layer
Consume responsibility by «top» layer
Business Logic
Data Access
PresentationData
Contracts and Development Teams
«Three» teams can develop independently, if they agree
on Contracts
Contract DA/BL
Contract BL/P
Interfaces and Layers
Layers communicate each other via
contracts/interfacesBusiness Logic
Data Access
Presentation
Contract DA/BL
Contract BL/P
Instantiation
An object is created from class through instantiation
Instantiation is memory management…
Reservation (in stack)
Allocation (in heap)
That memory is organized as classes describe
C#
co
de
Factory Methods
• Classes are instantiated via new operator
• New has two problems
Highly coupling
Not delegable in case of non-default constructor with parameters
Impossible delegating new operator
• Patterns comes in help
Creational Patterns
A function/method that create an object
Physically separate (hide) new operator from outside
Lifetime
b is an object and must be created
What creates b? When b is created?
a
a creates b internally
a has a reference to b
a has to «destroy» b
Context(a)
Context(a) creates b
a has reference to Context(a)
Context(a) has to «destroy» b
a has not to «destroy» b
C#
co
de
Singletons
• Singletons are single instances for single apps
• It’s a way to decouple global scope from language/technology specific contexts
C#
co
de
Inversion of Control (IoC)
• What is «inverted»?
• Imperative: «I instantiate B to have b» (because I need b)
• Declarative: «I need b of type B»
Who can answer me?
If I need B and I receive BB, that derives from B, is the same, because BB is compatible with B
• So inversion is another aspect of declarative (and responsibility):
Declare your needs
Then
Find (actively declare)locator service
Ask (passively declare)autowiring
Decorating Contracts
Declare your need «outside» member
Around
We can say «not by code»
This is Aspect Oriented Programming
Program, at runtime, can inspect code if some member(s) are
decorated with an «aspect»
C#
co
de
Attributi
• Permettono di associare metadati agli elementi di definizione di una classe (classe, metodo, variabile, proprietà, …)
• Sono informazioni disponibili a runtime tramite reflection
<object>.GetType().GetMember()
• Permettodo di implementare algoritmi basati sulla struttura stessa della classe, decidendo in base agli attributi
Un esempio su tutti: serializzazione
• Atttributi Standard (dalla BCL)
• Attributi Custom
Classi derivate da System.Attribute
• Accessibili tramite Attribute.GetCustomAttribute(<memberinfo>)
• Sintassi:
[<attribute>Attribute(positional parameters, named parameters….)]
Blueprints for objects: patterns
Blueprints for objects: patterns
How do you use all these things?
How do you build up a class?
I’m the first that ever build an object?
Experience from many, not just one
Many have collected experiences
Experiences are collected as patterns
Patterns grouped by usage
Design Patterns
(Gand of our, Gamma et al)
http://en.wikipedia.org/wiki/Design_Patterns
Patterns of Enterprise Application Architecture
(Martin Fowler)
http://martinfowler.com/eaaCatalog/index.html
Object Oriented Design
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Cloud Computing Patterns
http://www.cloudcomputingpatterns.org/
Domain Driven Design
http://en.wikipedia.org/wiki/Domain-driven_design
Experience from many
dogmas from no one
All patterns are effective experience…
…for most of the “standard” situations!
Every situation have to be verified because many parameters can
influence how to choose
Performances
Correctness
Inside a domain and a process
inside a domain and in a process
When we speak about objects for a biz, we refer tipically to a
domain object
When we speak about objects, we talk about “in-memory” objects
You need to “name” some data. You
need…
…an entity object
An Entity map all properties to columns into a table
An Entity has some columns that means “business key”
If an “int” or “long” key is used, we speak about “surrogate key”
An entity is an object that is recognized by an identity key
Two entity objects are equals if identity keys are equal
If two entity objects, with the same identity, but different values, are concurrent
Distinguished by its identity attributes.
Equal attribute values doesn’t indicate Identical objects.
Non equal attribute values doesn’t indicate Non Identical objects
Same real-world thing might / might not be represented as an entity in a domain model
Identity might / might not be of interest to the application user
You need to handle some data. You
need…
…a value object
All single pieces are needed to identify data
A value object is an object that is identified by values tuple of its properties
Two objects are the same objects if of the same type and all values, by properties, are equal
Value object has no identity
Value object is identified by all its specific values
Value object cannot live outside another object
Describes the characteristics of a thing.
Represents a descriptive aspect of the domain with no conceptual identity.
Value objects can reference Entity objects
Value objects are interchangeable.
Value objects are immutable (name shouldn’t change in every person)
Usually found by traversal from some entity.
Finding a Value with specific properties = Creating a new instance with the same properties.
You need to track changes to entities.
You need…
…a Unit of Work
A Unit of Work keeps track of everything you do during a business
transaction that can affect the database. When you're done, it
figures out everything that needs to be done to alter the database
as a result of your work.
Contains original values copies of objects just after loaded
Undestand value changes and performs operations back to the db
You have to do prepare an Entity for the
presentation. You need…
…a ViewModel
Is a model of an entity optimized for UI
No Database-like references
An entity object is not suitable for universal usage
No localization
Data already decoded
Data already loaded (if good to)
A ViewModel is typically an “pure” “language” object
Minimize (down to zero) needs of getting other data from other sources
You have to consune a View Model in
presentation. You need…
…a View
An object that get data from VieModel and put in the UI
How to put data in UI?
Explicit Copy values
Data Binding
A View is typically a “technology” object
It depends from a UI framework
You need to do some actions on a graph
of entities. You need…
…an aggregate root
An object that excapsulates all entities inside without exposing them outside (no ref for entities)
Aggregate Root is an entity object (called “root”) that guarantee consistency of the entity in the system
Exposes an API for acttions to be perfomed on entities
No mixing between actions and queries
The aggregate root guarantees the consistency of changes being made within the aggregate by forbidding external objects from holding references to its members.
A cluster of associated objects treated as a unit for the purpose of data change
Has a root (Entity) and a boundary (defines what is inside)
Root entity has a global identity
Non-Root entities have local identity
Nothing outside the aggregate boundary can hold a reference to anything inside, except to the root entity
Only aggregate roots can be obtained directly with database queries.(other objects must be found by traversal of associations)
Root entity can expose references to the internal entities. Usage is only transient, and references shouldn’t be held
Objects within an aggregate can hold references to other aggregate roots
A delete operation removes everything within the aggregate boundary at once. (cascade delete)
You need to persist an aggregate. You
need a…
…Repository Object
isolates domain objects from details of the database access code
A Repository mediates between the domain and data mapping
layers, acting like an in-memory domain object collection
providing a more object-oriented view of the persistence layer
Outside process
Outside process or domain
Inside objects
When we speak about objects for a biz, we refer tipically to a domain object
When we speak about objects, we talk about “in-memory” objects
When we get out a domain, we can get out layers also…
…and we get many “non functional” aspect to handle
Serialization
Communication
Performances
You need to perform a “call” on a remote
aggregate root, through boundaries
You need a command
Command object is a object that assert an intention to an action
All values assigned to properties specify parameters of the intention of the command
Typically, this kind of objects are flat (not complex)
Typically this object have no particular dependencies
If you have
<someobject>.DoSomething(args)
Model as
Class DoSomethingCommand{
public <args>}
Default constructor
Simple types
You need to handle requests from outside
a domain. You need…
…a Service object
It avoids many details (implementation, lifetime, instantiation)
It’s just “contract”
Refer to an activity (verb) rather than an entity (noun).
Services are stateless.
You need to handle a request from
outside process
A service objects have to be encapsulated inside a boundary that
can handle a request
An objects that maps a request into an usable object
That objects is a Controller
The type of request shapes the type of object request is mapped
on
You need some data to decide. You
need…
…a Data Transfer Object
An object that carries data between processes in order to reduce
the number of method calls
(http://martinfowler.com/eaaCatalog/dataTransferObject.html)
An aggregate of information
A mono-directional object optimized for data presentation
Typically is a result of mapping of a generic query from a
datasource
How can you obtain a DTO? You can
use…
…a Data Source object
An object that prepare DTO for you
All different requests are already defined
You need to notify externally from an aggregate
root that something has happened. You need…
…an event object
Event object is an object that notify execution of an action
All values assigned to properties define the keys to reach the
context where action was executed
Typically, this kind of object is flat (not complex)
Writing good C# code
for good cloud applications
2014 Edition
Marco Parenzan