www.devcoach.com
PRESENTED BYDaniel Fisher
CONTACT [email protected]
dcEFFECTIVE, LOOSLY COUPLED
Writing better code with C#
www.devcoach.com
www.devcoach.com
LENNYBACON.COMDaniel Fisher | CTO & Software Architect
CCD mit MCP, MCTS, MCPD…[email protected]
Mit-Gründer und Geschäftsführer von devcoach.comwww.devcoach.com
Mit-Gründer und Vorstand dergemeinnützigen www.just community.de e.V.
Veranstalter des größten Entwickler & IT-Pro Community Events in Deutschland: www.nrwconf.de
Mit-Gründer und Leiter derINETA Usergroup Düsseldorf
www.NetUG-NiederRhein.de
Mitglied im Microsoft Community Leader & Insider Program (CLIP)Connected Systems Advisory Board
Expertengruppe für WCF, WF & BizTalk
www.devcoach.com
DEVCOACH.COM• Leistungen
– Architektur-Beratung• Strukturierter und effizienter zu einer wartbaren Anwendung.
– Prozessoptimierung• BPM• FDD, TDD, MSF Agile & SCRUM
– Software-Entwicklung• Team-out-of-the-box (Near-shoring)• Objektmodelle und Datenzugriff• Kommunikations-Infrastrukturen• Identitäts- und Berechtigungsmodelle• Web 2.0 und Rich Internet Applikation
– Coaching & Training• Technologien schneller verstehen und richtig einsetzen.
• Technologien– Microsoft Windows & .NET Framework
• ASP.NET, WCF, WF, WPF, Silverlight & Geneva
• Kunden– Versicherung, Finanzindustrie, Mittelstand, Handel, Kommunikation,
Softwarehersteller u.v.a.• Bundesamt für Sicherheit in der Informationstechnologie, Microsoft,
Dresdner Bank…
Project Experience
Technology Know-how
devcoach®
www.devcoach.com
AGENDA
• Loose Koppelung• Konzepte• Code
www.devcoach.com
LOOSE KOPPELUNG
www.devcoach.com
www.devcoach.com
www.devcoach.com
www.devcoach.com
www.devcoach.com
WHAT IS BAD DESIGN?
"That's not the way I would have done it..."
Well, that is not a valid measure for the quality of the design! This statement is purely based on personal preferences.
www.devcoach.com
WHAT IS BAD DESIGN?• Rigid: – it's hard to change a part of the system without affection
too many other parts of the system
• Fragile: – when making a change, unexpected parts of the system
break
• Immobile: – it is hard to reuse it in another application because it cannot
be disentangled from the current application.
www.devcoach.com
THE "OBJECT-STYLE"
www.devcoach.com
www.devcoach.com
www.devcoach.com
PetSearch
PetSearchResultList
PetSearchResult
www.devcoach.com
QUESTION?• Are you telling me that every screen the app
has, there is a different object?
• No, but …– Define your objects like they are "viewed" in the
application.
www.devcoach.com
KONZEPTE
www.devcoach.com
DESIGN GOALS• There are several design goals– Reusability– Maintainability– Performance – Scalability– …
• Make decisions on the goals of you application!
www.devcoach.com
WHY MAINTAINABILITY?• The most expensive and time-consuming work of software
development is the work of finding bugs and fixing them. – In the U.S. the number of bugs … averages five per function point. – The cost of finding and repairing these defects averages about 35
percent of the total development cost of building the application. – The schedule time required is about 30 percent of project development
schedules.
• Defect repair costs and schedules are often larger than coding costs and schedules.
Capers Jones, Estimating Software Costshttp://www.amazon.com/Estimating-Software-Costs-Capers-Jones/dp/0071483004/
www.devcoach.com
COMPOSITION OVER INHERITANCE
Person
Employee
Person Employee
www.devcoach.com
COMPOSITION OVER INHERITANCE
Person
Employee
Person Contract
Company
www.devcoach.com
FRAGILE BASE CLASS• A fundamental architectural problem problem
of OOP• Base classes (superclasses) are considered
"fragile" – Modifications to a base class may cause derived
classes to malfunction. – The programmer cannot determine whether a base
class change is safe simply by examining in isolation the methods of the base class.
• Solutions: "sealed" and "non-virtual"http://en.wikipedia.org/wiki/Fragile_base_class
www.devcoach.com
COMPOSITION ADVANTAGES• More flexibility • Much more resilient to change– When used properly :-)
• Where inheritance represents the relationship with the most coupling between two classes, composition allows us to freely decouple two (or more) classes.
www.devcoach.com
INHERITANCE SAMPLE
public class SqlRoleProvider{ …}public class CachedSqlRoleProvider : SqlRoleProvider{ public override string[] GetAllRoles() { //TODO: Get from Cache and return var roles = base.GetAllRoles()
//TODO: Fill Cache return roles; }}
www.devcoach.com
SOLID DESING…• Single Responsibility Principle • Open Closed Principle• Liskov Substitution Principle • Interface Segregation Principle • Dependency Inversion Principle
www.devcoach.com
SINGLE RESPONSIBILITY PRINCIPLE• A class should have one, and only one, reason to
change.
• "Separation of concerns"
www.devcoach.com
www.devcoach.com
OPEN CLOSE PRINCIPLE• You should be able to extend a classes behavior,
without modifying it.– Keep public interfaces reduced to the neccessary…• All member fields private.• No Global Variables -- Ever.
www.devcoach.com
www.devcoach.com
LISKOV SUBSTITUTION PRINCIPLE• Derived classes must be substitutable for their
base classes.
www.devcoach.com
IMAGINE FOLLOWING
public class Rectangle{
public void SetWidth(double w) { itsWidth=w; }public void SetHeight(double h) { itsHeight=w; }public double GetHeight() { return itsHeight; }public double GetWidth() { return itsWidth; }private double itsWidth;private double itsHeight;
};
www.devcoach.com
NOW THIS …
public class Square : Rectangle{ new void SetWidth(double w) { base.SetWidth(w); base.SetHeight(w); } new void SetHeight(double h) { base.SetHeight(h); base.SetWidth(h); }}
www.devcoach.com
WHAT WILL HAPPEN HERE?
public void f(Rectangle r){ r.SetWidth(32); }
www.devcoach.com
AND HERE?
void f<TObj>(TObj r) where T: Rectangle{ r.SetWidth(32); }
www.devcoach.com
ENABLE EXTENSION…
public class Rectangle{
public void virtual SetWidth(double w) { itsWidth=w; }
public void virtual SetHeight(double h) { itsHeight=w;}
public double GetHeight() { return itsHeight; }public double GetWidth() { return itsWidth; }private double itsWidth;private double itsHeight;
};
www.devcoach.com
www.devcoach.com
INTERFACE SEGREGATION PRINCIPLE
• Make fine grained interfaces that are client specific.
www.devcoach.com
IMAGINE FOLLOWING
public interface IRectangle{
void SetWidth(double w);void SetHeight(double h);double GetHeight();double GetWidth();
};
www.devcoach.com
VS. THAT
public interface IRectangle{
double GetHeight();double GetWidth();
};
public interface IEditableRectangle{
void SetWidth(double w);void SetHeight(double h);
};
www.devcoach.com
www.devcoach.com
DEPENDENCY INVERSION PRINCIPLE
• Depend on abstractions, not on concretions.
www.devcoach.com
IMAGINE FOLLOWING
public class Lamp{ public void TurnOff(); public void TurnOn();};
public class Button{ private Lamp _lamp; public Button(Lamp lamp) { _lamp = lamp; } public void Detect() { if (GetPhysicalState()) _lamp.TurnOn(); return; _lamp.TurnOff(); } public bool GetPhysicalState(){ return Clicked;}};
www.devcoach.com
VS. THAT
public class ButtonClient{ public void TurnOff(); public void TurnOn();}public class Lamp : ButtonClient{ //The button client allows us to re-use the button...}public class Button{ private ButtonClient _client; public Button(ButtonClient client) { _client = client; } public void Detect() { if (GetPhysicalState()) _client.TurnOn(); return; _client.TurnOff(); } public bool GetPhysicalState();};
www.devcoach.com
www.devcoach.com
INVERSION OF CONTROL
• Constructor Injection• Method Injection• Property Injection• Configuration Injection– Dependency Object Container
www.devcoach.com
MICROSOFT AND IOC...
public interface IServiceProvider { object GetService(Type serviceType); }
public interface IServiceLocator : IServiceProvider { GetAllInstances<TService>(); IEnumerable<object> GetAllInstances(Type serviceType); TService GetInstance<TService>(); TService GetInstance<TService>(string key); object GetInstance(Type serviceType); object GetInstance(Type serviceType, string key); }
www.devcoach.com
SIMPLE DESIGN
“Simplicity is more complicated than you think. But it’s well worth it.”
• Satisfy requirements– No Less– No more
• Shape units
www.devcoach.com
DIVIDE AND CONQUER
„recursively breaking down a problem into two or more sub-problems of the same (or related) type, until these become simple enough to be solved directly. “
„ The solutions to the sub-problems are then combined to give a solution to the original problem. “
www.devcoach.com
CREATE ASSEMBLIES WISELY• More assemblies = more physical stuff– Build, configuration, Deployment, File IO…
• Who will pay that?
• But necessary for:– Product Separation?– Different Liceses models?
www.devcoach.com
SIMPLE DESIGN CRITERIA
• The code …– Fulfills the requirements.• YAGNI
– Has the smallest number of classes.• FxCop Rule: At least 3 members per class.
– Has the smallest number of methods• Keep your methods maintainable.
– At maximum 50 lines– At least 80 chars– …
www.devcoach.com
Demo!
www.devcoach.com
Thank you!
www.devcoach.com
Q & A
www.devcoach.com
SOLID References
• http://www.objectmentor.com/resources/articles/srp.pdf
• http://www.objectmentor.com/resources/articles/ocp.pdf
• http://www.objectmentor.com/resources/articles/lsp.pdf
• http://www.objectmentor.com/resources/articles/isp.pdf
• http://www.objectmentor.com/resources/articles/dip.pdf
Top Related