SlideShare a Scribd company logo
1 of 71
SOLID Principles
        Chris Weldon
     Improving Enterprises
Me

•   Fightin’ Texas Aggie

•   .Net and PHP Developer

•   UNIX and Windows Sysadmin

•   Senior Consultant at Improving Enterprises

•   Contact Me: chris@chrisweldon.net
Agile, Microsoft, Open Technologies, UX
Applied Training, Coaching, Mentoring
Certified Consulting
Rural Sourcing
Recruiting Services
What is OOD?
Abstraction



  What is OOD?
Abstraction   Inheritance



  What is OOD?
Abstraction     Inheritance



   What is OOD?
Encapsulation
Abstraction      Inheritance



   What is OOD?
Encapsulation   Polymorphism
What is SOLID?
?
SOLID is not a law
An Order
public class Order
{
    private int _id;
    private int _userId;
    private Product[] _products;

    public int getId() {
        return this._id;
    }

    public void setId(int id) {
        this._id = id;
    }

    public int getUserId() {
        return this._userId;
    }

    public void setUserId(int userId) {
        this._userId = userId;
    }
public Product[] getProducts() {
    return this._products;
}

public void addProduct(Product product) {
    this._products.add(product);
}

public void setProducts(Product[] products) {
    this._products = products;
}
private DBConnection _db;

public Order()
{
    // Read from configuration to get connection string.
    string connectionString = string.Empty;
    Handle fileHandle = fopen("/etc/database/app.config", "r");
    while (string row = readLine(fileHandle)) {
        if (row.StartsWith("dbo")) {
            connectionString = row;
        }
    }
    fclose(fileHandle);
    this._db = new DBConnection(connectionString);
}
public static Order CreateOrder(int userId, Product[] products)
    {
        Order order = new Order();
        order.setUserId(userId);
        order.setProducts(products);
        return order;
    }

    public static Order getOrderById(int orderId)
    {
        if (orderId == null || orderId < 0)
        {
            DBCommand command = this._db.exec("SELECT * FROM orders");
            Order[] results = this._db.getResults(command);

            // Get the first result.
            return results[0];
        }

        DBCommand command = this._db.exec("SELECT * FROM orders WHERE id
= ?", orderId);
        Order order = this._db.getSingle($command);
        return order;
    }
public void deliverOrder()
{
    try {
        WebServiceConnection networkConnection =
            new WebServiceConnection("http://shpt1/shipctrl.svc");
        networkConnection->open();
        ShippingManager shippingManager =
             new ShippingManager(networkConnection);
        shippingManager.setOrder(this);
        shippingManager.setDeliveryType(DeliveryType.EXPRESS);
        shippingManager.shipViaWebService();

        this.notifyCustomer();
    } catch (Exception e) {
        Handle logFile = fopen("/tmp/logfile.log", "a");
        fwrite("An error occurred while delivering the order.", logFile);
        fclose(logFile);
    }
}
public void notifyCustomer()
    {
        try {
            mailer = new Mailer();
            mailer.setFrom(“orders@chrisweldon.net”, “Grumpy Baby Orders”);
            mailer.setSubject(“Order #” + this.getId() + “ out for
Delivery”);
            mailer.setBodyText(“Your order is being shipped!”);
            mailer.send();
        } catch (Exception $e) {
            Handle logFile = fopen("/tmp/logfile.log", "a");
            fwrite("An error occurred while emailing the notice.", logFile);
            fclose(logFile);
        }
    }
}
OMG
Next Sample
public void ActivateDrillBit(string customerOption) {
    if (customerOption == "small") {
        SmallBit drillBit = new SmallBit();
        drillBit.activate();
    } else if (customerOption == "medium") {
        MediumBit drillBit = new MediumBit();
        drillBit.activate("120hz");
    } else if (customerOption == "large") {
        LargeBit drillBit = new LargeBit();
        drillBit.activate("240hz", Options.Water);
    }
}
Requirements Change!
 Customer Needs to Specify Options
public void ActivateDrillBit(string customerOption, string freq,
Options options) {
    if (freq == "") freq = "240hz";
    if (options == null) options = Options.NoWater;
    if (customerOption == "small") {
        SmallBit drillBit = new SmallBit();
        drillBit.activate(freq, options);
    } else if (customerOption == "medium") {
        MediumBit drillBit = new MediumBit();
        drillBit.activate(freq, options);
    } else if (customerOption == "large") {
        LargeBit drillBit = new LargeBit();
        drillBit.activate(freq, options);
    }
}
You
 Broke
  My
  App
!@#!@
public class DrillBitActivator {
    public void ActivateDrillBit(string customerOption) {
        // ...
    }
}

public class DrillBitConfigurableActivator : DrillBitActivator {
    public DrillBitConfigurableActivator(string freqency, Options options) {
        // Configurable!
    }

