solid - not just a state of matter, its principles for oo propriety

98
SOLID Not Just a State of Matter, It’s Principles for OO Propriety Chris Weldon

Upload: chris-weldon

Post on 29-Jan-2018

1.414 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

SOLIDNot Just a State of Matter, It’s Principles for OO Propriety

Chris Weldon

Page 2: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Me

• Fightin’ Texas Aggie

• .Net and PHP Developer

• UNIX and Windows Sysadmin

• Senior Consultant at Improving Enterprises

• Contact Me: [email protected]

Page 3: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Agile, Microsoft, Open Technologies, UX

Applied Training, Coaching, Mentoring

Certified Consulting

Rural Sourcing

Recruiting Services

Page 4: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

What is OOD?

Page 5: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

What is OOD?

Abstraction

Page 6: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

What is OOD?

InheritanceAbstraction

Page 7: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

What is OOD?Encapsulation

InheritanceAbstraction

Page 8: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

What is OOD?Encapsulation Polymorphism

InheritanceAbstraction

Page 9: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

What is SOLID?

Page 10: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

?

Page 11: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Is it law?

Page 12: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

They be more like“guidelines”

Page 13: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 14: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

An Order

Page 15: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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; }

Page 16: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public Product[] getProducts() { return this._products; }

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

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

Page 17: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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); }

Page 18: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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; }

Page 19: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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); } }

Page 20: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public void notifyCustomer() { try { mailer = new Mailer(); mailer.setFrom(“[email protected]”, “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); } }}

Page 21: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 22: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

OMG

Page 23: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

OMGWho vomited in my codebase?

Page 24: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 25: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

“There should never be more than one reasonfor a class to change”

Page 26: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Improve

Page 27: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Improve

public class Order{ // I’m just a model}

Page 28: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Improve

public class Order{ // I’m just a model}

public class OrderDao{ // I just talk to the database public OrderDao(); public static Order CreateOrder(int userId, Product[] products); public static Order getOrderById(int orderId);}

Page 29: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Improve

public class Order{ // I’m just a model}

public class OrderDao{ // I just talk to the database public OrderDao(); public static Order CreateOrder(int userId, Product[] products); public static Order getOrderById(int orderId);}

public class OrderDeliverer{ // I just deliver orders public void deliverOrder();}

Page 30: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Improve

public class Order{ // I’m just a model}

public class OrderDao{ // I just talk to the database public OrderDao(); public static Order CreateOrder(int userId, Product[] products); public static Order getOrderById(int orderId);}

public class OrderDeliverer{ // I just deliver orders public void deliverOrder();}

public class CustomerNotifier{ // I just deliver orders public void notifyCustomer();}

Page 31: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Improve

public class Order{ // I’m just a model}

public class OrderDao{ // I just talk to the database public OrderDao(); public static Order CreateOrder(int userId, Product[] products); public static Order getOrderById(int orderId);}

public class OrderDeliverer{ // I just deliver orders public void deliverOrder();}

public class CustomerNotifier{ // I just deliver orders public void notifyCustomer();}

it’s what we do

Page 32: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Next Sample

Page 33: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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); }}

Page 34: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Requirements Change!Customer Needs to Specify Options

Page 35: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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); }}

Page 36: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 37: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

YouBroke

MyApp

!@#!@

Page 38: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 39: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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) { // ... }}

Page 40: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public function ActivateDrillBit(string customerOption) IDrillBit drillBit = DrillBitFactory::CreateDrillBit(customerOption); drillBit.activate(this._freq, this._options);}

Page 41: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Next:A Familiar Example

Page 42: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public interface IManageCustomers { void TakeSpecifications(Specs specs); void ReviewSpecifications(Specs specs); void GiveToEngineers(Specs specs); void DealWithTheGoshDarnCustomers(); bool IsPeoplePerson();}

Page 43: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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! }}

Page 44: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 45: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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! }}

Page 46: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 47: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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();}

Page 48: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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! }}

