Download - Clean Code Development
![Page 1: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/1.jpg)
Clean Code Development
Peter Gfader#netug
Delivering Awesome Web Applications
![Page 2: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/2.jpg)
C# and .NET (Java not anymore)
TestingAutomated tests
Agile, ScrumScrum Developer Trainer
Technology aficionado SilverlightASP.NETWindows FormsLINQ,...
Peter Gfaderhttp://blog.gfader.com/
twitter.com/peitor#netug
![Page 3: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/3.jpg)
• Why code matters• Good and Bad Code• The Broken Window Theory• The Grand Redesign in the Sky• The Boy Scout Rule
• OOP Patterns and Principles• SOLID Principles
• How to measure clean code?• Tools
Agenda
![Page 4: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/4.jpg)
1903 Wright brothers flew 59 seconds
Why code matters?
http://www.reddit.com/r/AskReddit/comments/dlrjs/whats_the_most_mindblowing_fact_you_heardread_in/
![Page 5: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/5.jpg)
1969We landed on the moon
Why code matters?
![Page 6: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/6.jpg)
TodayWe fly around the world in 32 hoursTourists in space
Why code matters?
![Page 7: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/7.jpg)
1903 - 0 computers
Why code matters?
![Page 8: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/8.jpg)
40 years later - a handful of computers
Why code matters?
![Page 9: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/9.jpg)
Today > 500 billion programmable devices
Why code matters?
![Page 10: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/10.jpg)
Today > 500 billion programmable devices (more than humans on earth)
Why code matters?
![Page 11: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/11.jpg)
2100Programmable devices everywhereUnder skin, in brain, in blood… like dust…
Why code matters?
![Page 12: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/12.jpg)
Who programs those?
Why code matters?
![Page 13: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/13.jpg)
Why code matters?
What tools do we use?
![Page 14: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/14.jpg)
Why code matters?
Can we trust our code?
Important?
![Page 15: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/15.jpg)
What is good code?
![Page 16: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/16.jpg)
It's gotta ship?
It's gotta pass the tester?
It's gotta implement requirements?
It's gotta be reasonably performant?
"Wartung"? (aka Maintainability)
What is good code?
![Page 17: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/17.jpg)
What is bad code?
![Page 18: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/18.jpg)
What is bad code?
![Page 19: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/19.jpg)
What is bad code?
![Page 20: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/20.jpg)
while ((!found) && (pos < (fileContent.Length - 6))){ byteData = new byte[6]; Array.Copy(fileContent, pos, byteData, 0, 6); pos = pos + 6; str_byteData = enc.GetString(byteData); if (str_byteData.Contains("s")) { posE_byteData = str_byteData.IndexOf("s"); pos = pos + (posE_byteData - 6); Array.Copy(fileContent, pos, byteData, 0, 6); pos = pos + 6; if (byteData[0] == 0x73) // 's' { if (byteData[1] == 0x74) // 't' { if (byteData[2] == 0x72) // 'r' { if (byteData[3] == 0x65) // 'e' { if (byteData[4] == 0x61) // 'a' { if (byteData[5] == 0x6D) // 'm' { found = true; break; } else { if (byteData[5] == 0x73) { pos = pos - 1; } } }
What is bad code?
![Page 21: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/21.jpg)
public int x() { int q = 0; int z = 0; for (int kk = 0; kk < 10; kk++) { if (l[z] == 10) { q += 10 + (l[z + 1] + l[z + 2]); z += 1; } else if (l[z] + l[z + 1] == 10) { q += 10 + l[z + 2]; z += 2; } else { q += l[z] + l[z + 1]; z += 2; } } return q;}
What is bad code?
![Page 22: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/22.jpg)
What is bad code?
![Page 23: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/23.jpg)
• Hard to understand at first sight• Unmaintained• Messy• No one cares
What is bad code?
![Page 24: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/24.jpg)
• Hard to understand at first sight• Unmaintained• Messy• No one cares
"Wartung"? (aka Maintainabilty)
What is bad code?
![Page 25: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/25.jpg)
Bad Code
Is SCARY!!!
![Page 26: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/26.jpg)
Why are we writing bad code?
![Page 27: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/27.jpg)
![Page 28: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/28.jpg)
Broken Window Theory
![Page 29: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/29.jpg)
Broken Window Theory
![Page 30: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/30.jpg)
The rewrite
![Page 31: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/31.jpg)
Netscape
rewrote Netscape 4.0 and released it after three years as Netscape 6.0
![Page 32: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/32.jpg)
Borland
rewrote dBase and Quattro Pro
![Page 33: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/33.jpg)
Microsoft
Rewrote Vista~60%
![Page 34: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/34.jpg)
What can we do?
![Page 35: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/35.jpg)
Sushi chef rule
Clean up as you doNA
![Page 36: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/36.jpg)
Hotel room rule
Let someone clean up every dayNA
![Page 37: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/37.jpg)
The Boy Scout Rule
Leave the campground cleaner than you found it OK
![Page 38: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/38.jpg)
How can we improve?
![Page 39: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/39.jpg)
"Everything I have to change, in order to make the product owner happy!"
• Config files .config, .svc• XAML .xaml, .CSS, .. • Code .cs, .vb, .js, ..• Deployment scripts .ps• Batch files .bat
What is code?
![Page 40: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/40.jpg)
OOP Principles
![Page 41: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/41.jpg)
Solid PrinciplesS.o.l.i.d. Principles
![Page 42: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/42.jpg)
Single Responsibility Principle
Only one reason to change
Robustness
Focus
Every entity should have a single responsibility
![Page 43: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/43.jpg)
public class PrintServer { public string CreateJob(PrintJob data) { //... } public int GetStatus(string jobId) { //... } public void Print(string jobId, int startPage, int endPage) { //... }
public List<Printer> GetPrinterList() { //... } public bool AddPrinter(Printer printer) { //... }
public event EventHandler<JobEvent> PrintPreviewPageComputed;
public event EventHandler PrintPreviewReady;
// ...}
![Page 44: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/44.jpg)
public class PrintServer {
public string CreateJob(PrintJob data) { //... }
public int GetStatus(string jobId) { //... }
public void Print(string jobId, int startPage, int endPage) { //... }
}
public class PrinterList {
public List<Printer> GetPrinterList() { //... }
public bool AddPrinter(Printer printer) { //... }}
![Page 45: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/45.jpg)
OpenClose Principle
Open for extension
Close for modification
Every entity should be open for extension, but closed for modification
![Page 46: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/46.jpg)
public void SaveToolbarStateSwitch() {
long version = Core.GetVisualStudioVersion();
Configuration.VSToolbarHeight = AddinCommandBar.Height.ToString(); Configuration.VS2010ToolbarWidth = AddinCommandBar.Width.ToString(); Configuration.VS2010ToolbarHeight = AddinCommandBar.Height.ToString(); switch (version) { case 2003: case 2004: case 2005: Configuration.VSToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; Configuration.VSToolbarPosition = ((int)AddinCommandBar.Position).ToString(); Configuration.VS2010ToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VS2010ToolbarWidth = AddinCommandBar.Width.ToString(); Configuration.VS2010ToolbarHeight = AddinCommandBar.Height.ToString(); break; case 2008: Configuration.VSToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; Configuration.VSToolbarPosition = ((int)AddinCommandBar.Position).ToString(); break; case 2010: Configuration.VSToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VSToolbarLeft = AddinCommandBar.Left.ToString(); Configuration.VSToolbarTop = AddinCommandBar.Top.ToString(); Configuration.VSToolbarWidth = AddinCommandBar.Width.ToString(); break; default: Configuration.VS2010ToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; Configuration.VS2010ToolbarPosition = AddinCommandBar.Position.ToString(); break; }
![Page 47: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/47.jpg)
public class ToolbarManager { public void SaveToolbarState() { var version = Core.GetVisualStudioVersion();
Configuration.VSToolbarHeight = AddinCommandBar.Height.ToString(); if (version <= 2003) { Configuration.VS2010ToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; Configuration.VS2010ToolbarPosition = AddinCommandBar.Position.ToString(); } else if (version >= 2005 && version <= 2008) { Configuration.VSToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; Configuration.VSToolbarPosition = ((int)AddinCommandBar.Position).ToString();
} else if (version == 2010) { Configuration.VSToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VSToolbarLeft = AddinCommandBar.Left.ToString(); Configuration.VSToolbarTop = AddinCommandBar.Top.ToString(); Configuration.VSToolbarWidth = AddinCommandBar.Width.ToString(); } else { Configuration.VSToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; Configuration.VSToolbarPosition = ((int)AddinCommandBar.Position).ToString(); Configuration.VS2010ToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VS2010ToolbarWidth = AddinCommandBar.Width.ToString(); Configuration.VS2010ToolbarHeight = AddinCommandBar.Height.ToString(); } }
![Page 48: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/48.jpg)
private void SaveForVs2003() { Configuration.VSToolbarVisible = "False"; Configuration.VSToolbarPosition = ((int)AddinCommandBar.Position).ToString(); Configuration.VS2010ToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VS2010ToolbarWidth = AddinCommandBar.Width.ToString(); Configuration.VS2010ToolbarHeight = AddinCommandBar.Height.ToString(); }
private void SaveForVs2005() { Configuration.VSToolbarVisible = "True"; Configuration.VSToolbarPosition = ((int)AddinCommandBar.Position).ToString(); Configuration.VS2010ToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VS2010ToolbarWidth = AddinCommandBar.Width.ToString(); Configuration.VS2010ToolbarHeight = AddinCommandBar.Height.ToString(); Configuration.VS2010ToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; }
private void SaveForVs2008() { Configuration.VSToolbarPosition = "False"; Configuration.VS2010ToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VS2010ToolbarVisible = "False"; Configuration.VS2010ToolbarWidth = AddinCommandBar.Width.ToString(); Configuration.VS2010ToolbarHeight = AddinCommandBar.Height.ToString();
} private void SaveForVs2010() { Configuration.VSToolbarVisible = AddinCommandBar.Visible ? "True" : "False"; Configuration.VSToolbarPosition = "False"; Configuration.VS2010ToolbarRowIndex = AddinCommandBar.RowIndex.ToString(); Configuration.VS2010ToolbarWidth = AddinCommandBar.Width.ToString(); Configuration.VS2010ToolbarHeight = AddinCommandBar.Height.ToString(); }
![Page 49: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/49.jpg)
public class ToolbarManager { private readonly Dictionary<long, Action> _versionAction;
public ToolbarManager() { _versionAction = new Dictionary<long, Action>(); _versionAction.Add(2003, SaveForVs2003); _versionAction.Add(2005, SaveForVs2005); _versionAction.Add(2008, SaveForVs2008); _versionAction.Add(2010, SaveForVs2010); }
public void SaveToolbarStateBetter() { var version = Core.GetVisualStudioVersion();
if (_versionAction.ContainsKey(version)) { _versionAction[version].Invoke(); }
}
![Page 50: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/50.jpg)
public class ToolbarManager { private readonly Dictionary<long, Action> _versionAction;
public ToolbarManager() { _versionAction = new Dictionary<long, Action>(); _versionAction.Add(2003, SaveForVs2003); _versionAction.Add(2005, SaveForVs2005); _versionAction.Add(2008, SaveForVs2008); _versionAction.Add(2010, SaveForVs2010); _versionAction.Add(2012, SaveForVs2012); }
private void SaveForVs2012() { Configuration.EnableSpeechRecognition = "True"; Configuration.HandGestureRecognition = AddinCommandBar.Top; }
![Page 51: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/51.jpg)
Liskov Substitution Principle
If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T
![Page 52: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/52.jpg)
Liskov Substitution Principle
Subtypes must be substitutable for their base types
Inheritance and polymorphism
![Page 53: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/53.jpg)
public class Rectangle { public int Width { get; set; }
public int Height { get; set; }
public int GetArea() { return Width*Height; } }
![Page 54: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/54.jpg)
[TestFixture]public class RectangleTests{ [Test] public void CheckArea_PassingTest() { Rectangle r = new Rectangle(); CheckAreaOfRectangle(r); }
private void CheckAreaOfRectangle(Rectangle r) { r.Width = 5; r.Height = 2;
Assert.AreEqual(10, r.GetArea()); }
}
![Page 55: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/55.jpg)
We need a Square!
![Page 56: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/56.jpg)
public class Rectangle { protected int _width; public virtual int Width { get { return _width; } set { _width = value; } }
protected int _height; public virtual int Height { get { return _height; } set { _height = value; } }
public int GetArea() { return Width*Height; } }
public class Square : Rectangle { public override int Width { get { return _width; } set { _width = value; _height = value; } } public override int Height { get { return _height; } set { _height = value; _width = value; } } }
![Page 57: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/57.jpg)
[TestFixture]public class RectangleTests{ [Test] public void CheckArea_PassingTest() { Rectangle r = new Rectangle(); CheckAreaOfRectangle(r); }
private void CheckAreaOfRectangle(Rectangle r) { r.Width = 5; r.Height = 2;
Assert.AreEqual(10, r.GetArea()); }
[Test] public void CheckArea_FAILINGTest() { Rectangle r = new Square(); CheckAreaOfRectangle(r); }
}
![Page 58: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/58.jpg)
public class Rectangle { public int Width { get; set; }
public int Height { get; set; }
public int GetArea() { return Width * Height; } }
public class Square { public int Side { get; set; }
public int GetArea() { return Side * Side; }
}
![Page 59: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/59.jpg)
Interface Segregation Principle
Don’t be force to implement unused methods
Avoid “Fat Interfaces”
Clients should not be forced to depend on methods they do not use
![Page 60: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/60.jpg)
public override bool ValidateUser(string usercode, string password) { var returnValue = false;
MoneyService moneyServices = new MoneyService();
if (moneyServices.IsValid(usercode, password)) { returnValue = true; }
return returnValue; }
-- snip snip snip ----
public class MoneyMembershipProvider : MembershipProvider {
![Page 61: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/61.jpg)
namespace System.Web.Security{ public abstract class MembershipProvider : ProviderBase { public abstract bool EnablePasswordRetrieval { get; } public abstract bool EnablePasswordReset { get; } public abstract bool RequiresQuestionAndAnswer { get; } public abstract string ApplicationName { get; set; } public abstract int MaxInvalidPasswordAttempts { get; } public abstract int PasswordAttemptWindow { get; } public abstract bool RequiresUniqueEmail { get; } public abstract MembershipPasswordFormat PasswordFormat { get; } public abstract int MinRequiredPasswordLength { get; } public abstract int MinRequiredNonAlphanumericCharacters { get; } public abstract string PasswordStrengthRegularExpression { get; }
public abstract MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);
public abstract bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer);
public abstract string GetPassword(string username, string answer); public abstract bool ChangePassword(string username, string oldPassword, string newPassword); public abstract string ResetPassword(string username, string answer); public abstract void UpdateUser(MembershipUser user); public abstract bool ValidateUser(string username, string password); public abstract bool UnlockUser(string userName); public abstract MembershipUser GetUser(object providerUserKey, bool userIsOnline); public abstract MembershipUser GetUser(string username, bool userIsOnline); public abstract string GetUserNameByEmail(string email); public abstract bool DeleteUser(string username, bool deleteAllRelatedData); public abstract MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords); public abstract int GetNumberOfUsersOnline();
public abstract MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);
public abstract MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords);
protected virtual byte[] EncryptPassword(byte[] password);
protected virtual byte[] EncryptPassword(byte[] password, MembershipPasswordCompatibilityMode legacyPasswordCompatibilityMode);
protected virtual byte[] DecryptPassword(byte[] encodedPassword); protected virtual void OnValidatingPassword(ValidatePasswordEventArgs e); public event MembershipValidatePasswordEventHandler ValidatingPassword; }}
![Page 62: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/62.jpg)
public class AuctionsPlusMembershipProvider : MembershipProvider {
-- snip snip snip ----
public override bool ChangePassword(string username, string oldPassword, string newPassword) { throw new NotImplementedException(); }
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) { throw new NotImplementedException(); }
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) { throw new NotImplementedException(); }
public override bool DeleteUser(string username, bool deleteAllRelatedData) { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
![Page 63: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/63.jpg)
public interface IEnableUservalidation { bool ValidateUser(string username, string password); }
public interface IAllowUserRetrieval { MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords); MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords); MembershipUser GetUser(object providerUserKey, bool userIsOnline); MembershipUser GetUser(string username, bool userIsOnline); string GetUserNameByEmail(string email); MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords); int GetNumberOfUsersOnline(); }
public interface IProvidePassword { bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer);
bool ChangePassword(string username, string oldPassword, string newPassword); string ResetPassword(string username, string answer);
string GetPassword(string username, string answer); }
![Page 64: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/64.jpg)
Dependency Inversion Principle
Depend on Abstractions Interfaces, not concrete types
Inject Dependencies into Classes
Inversion of ControlHollywood Principle: "Don't call us, We call you"
I tell an object its partners, and not the object chooses its partners
![Page 65: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/65.jpg)
public class WCFSalaryService { private IDBHelper dbHelper = new SQLHelper(); private ILoggerHelper loggerHelper = new FileLogWriter(); private IAuthenticationHelper authenticationHelper = new WebServiceAuth(); private IUserUtility userHelper; private IConnections connectionHelper = new HTTPConnectionHelper();
public WCFSalaryService() { userHelper = new UserHelper(connectionHelper); userHelper.Logger = loggerHelper; dbHelper.Logger = loggerHelper;
// ----- snip snip snip ---- }
// ----- snip snip snip ---- }
![Page 66: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/66.jpg)
private IDBHelper _dbHelper; private ILoggerHelper _loggerHelper; private IAuthenticationHelper _authenticationHelper; private IUserUtility _userHelper; private IConnections _connectionHelper;
public WCFSalaryService( IDBHelper dbHelper, ILoggerHelper loggerHelper, IAuthenticationHelper authenticationHelper, IUserUtility userHelper, IConnections connectionHelper) { _dbHelper = dbHelper; _loggerHelper = loggerHelper; _authenticationHelper = authenticationHelper; _userHelper = userHelper; _connectionHelper = connectionHelper;
![Page 67: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/67.jpg)
private IDBHelper _dbHelper; private ILoggerHelper _loggerHelper = new FileLogWriter(); private IAuthenticationHelper _authenticationHelper = new WebserviceAuth(); private IUserUtility _userHelper; private IConnections _connectionHelper;
public WCFSalaryService( IDBHelper dbHelper, ILoggerHelper loggerHelper, IAuthenticationHelper authenticationHelper, IUserUtility userHelper, IConnections connectionHelper) { _userHelper = new UserHelper(connectionHelper); _userHelper.Logger = loggerHelper;
if (authenticationHelper != null) { _authenticationHelper = authenticationHelper; }
if (dbHelper != null) { _connectionHelper.DbHelper = dbHelper; _authenticationHelper.DbHelper = dbHelper; } else { _connectionHelper.DbHelper = DBHelper.Instance; _authenticationHelper.DbHelper = DBHelper.Instance; }
if (loggerHelper != null) { this._loggerHelper = loggerHelper; }
_userHelper.LoggerHelper = this._loggerHelper; _authenticationHelper.LoggerHelper = this._loggerHelper; _connectionHelper.LoggerHelper = this._loggerHelper; // ----- snip snip snip ---- }
![Page 68: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/68.jpg)
![Page 69: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/69.jpg)
public class SalaryScenario : NinjectModule { public override void Load() { Bind<ILoggerHelper>().To<FileLogWriter>(); Bind<IDBHelper>().To<SQLHelper>(); Bind<IAuthenticationHelper>().To<WebServiceAuth>(); Bind<IUserUtility>().To<UserUtility>(); Bind<IConnections>().To<HTTPConnectionHelper>(); } }
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { IKernel kernel = new StandardKernel (new SalaryScenario());
var logger = kernel.Get<ILoggerHelper>(); logger.LogIt("App started up"); }
![Page 70: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/70.jpg)
Solid PrinciplesS.o.l.i.d. Principles
![Page 71: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/71.jpg)
Adam: "What you cant measure you cant improve!"
Measure clean code
![Page 72: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/72.jpg)
![Page 73: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/73.jpg)
• Dependency Diagrams (VS2010)• StyleCop• Code Analysis (VS2010)• Code Metrics (VS2010)• Nitriq
Tools!
![Page 74: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/74.jpg)
• Code Auditor• ReSharper / CodeRush / Refactor Pro• Atomiq• SourceMonitor• NDepend
And more...
More Tools!
![Page 75: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/75.jpg)
No tool can replace a code review
![Page 76: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/76.jpg)
"Writing code a computer can understand is science. Writing code other programmers can understand is an art."
Jason Gorman
Its not easy
![Page 77: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/77.jpg)
From now on...
![Page 78: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/78.jpg)
Readable Code
![Page 79: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/79.jpg)
Tests
![Page 80: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/80.jpg)
Avoid Duplication
![Page 81: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/81.jpg)
• Readable• Tests in place• No duplication
"Wartung"
What is clean code?
![Page 82: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/82.jpg)
• Why code matters• Good and Bad Code• The Broken Window Theory• The Grand Redesign in the Sky• The Boy Scout Rule
• OOP Patterns and Principles• SOLID Principles
• How to measure clean code?• Tools
Summary
![Page 83: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/83.jpg)
Further Reading
![Page 84: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/84.jpg)
Further Reading
![Page 85: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/85.jpg)
Further Reading
![Page 86: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/86.jpg)
Further Reading
![Page 88: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/88.jpg)
VS2010 Code Metrics
http://bit.ly/bda4T1
JB Rainsberger The Four Elements of Simple Design
http://www.jbrains.ca/permalink/the-four-elements-of-simple-design
How to hire a programmer? Have people fix up some smelly code
http://codebetter.com/blogs/karlseguin/archive/2006/12/01/How-to-hire-a-programmer-_2D00_-Part-2-_2D00_-Improve-this-code.aspx
C# Coding Practices
http://www.codeproject.com/KB/cs/CSharp_Coding_Practices.aspx
Object Oriented Principles
http://www.objectmentor.com/omSolutions/oops_what.html
Further Reading
![Page 89: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/89.jpg)
http://www.refactoring.com/
http://refactormycode.com/
All links and slides on
http://blog.gfader.com/
Further Doing
![Page 90: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/90.jpg)
VS2010http://msdn.microsoft.com/en-us/vstudio/
Nitriq & Atomiqhttp://nimblepros.com/products.aspx
SourceMonitorhttp://www.campwoodsw.com/sourcemonitor.html
Ndependhttp://www.ndepend.com/
Tools References
![Page 91: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/91.jpg)
Better SoftwareAn introduction to good code
Giordano Scalzo, 06/05/2009
Thanks toGiordano!
![Page 92: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/92.jpg)
http://creativecommons.org/licenses/by-nc-sa/3.0/
![Page 93: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/93.jpg)
Be a boy scoutLeave the campground cleaner than you found it
![Page 94: Clean Code Development](https://reader036.vdocuments.mx/reader036/viewer/2022081413/5479557fb4af9f3c5e8b4618/html5/thumbnails/94.jpg)
Be a boy scoutLeave code cleaner than you found it
All links and slides on
http://blog.gfader.com
Thank you!!!