    public override function ActivateDrillBit(string customerOption) {
        // ...
    }
}
public function ActivateDrillBit(string customerOption)
    IDrillBit .drillBit = DrillBitFactory::CreateDrillBit(customerOption);
    drillBit.activate(this._freq, this._options);
}
Next:
A Familiar Example
public interface IManageCustomers {
    void TakeSpecifications(Specs specs);
    void ReviewSpecifications(Specs specs);
    void GiveToEngineers(Specs specs);
    void DealWithTheGoshDarnCustomers();
    bool IsPeoplePerson();
}
public class GoodManager : IManageCustomers {
    public void TakeSpecifications(Specs specs) {
        this.ReviewSpecifications(specs);
    }

    public void ReviewSpecifications(Specs specs) {
        // If specs seem good.
        this.GiveToEngineers(specs);
    }

    public void GiveToEngineers(Specs specs) {
        // E-mails specs to engineers.
    }

    public void DealWithTheGoshDarnCustomers() {
        // You better believe he does.
    }

    public bool IsPeoplePerson() {
        return true; // Absolutely!
    }
}
public class Tom : IManageCustomers {
    public void TakeSpecifications(Specs specs) {
        throw new DelegateToSecretary();
    }

    public void ReviewSpecifications(Specs specs) {
        throw new DelegateToSecretary();
    }

    public void GiveToEngineers(Specs specs) {
        throw new DelegateToSecretary();
    }

    public void DealWithTheGoshDarnCustomers() {
        // Your gosh darn right I do!
    }

    public bool IsPeoplePerson() {
        return true; // I AM a people person, dammit!
    }
}
public interface ITakeSpecifications {
    function TakeSpecifications(Specs specs);
}

public interface IReviewSpecifications {
    function ReviewSpecifications(Specs specs);
}

public interface IGiveToEngineers {
    function GiveToEngineers(Specs specs);
}

public interface IManageCustomers {
    function DealWithTheGoshDarnCustomers();
    function IsPeoplePerson();
}
public class GoodManager :
    IManageCustomers, ITakeSpecifications, IReviewSpecifications, IGiveToEngineers
{
    public void TakeSpecifications(Specs specs) {
        this.ReviewSpecifications(specs);
    }

    public void ReviewSpecifications(Specs specs) {
        // If specs seem good.
        this.GiveToEngineers(specs);
    }

    public void GiveToEngineers(Specs $specs) {
        // E-mails specs to engineers.
    }

    public void DealWithTheGoshDarnCustomers() {
        // You better believe he does.
    }

    public bool IsPeoplePerson() {
        return true; // Absolutely!
    }
}
public class Tom : IManageCustomers {
    public void DealWithTheGoshDarnCustomers() {
        // Your gosh darn right I do!
    }

    public bool IsPeoplePerson() {
        return true; // I AM a people person, dammit!
    }
}
Next Up
public interface IDataResource
{
    void Load();
    void Save();
}
public class AppSettings : IDataResource {
    public void Load() {
        // Load application settings.
    }

