Your SlideShare is downloading. ×
SOLID Principles
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

SOLID Principles

1,046
views

Published on

Published in: Technology, Business

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,046
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
32
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 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, UXApplied Training, Coaching, MentoringCertified ConsultingRural SourcingRecruiting Services
    • 4. What is OOD?
    • 5. Abstraction What is OOD?
    • 6. Abstraction Inheritance What is OOD?
    • 7. Abstraction Inheritance What is OOD?Encapsulation
    • 8. Abstraction Inheritance What is OOD?Encapsulation Polymorphism
    • 9. What is SOLID?
    • 10. ?
    • 11. SOLID is not a law
    • 12. An Order
    • 13. 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; }
    • 14. public Product[] getProducts() { return this._products;}public void addProduct(Product product) { this._products.add(product);}public void setProducts(Product[] products) { this._products = products;}
    • 15. 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);}
    • 16. 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; }
    • 17. 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); }}
    • 18. public void notifyCustomer() { try { mailer = new Mailer(); mailer.setFrom(“orders@chrisweldon.net”, “Grumpy Baby Orders”); mailer.setSubject(“Order #” + this.getId() + “ out forDelivery”); 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); } }}
    • 19. OMG
    • 20. Next Sample
    • 21. 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); }}
    • 22. Requirements Change! Customer Needs to Specify Options
    • 23. 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); }}
    • 24. You Broke My App!@#!@
    • 25. 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) { // ... }}
    • 26. public function ActivateDrillBit(string customerOption) IDrillBit .drillBit = DrillBitFactory::CreateDrillBit(customerOption); drillBit.activate(this._freq, this._options);}
    • 27. Next:A Familiar Example
    • 28. public interface IManageCustomers { void TakeSpecifications(Specs specs); void ReviewSpecifications(Specs specs); void GiveToEngineers(Specs specs); void DealWithTheGoshDarnCustomers(); bool IsPeoplePerson();}
    • 29. 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! }}
    • 30. 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! }}
    • 31. 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();}
    • 32. 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! }}
    • 33. public class Tom : IManageCustomers { public void DealWithTheGoshDarnCustomers() { // Your gosh darn right I do! } public bool IsPeoplePerson() { return true; // I AM a people person, dammit! }}
    • 34. Next Up
    • 35. public interface IDataResource{ void Load(); void Save();}
    • 36. public class AppSettings : IDataResource { public void Load() { // Load application settings. } public void Save() { // Save application settings. }}
    • 37. public class UserSettings : IDataResource { public void Load() { // Load user settings. } public void Save() { // Save user settings. }}
    • 38. 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(); }}
    • 39. Our “Duck”
    • 40. public class UnsaveableSettings : AppSettings { public override void Load() { // Loads settings. } public override void Save() { throw new CannotSaveException(); }}
    • 41. 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(); }}
    • 42. public interface IDataResource{ void Load();}public interface ISaveResource{ void Save();}
    • 43. public class AppSettingsLoaderBase : IDataResource { public function Load() { // Load application settings. }}
    • 44. public class AppSettings extends AppSettingsLoaderBase implements ISaveResource { public function Save() { // Save application settings. }}
    • 45. public class UnsaveableSettings extends AppSettingsLoaderBase { public override void Load() { // Loads settings. }}
    • 46. 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(); }}
    • 47. Final Problem
    • 48. 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; }}
    • 49. Problems?
    • 50. Problems? Authenticator authenticate() : bool DataAccessLayerfindByUsernameAndPassword : array
    • 51. Problems? Authenticator authenticate() : bool DataAccessLayer findByUsernameAndPassword : arrayStrongly coupled to DataAccessLayer
    • 52. 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; }}
    • 53. 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
    • 54. Combine Principles!
    • 55. public interface IUserRepository { User findByUsernameAndPassword(string username, string password);}public class DataAccessLayer : IUserRepository { public User findByUsernameAndPassword(string username, string password) { // Do some database stuff. }}
    • 56. 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; }}
    • 57. Comparison
    • 58. Comparison Authenticator authenticate() : bool DataAccessLayerfindByUsernameAndPassword : array
    • 59. Comparison Authenticator authenticate() : bool DataAccessLayerfindByUsernameAndPassword : array
    • 60. Comparison Authenticator authenticate() : bool Authenticator authenticate() : bool IUserRepository findByUsernameAndPassword : array DataAccessLayerfindByUsernameAndPassword : array DataAccessLayer findByUsernameAndPassword : array
    • 61. Benefit: Flexibilitypublic 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 }}
    • 62. Thank You!Check improvingaggies.com http://spkr8.com/neraath