Page 49: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public class Tom : IManageCustomers { public void DealWithTheGoshDarnCustomers() { // Your gosh darn right I do! }

public bool IsPeoplePerson() { return true; // I AM a people person, dammit! }}

Page 50: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Hand Tom off to our consultants

Page 51: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Next Up

Page 52: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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

Page 53: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public class AppSettings : IDataResource { public void Load() { // Load application settings. }

public void Save() { // Save application settings. }}

Page 54: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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

public void Save() { // Save user settings. }}

Page 55: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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(); }}

Page 56: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Our “Duck”

Page 57: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public class UnsaveableSettings : AppSettings { public override void Load() { // Loads settings. }

public override void Save() { throw new CannotSaveException(); }}

Page 58: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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) { resource.Save(); }}

Page 59: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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) { resource.Save(); }}

Page 60: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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) { resource.Save(); }}

What happens with UnsaveableSettings?

Page 61: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 62: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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

resource.Save(); }}

teh fix!

Page 63: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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

resource.Save(); }}

teh fix!

Page 64: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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

resource.Save(); }}

teh fix!

omg shoot megood job reducing abstraction

Page 65: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

The Real Fix

Page 66: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

The Real FixInterface Segregation +

Polymorphism

Page 67: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public interface IDataResource{ void Load();}

public interface ISaveResource{ void Save();}

Page 68: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public class AppSettingsLoaderBase : IDataResource { public virtual void Load() { // Load application settings. }}

Page 69: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public class AppSettings extends AppSettingsLoaderBase implements ISaveResource { public function Save() { // Save application settings. }}

Page 70: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public class UnsaveableSettings extends AppSettingsLoaderBase { public override void Load() { // Loads settings. }}

Page 71: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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(); }}

Page 72: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Final Problem

Page 73: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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; }}

Page 74: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Problems?

Page 75: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Problems?

authenticate() : boolAuthenticator

findByUsernameAndPassword : arrayDataAccessLayer

Page 76: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Problems?

authenticate() : boolAuthenticator

findByUsernameAndPassword : arrayDataAccessLayer

Strongly coupled to DataAccessLayer

Page 77: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 78: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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

Page 79: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Step 1Invert Dependency

Page 80: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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; }}

Page 81: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Coupling = Bad

Page 82: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Step 2Depend on Abstractions

Page 83: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

public interface IUserRepository { User findByUsernameAndPassword(string username, string password);}

public class DataAccessLayer : IUserRepository { public User findByUsernameAndPassword(string username, string password) { // Do some database stuff. }}

Page 84: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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; }}

Page 85: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Comparison

Page 86: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Comparison

authenticate() : boolAuthenticator

findByUsernameAndPassword : arrayDataAccessLayer

Page 87: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Comparison

authenticate() : boolAuthenticator

findByUsernameAndPassword : arrayDataAccessLayer

Page 88: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Comparison

authenticate() : boolAuthenticator

findByUsernameAndPassword : arrayDataAccessLayer

authenticate() : boolAuthenticator

findByUsernameAndPassword : arrayIUserRepository

findByUsernameAndPassword : arrayDataAccessLayer

Page 89: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

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 }}

Page 90: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Recap

Page 91: SOLID - Not Just a State of Matter, Its Principles for OO Propriety
Page 92: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

S = SRP - Single Responsibility Principle

Page 93: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

S = SRP - Single Responsibility Principle

O = OCP - Open/Closed Principle

Page 94: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

S = SRP - Single Responsibility Principle

O = OCP - Open/Closed Principle

L = LSP - Liskov Substitution Principle

Page 95: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

S = SRP - Single Responsibility Principle

O = OCP - Open/Closed Principle

L = LSP - Liskov Substitution Principle

I = ISP - Interface Segregation Principle

Page 96: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

S = SRP - Single Responsibility Principle

O = OCP - Open/Closed Principle

L = LSP - Liskov Substitution Principle

I = ISP - Interface Segregation Principle

D = DIP - Dependency Inversion Principle

Page 97: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Questions?

Page 98: SOLID - Not Just a State of Matter, Its Principles for OO Propriety

Thank You!

http://spkr8.com/neraathCheck improvingaggies.com