    public void Save() {
        // Save application settings.
    }
}
public class UserSettings : IDataResource {
    public void Load() {
        // Load user settings.
    }

    public void Save() {
        // Save user settings.
    }
}
static IDataResource[] LoadAll() {
    IDataResource[] resources = new IDataResource[2] {
        new AppSettings(),
        new UserSettings()
    };

    foreach (IDataResource resource in resources) {
        resource.Load();
    }

    return resources;
}

static void SaveAll(IDataResource[] resources) {
    foreach (IDataResource resource in resources) {
        resource.Save();
    }
}
Our “Duck”
public class UnsaveableSettings : AppSettings {
    public override void Load() {
        // Loads settings.
    }

    public override void Save() {
        throw new CannotSaveException();
    }
}
static IDataResource[] LoadAll() {
    IDataResource[] resources = new IDataResource[3] {
        new AppSettings(),
        new UserSettings(),
        new UnsaveableSettings()
    };

    foreach (IDataResource resource in resources) {
        resource.Load();
    }

    return resources;
}

static void SaveAll(IDataResource[] resources) {
    foreach (IDataResource resource in resources) {
        if (resource is UnsaveableSettings) continue;

        resource.Save();
    }
}
public interface IDataResource
{
    void Load();
}

public interface ISaveResource
{
    void Save();
}
public class AppSettingsLoaderBase : IDataResource {
    public function Load() {
        // Load application settings.
    }
}
public class AppSettings extends AppSettingsLoaderBase
    implements ISaveResource {
    public function Save() {
        // Save application settings.
    }
}
public class UnsaveableSettings extends AppSettingsLoaderBase {
    public override void Load() {
        // Loads settings.
    }
}
static IDataResource[] LoadAll() {
    IDataResource[] resources = new IDataResource[3] {
        new AppSettings(),
        new UserSettings(),
        new UnsaveableSettings()
    };

    foreach (IDataResource resource in resources) {
        resource.Load();
    }

    return resources;
}

static void SaveAll(ISaveResource[] resources) {
    foreach (ISaveResource resource in resources) {
        resource.Save();
    }
}
Final Problem
public class Authenticator {
    private DataAccessLayer _repository;

    public DataAccessLayer() {
        this._repository = new DataAccessLayer();
    }

    public bool authenticate(string username, string password) {
        string hashedPassword = md5(password);
        User user = this._repository.findByUsernameAndPassword(
            username, hashedPassword);
        return user == null;
    }
}
Problems?
Problems?
          Authenticator
      authenticate() : bool




        DataAccessLayer
findByUsernameAndPassword : array
Problems?
                Authenticator
            authenticate() : bool




              DataAccessLayer
      findByUsernameAndPassword : array



Strongly coupled to DataAccessLayer
class Authenticator {
    private DataAccessLayer _repository;

    public Authenticator(DataAccessLayer repository) {
        this._repository = repository;
    }

    public bool authenticate(string username, string password) {
        string hashedPassword = md5(password);
        User user = this._repository.findByUsernameAndPassword(
            username, hashedPassword);
        return user == null;
    }
}
Dependency Inversion


•   “High-level modules should not depend upon low level modules. They
    should depend upon abstractions.

•   “Abstractions should not depend upon details. Details should depend
    upon abstractions.”
                                                           Robert Martin
Combine Principles!
public interface IUserRepository {
    User findByUsernameAndPassword(string username, string password);
}
public class DataAccessLayer : IUserRepository {
    public User findByUsernameAndPassword(string username, string password) {
        // Do some database stuff.
    }
}
class Authenticator {
    private IUserRepository _repository;

    public Authenticator(IUserRepository repository) {
        this._repository = repository;
    }

