Tutte le novità di ASP.NET MVC3: Slide e codice dell'evento

datelunedì 30 maggio 2011 alle 22.33  - posted by Manuel Scapolan in ASP.NET | Eventi | Patterns And Principles

Di seguito potete trovare le slide e il codice della mia sessione su Tutte le novità di ASP.NET MVC3.

Nota: Per eseguire il codice di esempio è necessario modificare i percorsi del file database che trovate nell'App_Data.
Codice di esempio pronto per il download >>
codice esempio

tagsTags: ,

Non commentare il codice, rendilo più leggibile con le Fluent Interface

dategiovedì 31 marzo 2011 alle 20.59  - posted by Manuel Scapolan in Patterns And Principles

Ad ognuno di noi sarà capitato almeno una volta di leggere una porzione di codice e di non riuscire a capirne la logica. Tra le cause oltre al cattivo design c’è quasi sempre la mancanza di commenti o di documentazione. Ma quanti di noi commentano il codice che scrivono? Intendiamoci è una buona regola commentare il codice, ma è un’attività talmente noiosa che diventa inutile se poi non manteniamo il commento aggiornato.
 
Vediamo allora come applicando le “Fluent Interface” possiamo scrivere del codice che si commenta da solo!
 
Una interfaccia è “fluente” quando ci consente di rendere il codice implementativo leggibile come le righe di un romanzo oppure come le strofe di una poesia. Tale caratteristica non è soggettiva, ma si può ottenere facilmente partendo dalla tecnica del method chaining.
Il method chaining, ovvero la possibilità di concatenare le chiamate ai metodi di una interfaccia, si ottiene definendo come valore di ritorno l’istanza corrente della classe a cui appartiene il metodo.
 
Con un po’ di codice tutto sarà più chiaro. Vediamo quindi un esempio di interfaccia non “fluente” che riguarda la prenotazione di un biglietto ferroviario. Partiamo con la classe Train:
namespace FluentInterface.Model.NoFluent
{
    using System;
    using System.Text;

    public class Train
    {
        public string Number { get; set; }

        public string DepartureStation { get; set; }

        public string Destination { get; set; }

        public DateTime DepartureDate { get; set; }

        public int Class { get; set; }

        public Train(){ }

        public Train(string number, 
                     string departureStation, string destination, 
                     DateTime departureDate, int _class)
        {
            this.Number = number;
            this.DepartureStation = departureStation;
            this.Destination = destination;
            this.DepartureDate = departureDate;
            this.Class = _class;
        }
    }
}

 Nel codice cliente andiamo poi a prenotare il biglietto per un particolare treno:

bookingService.PlaceBookingFor(
            new Train("9513", 
                      "Milano C.le", 
                      "Roma Termini", 
                      DateTime.Parse("2010/02/12 8:20"), 1)
);

Come possiamo notare il codice non è per niente leggibile, dobbiamo infatti ricorrere alla definizione del costruttore della classe per capire il significato dei parametri passati.

Grazie agli object initializer introdotti con la versione 3.0 di C# il codice si fa più chiaro, ma rimane ancora pesante da leggere:
bookingService.PlaceBookingFor(
    new Train()
    { 
      Number = "9513",
      DepartureStation = "Milano C.le",
      Destination = "Roma Termini",
      DepartureDate = DateTime.Parse("2010/02/12 8:20"),
      ClassNumber = 1
    }   
);

Vediamo quindi come una interfaccia “fluente” può rendere questo codice più leggibile:

namespace FluentInterface.Model.Fluent
{
    using System;
    using System.Text;

    public enum Class 
    {
        First = 1,
        Second = 2,
        Third = 3
    }

    public class Train
    {
        public string Number { get; set; }

        public string DepartureStation { get; set; }

        public string Destination { get; set; }

        public DateTime DepartureDate { get; set; }

        public int ClassNumber { get; set; }

        public Train(){ }

        public Train(string number, 
                     string departureStation, string destination, 
                     DateTime departureDate, int classNumber)
        {
            this.Number = number;
            this.DepartureStation = departureStation;
            this.Destination = destination;
            this.DepartureDate = departureDate;
            this.ClassNumber = classNumber;
        }

        #region Fluent Interface
        public Train Nr(string number)
        {
            this.Number = number;
            return this;
        }

        public Train From(string departureStation)
        {
            this.DepartureStation = departureStation;
            return this;
        }

        public Train To(string destination)
        {
            this.Destination = destination;
            return this;
        }

        public Train DepartureAt(DateTime departureDate)
        {
            this.DepartureDate = departureDate;
            return this;
        }

        public Train DepartureAt(string departureDate)
        {
            this.DepartureDate = DateTime.Parse(departureDate);
            return this;
        }

        public Train In(Class _class)
        {
            this.ClassNumber = (int)_class;
            return this;
        }
        #endregion
    }
}

 Vediamo come cambia il nostro codice cliente per quanto riguarda la prenotazione di un biglietto ferroviario:

bookingService.PlaceBookingFor(new Train().Nr("9513")
                                          .From("Milano C.le")
                                          .To("Roma Termini")
                                          .DepartureAt("12/2/09 8:20")
                                          .In(Class.First));

Possiamo migliorare ancora trasformando il metodo Nr in una “static factory”, ovvero implementando al suo interno la creazione di una istanza della classe Train, così:

public static Train Nr(string number)
{
   Train train = new Train();
   train.Number = number;
   return train;
}

La differenza rispetto al codice di prima è minima, ma evidente:

