Top Banner
Clean Code Development Peter Gfader #netug Delivering Awesome Web Applications
94

Clean Code Development

Nov 29, 2014

Download

Technology

Peter Gfader

Good and Bad Code
The Broken Window Theory
The Grand Redesign in the Sky
The Sushi Chef Rule
The Hotel Room Rule
The Boy Scout Rule

OOP Patterns and Principles
SOLID Principles

How to measure clean code?
Tools
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Clean Code Development

Clean Code Development

Peter Gfader#netug

Delivering Awesome Web Applications

Page 2: Clean Code Development

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

• 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

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

1969We landed on the moon

Why code matters?

Page 6: Clean Code Development

TodayWe fly around the world in 32 hoursTourists in space

Why code matters?

Page 7: Clean Code Development

1903 - 0 computers

Why code matters?

Page 8: Clean Code Development

40 years later - a handful of computers

Why code matters?

Page 9: Clean Code Development

Today > 500 billion programmable devices

Why code matters?

Page 10: Clean Code Development

Today > 500 billion programmable devices (more than humans on earth)

Why code matters?

Page 11: Clean Code Development

2100Programmable devices everywhereUnder skin, in brain, in blood… like dust…

Why code matters?

Page 12: Clean Code Development

Who programs those?

Why code matters?

Page 13: Clean Code Development

Why code matters?

What tools do we use?

Page 14: Clean Code Development

Why code matters?

Can we trust our code?

Important?

Page 15: Clean Code Development

What is good code?

Page 16: Clean Code Development

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

What is bad code?

Page 18: Clean Code Development

What is bad code?

Page 19: Clean Code Development

What is bad code?

Page 20: Clean Code Development

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

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

What is bad code?

Page 23: Clean Code Development

• Hard to understand at first sight• Unmaintained• Messy• No one cares

What is bad code?

Page 24: Clean Code Development

• Hard to understand at first sight• Unmaintained• Messy• No one cares

"Wartung"? (aka Maintainabilty)

What is bad code?

Page 25: Clean Code Development

Bad Code

Is SCARY!!!

Page 26: Clean Code Development

Why are we writing bad code?

Page 27: Clean Code Development
Page 28: Clean Code Development

Broken Window Theory

Page 29: Clean Code Development

Broken Window Theory

Page 30: Clean Code Development

The rewrite

Page 31: Clean Code Development

Netscape

rewrote Netscape 4.0 and released it after three years as Netscape 6.0

Page 32: Clean Code Development

Borland

rewrote dBase and Quattro Pro

Page 33: Clean Code Development

Microsoft

Rewrote Vista~60%

Page 34: Clean Code Development

What can we do?

Page 35: Clean Code Development

Sushi chef rule

Clean up as you doNA

Page 36: Clean Code Development

Hotel room rule

Let someone clean up every dayNA

Page 37: Clean Code Development

The Boy Scout Rule

Leave the campground cleaner than you found it OK

Page 38: Clean Code Development

How can we improve?

Page 39: Clean Code Development

"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

OOP Principles

Page 41: Clean Code Development

Solid PrinciplesS.o.l.i.d. Principles

Page 42: Clean Code Development

Single Responsibility Principle

Only one reason to change

Robustness

Focus

Every entity should have a single responsibility

Page 43: Clean Code Development

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

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

OpenClose Principle

Open for extension

Close for modification

Every entity should be open for extension, but closed for modification

Page 46: Clean Code Development

        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

    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

        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

    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

    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

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

Liskov Substitution Principle

Subtypes must be substitutable for their base types

Inheritance and polymorphism

Page 53: Clean Code Development

    public class Rectangle    {        public int Width { get; set; }

        public int Height { get; set; }

        public int GetArea()        {            return Width*Height;        }     }

Page 54: Clean Code Development

[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

We need a Square!

Page 56: Clean Code Development

    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

[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

    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

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

        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

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

     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

    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

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

    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

        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

        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
Page 69: Clean Code Development

    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

Solid PrinciplesS.o.l.i.d. Principles

Page 71: Clean Code Development

Adam: "What you cant measure you cant improve!"

Measure clean code

Page 72: Clean Code Development
Page 73: Clean Code Development

• Dependency Diagrams (VS2010)• StyleCop• Code Analysis (VS2010)• Code Metrics (VS2010)• Nitriq

Tools!

Page 74: Clean Code Development

• Code Auditor• ReSharper / CodeRush / Refactor Pro• Atomiq• SourceMonitor• NDepend

And more...

More Tools!

Page 75: Clean Code Development

No tool can replace a code review

Page 76: Clean Code Development

"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

From now on...

Page 78: Clean Code Development

Readable Code

Page 79: Clean Code Development

Tests

Page 80: Clean Code Development

Avoid Duplication

Page 81: Clean Code Development

• Readable• Tests in place• No duplication

"Wartung"

What is clean code?

Page 82: Clean Code Development

• 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

Further Reading

Page 84: Clean Code Development

Further Reading

Page 85: Clean Code Development

Further Reading

Page 86: Clean Code Development

Further Reading

Page 87: Clean Code Development

http://www.clean-code-developer.de/

Page 88: Clean Code Development

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

http://www.refactoring.com/

http://refactormycode.com/

All links and slides on

http://blog.gfader.com/

Further Doing

Page 90: Clean Code Development

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

Better SoftwareAn introduction to good code

Giordano Scalzo, 06/05/2009

Thanks toGiordano!

Page 92: Clean Code Development

http://creativecommons.org/licenses/by-nc-sa/3.0/

Page 93: Clean Code Development

Be a boy scoutLeave the campground cleaner than you found it

Page 94: Clean Code Development

Be a boy scoutLeave code cleaner than you found it

All links and slides on

http://blog.gfader.com

Thank you!!!