    public bool authenticate(string username, string password) {
        string hashedPassword = md5(password);
        User user = this._repository.findByUsernameAndPassword(
            username, hashedPassword);
        return user == null;
    }
}
Comparison
Comparison

          Authenticator
      authenticate() : bool




        DataAccessLayer
findByUsernameAndPassword : array
Comparison

          Authenticator
      authenticate() : bool




        DataAccessLayer
findByUsernameAndPassword : array
Comparison
                                                 Authenticator
                                             authenticate() : bool

          Authenticator
      authenticate() : bool

                                                IUserRepository
                                       findByUsernameAndPassword : array

        DataAccessLayer
findByUsernameAndPassword : array

                                               DataAccessLayer
                                       findByUsernameAndPassword : array
Benefit: Flexibility
public class WebServiceUserRepository : IUserRepository {
    public User findByUsernameAndPassword(string username, string password) {
        // Fetch our user through JSON or SOAP
    }
}

public class OAuthRepository : IUserRepository {
    public User findByUsernameAndPassword(string username, string password) {
        // Connect to your favorite OAuth provider
    }
}
Thank You!



Check improvingaggies.com   http://spkr8.com/neraath

More Related Content

What's hot

Oleksandr Valetskyy - DI vs. IoC
Oleksandr Valetskyy - DI vs. IoCOleksandr Valetskyy - DI vs. IoC
Oleksandr Valetskyy - DI vs. IoCOleksandr Valetskyy
 
Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Kevin Octavian
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTruls Jørgensen
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)Yurii Kotov
 
Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020Jerry Liao
 
Anton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightAnton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightMichael Pustovit
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennPaintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennJavaDayUA
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42Yevhen Bobrov
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityWashington Botelho
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperJonathan Wage
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring DataOliver Gierke
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMJonathan Wage
 
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...Cloudera, Inc.
 

What's hot (20)

Oleksandr Valetskyy - DI vs. IoC
Oleksandr Valetskyy - DI vs. IoCOleksandr Valetskyy - DI vs. IoC
Oleksandr Valetskyy - DI vs. IoC
 
Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1Windows 8 Training Fundamental - 1
Windows 8 Training Fundamental - 1
 
Testdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinnerTestdrevet javautvikling på objektorienterte skinner
Testdrevet javautvikling på objektorienterte skinner
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020
 
Phactory
PhactoryPhactory
Phactory
 
Anton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightAnton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 light
 
An intro to cqrs
An intro to cqrsAn intro to cqrs
An intro to cqrs
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Di and Dagger
Di and DaggerDi and Dagger
Di and Dagger
 
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp KrennPaintfree Object-Document Mapping for MongoDB by Philipp Krenn
Paintfree Object-Document Mapping for MongoDB by Philipp Krenn
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 
Easy Button
Easy ButtonEasy Button
Easy Button
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrity
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring Data
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
 
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
 

Viewers also liked

Don't be STUPID, Grasp SOLID - North East PHP
Don't be STUPID, Grasp SOLID - North East PHPDon't be STUPID, Grasp SOLID - North East PHP
Don't be STUPID, Grasp SOLID - North East PHPAnthony Ferrara
 
Properties of solids sydney
Properties of solids sydneyProperties of solids sydney
Properties of solids sydneyJenny Pickett
 
Software_Architectures_from_SOA_to_MSA
Software_Architectures_from_SOA_to_MSASoftware_Architectures_from_SOA_to_MSA
Software_Architectures_from_SOA_to_MSAPeter Denev
 
Tang 06 valence bond theory and hybridization
Tang 06   valence bond theory and hybridizationTang 06   valence bond theory and hybridization
Tang 06 valence bond theory and hybridizationmrtangextrahelp
 
Mechanical properties
Mechanical propertiesMechanical properties
Mechanical propertiesYatin Singh
 
Assignment on mech properties in torsion1
Assignment on mech properties in torsion1  Assignment on mech properties in torsion1
Assignment on mech properties in torsion1 Ezhum Barithi
 