bookingService.PlaceBookingFor(Train.Nr("9513")
                                    .From("Milano C.le")
                                    .To("Roma Termini")
                                    .DepartureAt("12/02/2009 8:20")
                                    .In(Class.First));

In conclusione ci sono molti modi per aiutare noi stessi e altri programmatori a capire che cosa fa il nostro codice, il più importante di tutti rimane sempre il commento, ma le fluent interface sono un valido alleato per combattere le lunghe sedute davanti al reflector!

Model View Controller: slide e demo disponibili per il download

datemercoledì 16 dicembre 2009 alle 21.12  - posted by Manuel Scapolan in ASP.NET | Castle Project | Patterns And Principles | Eventi

Per chi fosse interessato sono disponibili per il download le slide e la demo dell'evento di giovedì scorso organizzato da 1nn0va sul Model View Controller. Nella demo i progetti di esempio con il confronto tra WebForms, ASP.NET MVC e MonoRail.

Per scaricare i file cliccare sui link qui sotto:

Il programmatore con solidi principi

datedomenica 28 giugno 2009 alle 9.35  - posted by Manuel Scapolan in Patterns And Principles

Programmare per alcuni è un'arte, un esercizio di creatività che non può essere limitato da regole e schemi, una definizione però che non tiene conto degli obiettivi che un programmatore deve perseguire nello scrivere "buon codice", ovvero mantenibilità, estendibilità, scalabilità, stabilità, etc. Per raggiungere questi obiettivi e non perdere la bussola dobbiamo avere dei solidi principi:

  • S - Single Responsibility Principle
  • O - Open/Closed Principle
  • L - Liskov Substitution Principle
  • I - Interface Segregation Principle
  • D - Dependency Inversion Principle

Ecco i principi che aiutano il programmatore ad ottenere una "buona" programmazione ad oggetti:

Single Responsibility Principle (SRP)

Ogni classe deve essere disegnata per svolgere bene un solo compito, avere una sola responsabilità, in pratica una classe deve avere un solo motivo per cambiare. Seguire questo principio porta automaticamente ad avere un basso accoppiamento.

Open/Closed Principle (OCP)

Una classe deve essere aperta alle estensioni, ma chiusa alle modifiche. Dobbiamo quindi essere in grado di estendere il comportamento di una classe senza modificarne l'implementazione (aka codice sorgente). Come? Facendo uso di classi astratte o interfacce, ovvero sfruttando il polimorfismo.

Liskov Substitution Principle (LSP)

Una funzione che utilizza un riferimento ad una classe base deve poter utilizzare al suo posto una qualsiasi delle classi derivate senza conoscerne l'implementazione. In pratica non dobbiamo modificare in alcun modo il comportamento di una classe base in una derivata. Una via potrebbe essere preferire dove possibile la composizione all'ereditarietà, ponendosi ogni volta la fatidica domanda IS A or HAS A?

Interface Segregation Principle (ISP)

Una classe non deve implementare una interfaccia che non usa o che usa parzialmente. Molte volte si deve preferire più interfacce con una sola funzionalità ad un'unica interfaccia che fa tutto. Il motivo? Una classe è influenzata dal cambiamento di una interfaccia anche se non la usa.  

Dependency Inversion Principle (DIP)

Si basa sul concetto che una classe di un alto livello non deve dipendere dall'implementazione di classi o entità di un livello inferiore. In pratica per raggiungere tale scopo devo progettare le classi pensando alle interfacce e non alle implementazioni. Questo porta ad avere non solo un basso accoppiamento tra i livelli della mia architettura, ma automaticamente a poter sostituire l'implementazione di un livello inferiore senza pregiudicare il funzionamento di quelli superiori.

 

In conclusione questi principi aiutano il programmatore, laddove non arriva l'esperienza, ad ottenere un codice di qualità che mantenga una forte coesione ed un basso accoppiamento tra le entità del sistema. Non devono però diventare un dogma, ma uno strumento da conoscere e da utilizzare a seconda degli obiettivi e dei requisiti applicativi.

Link utili

About me

manuel scapolanSono un consulente informatico. Nel 2004 terminati gli studi in Ingegneria Informatica (1° livello), ho iniziato come freelance collaborando con una ditta di consulenza informatica ed una agenzia di marketing e comunicazione nello sviluppo di applicazioni web. Attualmente divido il lavoro di sviluppatore e progettista web con attività di formazione nel settore della programmazione.
View Manuel Scapolan's profile on LinkedIn

Follow me on Follow manuelscapolan on Twitter
Member of:
innova

Calendario


<<  febbraio 2012  >>
lumamegivesado
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

Disclaimer

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati mediante:
creative commons
Attribuzione: Non commerciale
Condividi allo stesso modo. R.2.5

Books (a bit more about my library)

Domain Driven Design - Eric Evans Applying Domain-Driven Design and Patterns - Jimmy Nilsson Refactoring to Patterns - Joshua Kerievsky Design Patterns -  Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides Code Complete Second Edition - Steve McConnell Patterns of Enterprise Application Architecture - Martin Fowler Agile Principles, Patterns, and Practices in C# - Robert C. Martin xUnit Test Patterns - Gerard Meszaros Refactoring - Martin Fowler CLR via C# Second Edition - Jeffrey Richter Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries - Krzysztof Cwalina, Brad Abrams Don't make me think! - Steve Krug Bulletproof Ajax - Jeremy Keith

Manuel Scapolan Copyright © 2007 - 2010 - Tutti i diritti riservati - Powered by BlogEngine.NET 1.5.0.7 - silk icons by famfamfam - Time CET