Tang 10 structure and properties of solids
Tang 10   structure and properties of solidsTang 10   structure and properties of solids
Tang 10 structure and properties of solidsmrtangextrahelp
 
What Are The 5 W’s
What Are The 5 W’sWhat Are The 5 W’s
What Are The 5 W’sSimon Jones
 
Mechanical Properties of matter
Mechanical Properties of matterMechanical Properties of matter
Mechanical Properties of matterphysics101
 

Viewers also liked (13)

Don't be STUPID, Grasp SOLID - North East PHP
Don't be STUPID, Grasp SOLID - North East PHPDon't be STUPID, Grasp SOLID - North East PHP
Don't be STUPID, Grasp SOLID - North East PHP
 
SOLID design
SOLID designSOLID design
SOLID design
 
Properties of solids sydney
Properties of solids sydneyProperties of solids sydney
Properties of solids sydney
 
Software_Architectures_from_SOA_to_MSA
Software_Architectures_from_SOA_to_MSASoftware_Architectures_from_SOA_to_MSA
Software_Architectures_from_SOA_to_MSA
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
Tang 06 valence bond theory and hybridization
Tang 06   valence bond theory and hybridizationTang 06   valence bond theory and hybridization
Tang 06 valence bond theory and hybridization
 
Mechanical properties
Mechanical propertiesMechanical properties
Mechanical properties
 
Assignment on mech properties in torsion1
Assignment on mech properties in torsion1  Assignment on mech properties in torsion1
Assignment on mech properties in torsion1
 
crystalstructure
crystalstructurecrystalstructure
crystalstructure
 
Tang 10 structure and properties of solids
Tang 10   structure and properties of solidsTang 10   structure and properties of solids
Tang 10 structure and properties of solids
 
What Are The 5 W’s
What Are The 5 W’sWhat Are The 5 W’s
What Are The 5 W’s
 
SOLID in PHP
SOLID in PHPSOLID in PHP
SOLID in PHP
 
Mechanical Properties of matter
Mechanical Properties of matterMechanical Properties of matter
Mechanical Properties of matter
 

Similar to SOLID Principles

Solid Software Design Principles
Solid Software Design PrinciplesSolid Software Design Principles
Solid Software Design PrinciplesJon Kruger
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietyChris Weldon
 
CDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCaelum
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv Startup Club
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo Ali Parmaksiz
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptSeok-joon Yun
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT TalkConstantine Mars
 
Architecture Components
Architecture Components Architecture Components
Architecture Components DataArt
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETtdc-globalcode
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mockskenbot
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatissimonetripodi
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Dimitrios Platis
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionChristian Panadero
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data BindingEric Maxwell
 

Similar to SOLID Principles (20)

Solid Software Design Principles
Solid Software Design PrinciplesSolid Software Design Principles
Solid Software Design Principles
 
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO ProprietySOLID - Not Just a State of Matter, It's Principles for OO Propriety
SOLID - Not Just a State of Matter, It's Principles for OO Propriety
 
CDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptorCDI e as ideias pro futuro do VRaptor
CDI e as ideias pro futuro do VRaptor
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Architecture components - IT Talk
Architecture components - IT TalkArchitecture components - IT Talk
Architecture components - IT Talk
 
Architecture Components
Architecture Components Architecture Components
Architecture Components
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatis
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]Writing SOLID C++ [gbgcpp meetup @ Zenseact]
Writing SOLID C++ [gbgcpp meetup @ Zenseact]
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
Effective Android Data Binding
Effective Android Data BindingEffective Android Data Binding
Effective Android Data Binding
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 

More from Chris Weldon

REST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkREST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkChris Weldon
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareChris Weldon
 
Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Chris Weldon
 

More from Chris Weldon (6)

Keat presentation
Keat presentationKeat presentation
Keat presentation
 
REST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend FrameworkREST Easy - Building RESTful Services in Zend Framework
REST Easy - Building RESTful Services in Zend Framework
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver Software
 
Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010Unit Testing in SharePoint 2010
Unit Testing in SharePoint 2010
 
IoC with PHP
IoC with PHPIoC with PHP
IoC with PHP
 
PHP & MVC
PHP & MVCPHP & MVC
PHP & MVC
 

Recently uploaded

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024The Digital Insurer
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 

Recently uploaded (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 

SOLID Principles

  • 1. SOLID Principles Chris Weldon Improving Enterprises
  • 2. Me • Fightin’ Texas Aggie • .Net and PHP Developer • UNIX and Windows Sysadmin • Senior Consultant at Improving Enterprises • Contact Me: chris@chrisweldon.net
  • 3. Agile, Microsoft, Open Technologies, UX Applied Training, Coaching, Mentoring Certified Consulting Rural Sourcing Recruiting Services
  • 6. Abstraction Inheritance What is OOD?
  • 7. Abstraction Inheritance What is OOD? Encapsulation
  • 8. Abstraction Inheritance What is OOD? Encapsulation Polymorphism
  • 10. ?
  • 11. SOLID is not a law
  • 12.
  • 14. public class Order { private int _id; private int _userId; private Product[] _products; public int getId() { return this._id; } public void setId(int id) { this._id = id; } public int getUserId() { return this._userId; } public void setUserId(int userId) { this._userId = userId; }
  • 15. public Product[] getProducts() { return this._products; } public void addProduct(Product product) { this._products.add(product); } public void setProducts(Product[] products) { this._products = products; }
  • 16. private DBConnection _db; public Order() { // Read from configuration to get connection string. string connectionString = string.Empty; Handle fileHandle = fopen("/etc/database/app.config", "r"); while (string row = readLine(fileHandle)) { if (row.StartsWith("dbo")) { connectionString = row; } } fclose(fileHandle); this._db = new DBConnection(connectionString); }
  • 17. public static Order CreateOrder(int userId, Product[] products) { Order order = new Order(); order.setUserId(userId); order.setProducts(products); return order; } public static Order getOrderById(int orderId) { if (orderId == null || orderId < 0) { DBCommand command = this._db.exec("SELECT * FROM orders"); Order[] results = this._db.getResults(command); // Get the first result. return results[0]; } DBCommand command = this._db.exec("SELECT * FROM orders WHERE id = ?", orderId); Order order = this._db.getSingle($command); return order; }
  • 18. public void deliverOrder() { try { WebServiceConnection networkConnection = new WebServiceConnection("http://shpt1/shipctrl.svc"); networkConnection->open(); ShippingManager shippingManager = new ShippingManager(networkConnection); shippingManager.setOrder(this); shippingManager.setDeliveryType(DeliveryType.EXPRESS); shippingManager.shipViaWebService(); this.notifyCustomer(); } catch (Exception e) { Handle logFile = fopen("/tmp/logfile.log", "a"); fwrite("An error occurred while delivering the order.", logFile); fclose(logFile); } }
  • 19. public void notifyCustomer() { try { mailer = new Mailer(); mailer.setFrom(“orders@chrisweldon.net”, “Grumpy Baby Orders”); mailer.setSubject(“Order #” + this.getId() + “ out for Delivery”); mailer.setBodyText(“Your order is being shipped!”); mailer.send(); } catch (Exception $e) { Handle logFile = fopen("/tmp/logfile.log", "a"); fwrite("An error occurred while emailing the notice.", logFile); fclose(logFile); } } }
  • 20.
  • 21. OMG
  • 22.
  • 24. public void ActivateDrillBit(string customerOption) { if (customerOption == "small") { SmallBit drillBit = new SmallBit(); drillBit.activate(); } else if (customerOption == "medium") { MediumBit drillBit = new MediumBit(); drillBit.activate("120hz"); } else if (customerOption == "large") { LargeBit drillBit = new LargeBit(); drillBit.activate("240hz", Options.Water); } }
  • 25. Requirements Change! Customer Needs to Specify Options
  • 26. public void ActivateDrillBit(string customerOption, string freq, Options options) { if (freq == "") freq = "240hz"; if (options == null) options = Options.NoWater; if (customerOption == "small") { SmallBit drillBit = new SmallBit(); drillBit.activate(freq, options); } else if (customerOption == "medium") { MediumBit drillBit = new MediumBit(); drillBit.activate(freq, options); } else if (customerOption == "large") { LargeBit drillBit = new LargeBit(); drillBit.activate(freq, options); } }
  • 27.
  • 28. You Broke My App !@#!@
  • 29.
  • 30. public class DrillBitActivator { public void ActivateDrillBit(string customerOption) { // ... } } public class DrillBitConfigurableActivator : DrillBitActivator { public DrillBitConfigurableActivator(string freqency, Options options) { // Configurable! } public override function ActivateDrillBit(string customerOption) { // ... } }
  • 31. public function ActivateDrillBit(string customerOption) IDrillBit .drillBit = DrillBitFactory::CreateDrillBit(customerOption); drillBit.activate(this._freq, this._options); }
  • 33. public interface IManageCustomers { void TakeSpecifications(Specs specs); void ReviewSpecifications(Specs specs); void GiveToEngineers(Specs specs); void DealWithTheGoshDarnCustomers(); bool IsPeoplePerson(); }
  • 34. public class GoodManager : IManageCustomers { public void TakeSpecifications(Specs specs) { this.ReviewSpecifications(specs); } public void ReviewSpecifications(Specs specs) { // If specs seem good. this.GiveToEngineers(specs); } public void GiveToEngineers(Specs specs) { // E-mails specs to engineers. } public void DealWithTheGoshDarnCustomers() { // You better believe he does. } public bool IsPeoplePerson() { return true; // Absolutely! } }
  • 35.
  • 36. public class Tom : IManageCustomers { public void TakeSpecifications(Specs specs) { throw new DelegateToSecretary(); } public void ReviewSpecifications(Specs specs) { throw new DelegateToSecretary(); } public void GiveToEngineers(Specs specs) { throw new DelegateToSecretary(); } public void DealWithTheGoshDarnCustomers() { // Your gosh darn right I do! } public bool IsPeoplePerson() { return true; // I AM a people person, dammit! } }
  • 37.
  • 38. public interface ITakeSpecifications { function TakeSpecifications(Specs specs); } public interface IReviewSpecifications { function ReviewSpecifications(Specs specs); } public interface IGiveToEngineers { function GiveToEngineers(Specs specs); } public interface IManageCustomers { function DealWithTheGoshDarnCustomers(); function IsPeoplePerson(); }
  • 39. public class GoodManager : IManageCustomers, ITakeSpecifications, IReviewSpecifications, IGiveToEngineers { public void TakeSpecifications(Specs specs) { this.ReviewSpecifications(specs); } public void ReviewSpecifications(Specs specs) { // If specs seem good. this.GiveToEngineers(specs); } public void GiveToEngineers(Specs $specs) { // E-mails specs to engineers. } public void DealWithTheGoshDarnCustomers() { // You better believe he does. } public bool IsPeoplePerson() { return true; // Absolutely! } }
  • 40. public class Tom : IManageCustomers { public void DealWithTheGoshDarnCustomers() { // Your gosh darn right I do! } public bool IsPeoplePerson() { return true; // I AM a people person, dammit! } }
  • 42. public interface IDataResource { void Load(); void Save(); }
  • 43. public class AppSettings : IDataResource { public void Load() { // Load application settings. } public void Save() { // Save application settings. } }
  • 44. public class UserSettings : IDataResource { public void Load() { // Load user settings. } public void Save() { // Save user settings. } }
  • 45. static IDataResource[] LoadAll() { IDataResource[] resources = new IDataResource[2] { new AppSettings(), new UserSettings() }; foreach (IDataResource resource in resources) { resource.Load(); } return resources; } static void SaveAll(IDataResource[] resources) { foreach (IDataResource resource in resources) { resource.Save(); } }
  • 47. public class UnsaveableSettings : AppSettings { public override void Load() { // Loads settings. } public override void Save() { throw new CannotSaveException(); } }
  • 48. static IDataResource[] LoadAll() { IDataResource[] resources = new IDataResource[3] { new AppSettings(), new UserSettings(), new UnsaveableSettings() }; foreach (IDataResource resource in resources) { resource.Load(); } return resources; } static void SaveAll(IDataResource[] resources) { foreach (IDataResource resource in resources) { if (resource is UnsaveableSettings) continue; resource.Save(); } }
  • 49.
  • 50. public interface IDataResource { void Load(); } public interface ISaveResource { void Save(); }
  • 51. public class AppSettingsLoaderBase : IDataResource { public function Load() { // Load application settings. } }
  • 52. public class AppSettings extends AppSettingsLoaderBase implements ISaveResource { public function Save() { // Save application settings. } }
  • 53. public class UnsaveableSettings extends AppSettingsLoaderBase { public override void Load() { // Loads settings. } }
  • 54. static IDataResource[] LoadAll() { IDataResource[] resources = new IDataResource[3] { new AppSettings(), new UserSettings(), new UnsaveableSettings() }; foreach (IDataResource resource in resources) { resource.Load(); } return resources; } static void SaveAll(ISaveResource[] resources) { foreach (ISaveResource resource in resources) { resource.Save(); } }
  • 56. public class Authenticator { private DataAccessLayer _repository; public DataAccessLayer() { this._repository = new DataAccessLayer(); } public bool authenticate(string username, string password) { string hashedPassword = md5(password); User user = this._repository.findByUsernameAndPassword( username, hashedPassword); return user == null; } }
  • 58. Problems? Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 59. Problems? Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array Strongly coupled to DataAccessLayer
  • 60.
  • 61. class Authenticator { private DataAccessLayer _repository; public Authenticator(DataAccessLayer repository) { this._repository = repository; } public bool authenticate(string username, string password) { string hashedPassword = md5(password); User user = this._repository.findByUsernameAndPassword( username, hashedPassword); return user == null; } }
  • 62. Dependency Inversion • “High-level modules should not depend upon low level modules. They should depend upon abstractions. • “Abstractions should not depend upon details. Details should depend upon abstractions.” Robert Martin
  • 64. public interface IUserRepository { User findByUsernameAndPassword(string username, string password); } public class DataAccessLayer : IUserRepository { public User findByUsernameAndPassword(string username, string password) { // Do some database stuff. } }
  • 65. class Authenticator { private IUserRepository _repository; public Authenticator(IUserRepository repository) { this._repository = repository; } public bool authenticate(string username, string password) { string hashedPassword = md5(password); User user = this._repository.findByUsernameAndPassword( username, hashedPassword); return user == null; } }
  • 67. Comparison Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 68. Comparison Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : array
  • 69. Comparison Authenticator authenticate() : bool Authenticator authenticate() : bool IUserRepository findByUsernameAndPassword : array DataAccessLayer findByUsernameAndPassword : array DataAccessLayer findByUsernameAndPassword : array
  • 70. Benefit: Flexibility public class WebServiceUserRepository : IUserRepository { public User findByUsernameAndPassword(string username, string password) { // Fetch our user through JSON or SOAP } } public class OAuthRepository : IUserRepository { public User findByUsernameAndPassword(string username, string password) { // Connect to your favorite OAuth provider } }
  • 71. Thank You! Check improvingaggies.com http://spkr8.com/neraath

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n