SlideShare uma empresa Scribd logo
1 de 94
Clean Code Development
Peter Gfader
#netug
Delivering Awesome Web Applications
C# and .NET
(Java not anymore)
Testing
Automated tests
Agile, Scrum
Scrum Developer Trainer
Technology aficionado
Silverlight
ASP.NET
Windows Forms
LINQ,
...
Peter Gfader
http://blog.gfader.com/
twitter.com/peitor
#netug
• 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
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/
1969
We landed on the moon
Why code matters?
Today
We fly around the world in 32 hours
Tourists in space
Why code matters?
1903 - 0 computers
Why code matters?
40 years later - a handful of computers
Why code matters?
Today > 500 billion programmable devices
Why code matters?
Today > 500 billion programmable devices
(more than humans on earth)
Why code matters?
2100
Programmable devices everywhere
Under skin, in brain, in blood… like dust…
Why code matters?
Who programs those?
Why code matters?
Why code matters?
What tools do we use?
Why code matters?
Can we trust our code?
Important?
What is good code?
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?
What is bad code?
What is bad code?
What is bad code?
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?
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?
What is bad code?
• Hard to understand at first sight
• Unmaintained
• Messy
• No one cares
What is bad code?
• Hard to understand at first sight
• Unmaintained
• Messy
• No one cares
"Wartung"? (aka Maintainabilty)
What is bad code?
Bad Code
Is SCARY!!!
Why are we writing bad code?
Broken Window Theory
Broken Window Theory
The rewrite
Netscape
rewrote Netscape 4.0 and released it
after three years as Netscape 6.0
Borland
rewrote dBase and Quattro Pro
Microsoft
Rewrote Vista
~60%
What can we do?
Sushi chef rule
Clean up as you do
Hotel room rule
Let someone clean up every day
The Boy Scout Rule
Leave the campground cleaner than you found it
How can we improve?
"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?
OOP Principles
Solid PrinciplesS.o.l.i.d. Principles
Single Responsibility Principle
Only one reason to change
Robustness
Focus
Every entity should have a single responsibility
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;
// ...
}
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) { //...
}
}
OpenClose Principle
Open for extension
Close for modification
Every entity should be open for extension, but closed for modification
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;
}
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();
}
}
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();
}
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();
}
}
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;
}
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
Liskov Substitution Principle
Subtypes must be substitutable for their base types
Inheritance and polymorphism
public class Rectangle
{
public int Width { get; set; }
public int Height { get; set; }
public int GetArea()
{
return Width*Height;
}
}
[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());
}
}
We need a Square!
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;
}
}
}
[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);
}
}
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;
}
}
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
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
{
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);
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 newPa
{
throw new NotImplementedException();
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passw
{
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 totalRecord
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalReco
{
throw new NotImplementedException();
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
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);
}
Dependency Inversion Principle
Depend on Abstractions
Interfaces, not concrete types
Inject Dependencies into Classes
Inversion of Control
Hollywood Principle: "Don't call us, We call you"
I tell an object its partners,
and not the object chooses its partners
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 ----
}
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;
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 ----
}
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");
}
Solid PrinciplesS.o.l.i.d. Principles
Adam:
"What you cant measure you cant improve!"
Measure clean code
• Dependency Diagrams (VS2010)
• StyleCop
• Code Analysis (VS2010)
• Code Metrics (VS2010)
• Nitriq
Tools!
• Code Auditor
• ReSharper / CodeRush / Refactor Pro
• Atomiq
• SourceMonitor
• NDepend
And more...
More Tools!
No tool
can replace a
code review
"Writing code a computer can understand is
science.
Writing code other programmers can
understand is an art."
Jason Gorman
Its not easy
From now on...
Readable Code
Tests
Avoid Duplication
• Readable
• Tests in place
• No duplication
"Wartung"
What is clean code?
• 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
Further Reading
Further Reading
Further Reading
Further Reading
http://www.clean-code-developer.de/
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
http://www.refactoring.com/
http://refactormycode.com/
All links and slides on
http://blog.gfader.com/
Further Doing
VS2010
http://msdn.microsoft.com/en-us/vstudio/
Nitriq & Atomiq
http://nimblepros.com/products.aspx
SourceMonitor
http://www.campwoodsw.com/sourcemonitor.html
Ndepend
http://www.ndepend.com/
Tools References
Better Software
An introduction to good code
Giordano Scalzo, 06/05/2009
Thanks to
Giordano!
http://creativecommons.org/licenses/by-nc-sa/3.0/
Be a boy scout
Leave the campground cleaner than you found it
Be a boy scout
Leave code cleaner than you found it
All links and slides on
http://blog.gfader.com
Thank you!!!

Mais conteúdo relacionado

Mais procurados

JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven PractisesRobert MacLean
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerAndrey Karpov
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Guillaume Laforge
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Victor_Cr
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your GroovyAlonso Torres
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript TutorialBui Kiet
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smellsPaul Nguyen
 
Indexing thousands of writes per second with redis
Indexing thousands of writes per second with redisIndexing thousands of writes per second with redis
Indexing thousands of writes per second with redispauldix
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Aaron Gustafson
 
JavaScript introduction 1 ( Variables And Values )
JavaScript introduction 1 ( Variables And Values )JavaScript introduction 1 ( Variables And Values )
JavaScript introduction 1 ( Variables And Values )Victor Verhaagen
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScriptMichael Girouard
 

Mais procurados (20)

Specs2
Specs2Specs2
Specs2
 
Bottom Up
Bottom UpBottom Up
Bottom Up
 
JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven Practises
 
Headless Js Testing
Headless Js TestingHeadless Js Testing
Headless Js Testing
 
Polyglot JVM
Polyglot JVMPolyglot JVM
Polyglot JVM
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
 
C++ L09-Classes Part2
C++ L09-Classes Part2C++ L09-Classes Part2
C++ L09-Classes Part2
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript Tutorial
 
Refactoring and code smells
Refactoring and code smellsRefactoring and code smells
Refactoring and code smells
 
Indexing thousands of writes per second with redis
Indexing thousands of writes per second with redisIndexing thousands of writes per second with redis
Indexing thousands of writes per second with redis
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
JavaScript introduction 1 ( Variables And Values )
JavaScript introduction 1 ( Variables And Values )JavaScript introduction 1 ( Variables And Values )
JavaScript introduction 1 ( Variables And Values )
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
Clean code
Clean codeClean code
Clean code
 

Destaque

Advanced Silverlight
Advanced SilverlightAdvanced Silverlight
Advanced Silverlightrsnarayanan
 
Silverlight vs HTML5 - Lessons learned from the real world...
Silverlight vs HTML5 - Lessons learned from the real world...Silverlight vs HTML5 - Lessons learned from the real world...
Silverlight vs HTML5 - Lessons learned from the real world...Peter Gfader
 
Innovation durch Scrum und Continuous Delivery
Innovation durch Scrum und Continuous DeliveryInnovation durch Scrum und Continuous Delivery
Innovation durch Scrum und Continuous DeliveryPeter Gfader
 
Testing with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs LifeTesting with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs LifePeter Gfader
 
Reports with SQL Server Reporting Services
Reports with SQL Server Reporting ServicesReports with SQL Server Reporting Services
Reports with SQL Server Reporting ServicesPeter Gfader
 
Clean Code - How to write comprehensible code regarding cognitive abilities o...
Clean Code - How to write comprehensible code regarding cognitive abilities o...Clean Code - How to write comprehensible code regarding cognitive abilities o...
Clean Code - How to write comprehensible code regarding cognitive abilities o...Mario Gleichmann
 
Redis training for java software engineers
Redis training for java software engineersRedis training for java software engineers
Redis training for java software engineersMoshe Kaplan
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionKent Huang
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeMario Gleichmann
 
Continuous Delivery with TFS msbuild msdeploy
Continuous Delivery with TFS msbuild msdeployContinuous Delivery with TFS msbuild msdeploy
Continuous Delivery with TFS msbuild msdeployPeter Gfader
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8Sergiu Mircea Indrie
 
OLAP – Creating Cubes with SQL Server Analysis Services
OLAP – Creating Cubes with SQL Server Analysis ServicesOLAP – Creating Cubes with SQL Server Analysis Services
OLAP – Creating Cubes with SQL Server Analysis ServicesPeter Gfader
 
Clean Code (Presentacion interna en Virtual Software)
Clean Code (Presentacion interna en Virtual Software)Clean Code (Presentacion interna en Virtual Software)
Clean Code (Presentacion interna en Virtual Software)jmiguel rodriguez
 
Java data structures powered by Redis. Introduction to Redisson @ Redis Light...
Java data structures powered by Redis. Introduction to Redisson @ Redis Light...Java data structures powered by Redis. Introduction to Redisson @ Redis Light...
Java data structures powered by Redis. Introduction to Redisson @ Redis Light...Nikita Koksharov
 
SSAS - Other Cube Browsers
SSAS - Other Cube BrowsersSSAS - Other Cube Browsers
SSAS - Other Cube BrowsersPeter Gfader
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best PracticesTheo Jungeblut
 
Don't make me wait! or Building High-Performance Web Applications
Don't make me wait! or Building High-Performance Web ApplicationsDon't make me wait! or Building High-Performance Web Applications
Don't make me wait! or Building High-Performance Web ApplicationsStoyan Stefanov
 

Destaque (19)

Advanced Silverlight
Advanced SilverlightAdvanced Silverlight
Advanced Silverlight
 
Silverlight vs HTML5 - Lessons learned from the real world...
Silverlight vs HTML5 - Lessons learned from the real world...Silverlight vs HTML5 - Lessons learned from the real world...
Silverlight vs HTML5 - Lessons learned from the real world...
 
Innovation durch Scrum und Continuous Delivery
Innovation durch Scrum und Continuous DeliveryInnovation durch Scrum und Continuous Delivery
Innovation durch Scrum und Continuous Delivery
 
Testing with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs LifeTesting with VS2010 - A Bugs Life
Testing with VS2010 - A Bugs Life
 
Reports with SQL Server Reporting Services
Reports with SQL Server Reporting ServicesReports with SQL Server Reporting Services
Reports with SQL Server Reporting Services
 
Clean Code - How to write comprehensible code regarding cognitive abilities o...
Clean Code - How to write comprehensible code regarding cognitive abilities o...Clean Code - How to write comprehensible code regarding cognitive abilities o...
Clean Code - How to write comprehensible code regarding cognitive abilities o...
 
Redis training for java software engineers
Redis training for java software engineersRedis training for java software engineers
Redis training for java software engineers
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible code
 
Continuous Delivery with TFS msbuild msdeploy
Continuous Delivery with TFS msbuild msdeployContinuous Delivery with TFS msbuild msdeploy
Continuous Delivery with TFS msbuild msdeploy
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8
 
OLAP – Creating Cubes with SQL Server Analysis Services
OLAP – Creating Cubes with SQL Server Analysis ServicesOLAP – Creating Cubes with SQL Server Analysis Services
OLAP – Creating Cubes with SQL Server Analysis Services
 
Clean Code (Presentacion interna en Virtual Software)
Clean Code (Presentacion interna en Virtual Software)Clean Code (Presentacion interna en Virtual Software)
Clean Code (Presentacion interna en Virtual Software)
 
Clean Code
Clean CodeClean Code
Clean Code
 
OOP Basics
OOP BasicsOOP Basics
OOP Basics
 
Java data structures powered by Redis. Introduction to Redisson @ Redis Light...
Java data structures powered by Redis. Introduction to Redisson @ Redis Light...Java data structures powered by Redis. Introduction to Redisson @ Redis Light...
Java data structures powered by Redis. Introduction to Redisson @ Redis Light...
 
SSAS - Other Cube Browsers
SSAS - Other Cube BrowsersSSAS - Other Cube Browsers
SSAS - Other Cube Browsers
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
 
Don't make me wait! or Building High-Performance Web Applications
Don't make me wait! or Building High-Performance Web ApplicationsDon't make me wait! or Building High-Performance Web Applications
Don't make me wait! or Building High-Performance Web Applications
 

Semelhante a Clean Code Development

A miało być tak... bez wycieków
A miało być tak... bez wyciekówA miało być tak... bez wycieków
A miało być tak... bez wyciekówKonrad Kokosa
 
Adopting F# at SBTech
Adopting F# at SBTechAdopting F# at SBTech
Adopting F# at SBTechAntya Dev
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mockskenbot
 
FITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endFITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endThibault Imbert
 
Technology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertTechnology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertFITC
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesAndrey Karpov
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerAndrey Karpov
 
Programas decompiladores
Programas decompiladoresProgramas decompiladores
Programas decompiladoresZulay Limaico
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...DevGAMM Conference
 
A la découverte de TypeScript
A la découverte de TypeScriptA la découverte de TypeScript
A la découverte de TypeScriptDenis Voituron
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Juan Pablo
 
Better Software: introduction to good code
Better Software: introduction to good codeBetter Software: introduction to good code
Better Software: introduction to good codeGiordano Scalzo
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeWim Godden
 
Some examples of the 64-bit code errors
Some examples of the 64-bit code errorsSome examples of the 64-bit code errors
Some examples of the 64-bit code errorsPVS-Studio
 
.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#Bertrand Le Roy
 

Semelhante a Clean Code Development (20)

A miało być tak... bez wycieków
A miało być tak... bez wyciekówA miało być tak... bez wycieków
A miało być tak... bez wycieków
 
Adopting F# at SBTech
Adopting F# at SBTechAdopting F# at SBTech
Adopting F# at SBTech
 
JavaTalks: OOD principles
JavaTalks: OOD principlesJavaTalks: OOD principles
JavaTalks: OOD principles
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
FITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endFITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an end
 
Technology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertTechnology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault Imbert
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
Programas decompiladores
Programas decompiladoresProgramas decompiladores
Programas decompiladores
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
 
mobl
moblmobl
mobl
 
A la découverte de TypeScript
A la découverte de TypeScriptA la découverte de TypeScript
A la découverte de TypeScript
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Better Software: introduction to good code
Better Software: introduction to good codeBetter Software: introduction to good code
Better Software: introduction to good code
 
Beyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the codeBeyond PHP - It's not (just) about the code
Beyond PHP - It's not (just) about the code
 
C#, What Is Next?
C#, What Is Next?C#, What Is Next?
C#, What Is Next?
 
Some examples of the 64-bit code errors
Some examples of the 64-bit code errorsSome examples of the 64-bit code errors
Some examples of the 64-bit code errors
 
.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#
 

Mais de Peter Gfader

Achieving Technical Excellence in Your Software Teams - from Devternity
Achieving Technical Excellence in Your Software Teams - from Devternity Achieving Technical Excellence in Your Software Teams - from Devternity
Achieving Technical Excellence in Your Software Teams - from Devternity Peter Gfader
 
You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019
You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019
You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019Peter Gfader
 
You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)
You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)
You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)Peter Gfader
 
How to make more impact as an engineer
How to make more impact as an engineerHow to make more impact as an engineer
How to make more impact as an engineerPeter Gfader
 
13 explosive things you should try as an agilist
13 explosive things you should try as an agilist13 explosive things you should try as an agilist
13 explosive things you should try as an agilistPeter Gfader
 
You cant be agile if your code sucks
You cant be agile if your code sucksYou cant be agile if your code sucks
You cant be agile if your code sucksPeter Gfader
 
Use Scrum and Continuous Delivery to innovate like crazy!
Use Scrum and Continuous Delivery to innovate like crazy!Use Scrum and Continuous Delivery to innovate like crazy!
Use Scrum and Continuous Delivery to innovate like crazy!Peter Gfader
 
Qcon london2012 recap
Qcon london2012 recapQcon london2012 recap
Qcon london2012 recapPeter Gfader
 
Data Mining with SQL Server 2008
Data Mining with SQL Server 2008Data Mining with SQL Server 2008
Data Mining with SQL Server 2008Peter Gfader
 
Business Intelligence with SQL Server
Business Intelligence with SQL ServerBusiness Intelligence with SQL Server
Business Intelligence with SQL ServerPeter Gfader
 
SQL Server - Full text search
SQL Server - Full text searchSQL Server - Full text search
SQL Server - Full text searchPeter Gfader
 
Usability AJAX and other ASP.NET Features
Usability AJAX and other ASP.NET FeaturesUsability AJAX and other ASP.NET Features
Usability AJAX and other ASP.NET FeaturesPeter Gfader
 
Work with data in ASP.NET
Work with data in ASP.NETWork with data in ASP.NET
Work with data in ASP.NETPeter Gfader
 
Introduction to ASP.NET
Introduction to ASP.NETIntroduction to ASP.NET
Introduction to ASP.NETPeter Gfader
 
Web services, WCF services and Multi Threading with Windows Forms
Web services, WCF services and Multi Threading with Windows FormsWeb services, WCF services and Multi Threading with Windows Forms
Web services, WCF services and Multi Threading with Windows FormsPeter Gfader
 
N-Tier Application with Windows Forms - Deployment and Security
N-Tier Application with Windows Forms - Deployment and SecurityN-Tier Application with Windows Forms - Deployment and Security
N-Tier Application with Windows Forms - Deployment and SecurityPeter Gfader
 
Better User Experience with .NET
Better User Experience with .NETBetter User Experience with .NET
Better User Experience with .NETPeter Gfader
 
C# advanced topics and future - C#5
C# advanced topics and future - C#5C# advanced topics and future - C#5
C# advanced topics and future - C#5Peter Gfader
 
.NET and C# introduction
.NET and C# introduction.NET and C# introduction
.NET and C# introductionPeter Gfader
 

Mais de Peter Gfader (20)

Achieving Technical Excellence in Your Software Teams - from Devternity
Achieving Technical Excellence in Your Software Teams - from Devternity Achieving Technical Excellence in Your Software Teams - from Devternity
Achieving Technical Excellence in Your Software Teams - from Devternity
 
You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019
You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019
You Can't Be Agile If Your Testing Practices Suck - Vilnius October 2019
 
You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)
You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)
You Cant Be Agile If Your Code Sucks (with 9 Tips For Dev Teams)
 
How to make more impact as an engineer
How to make more impact as an engineerHow to make more impact as an engineer
How to make more impact as an engineer
 
13 explosive things you should try as an agilist
13 explosive things you should try as an agilist13 explosive things you should try as an agilist
13 explosive things you should try as an agilist
 
You cant be agile if your code sucks
You cant be agile if your code sucksYou cant be agile if your code sucks
You cant be agile if your code sucks
 
Use Scrum and Continuous Delivery to innovate like crazy!
Use Scrum and Continuous Delivery to innovate like crazy!Use Scrum and Continuous Delivery to innovate like crazy!
Use Scrum and Continuous Delivery to innovate like crazy!
 
Speed = $$$
Speed = $$$Speed = $$$
Speed = $$$
 
Qcon london2012 recap
Qcon london2012 recapQcon london2012 recap
Qcon london2012 recap
 
Data Mining with SQL Server 2008
Data Mining with SQL Server 2008Data Mining with SQL Server 2008
Data Mining with SQL Server 2008
 
Business Intelligence with SQL Server
Business Intelligence with SQL ServerBusiness Intelligence with SQL Server
Business Intelligence with SQL Server
 
SQL Server - Full text search
SQL Server - Full text searchSQL Server - Full text search
SQL Server - Full text search
 
Usability AJAX and other ASP.NET Features
Usability AJAX and other ASP.NET FeaturesUsability AJAX and other ASP.NET Features
Usability AJAX and other ASP.NET Features
 
Work with data in ASP.NET
Work with data in ASP.NETWork with data in ASP.NET
Work with data in ASP.NET
 
Introduction to ASP.NET
Introduction to ASP.NETIntroduction to ASP.NET
Introduction to ASP.NET
 
Web services, WCF services and Multi Threading with Windows Forms
Web services, WCF services and Multi Threading with Windows FormsWeb services, WCF services and Multi Threading with Windows Forms
Web services, WCF services and Multi Threading with Windows Forms
 
N-Tier Application with Windows Forms - Deployment and Security
N-Tier Application with Windows Forms - Deployment and SecurityN-Tier Application with Windows Forms - Deployment and Security
N-Tier Application with Windows Forms - Deployment and Security
 
Better User Experience with .NET
Better User Experience with .NETBetter User Experience with .NET
Better User Experience with .NET
 
C# advanced topics and future - C#5
C# advanced topics and future - C#5C# advanced topics and future - C#5
C# advanced topics and future - C#5
 
.NET and C# introduction
.NET and C# introduction.NET and C# introduction
.NET and C# introduction
 

Último

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 

Último (20)

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 

Clean Code Development

  • 1. Clean Code Development Peter Gfader #netug Delivering Awesome Web Applications
  • 2. C# and .NET (Java not anymore) Testing Automated tests Agile, Scrum Scrum Developer Trainer Technology aficionado Silverlight ASP.NET Windows Forms LINQ, ... Peter Gfader http://blog.gfader.com/ twitter.com/peitor #netug
  • 3. • 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
  • 4. 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/
  • 5. 1969 We landed on the moon Why code matters?
  • 6. Today We fly around the world in 32 hours Tourists in space Why code matters?
  • 7. 1903 - 0 computers Why code matters?
  • 8. 40 years later - a handful of computers Why code matters?
  • 9. Today > 500 billion programmable devices Why code matters?
  • 10. Today > 500 billion programmable devices (more than humans on earth) Why code matters?
  • 11. 2100 Programmable devices everywhere Under skin, in brain, in blood… like dust… Why code matters?
  • 12. Who programs those? Why code matters?
  • 13. Why code matters? What tools do we use?
  • 14. Why code matters? Can we trust our code? Important?
  • 15. What is good code?
  • 16. 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?
  • 17. What is bad code?
  • 18. What is bad code?
  • 19. What is bad code?
  • 20. 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?
  • 21. 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?
  • 22. What is bad code?
  • 23. • Hard to understand at first sight • Unmaintained • Messy • No one cares What is bad code?
  • 24. • Hard to understand at first sight • Unmaintained • Messy • No one cares "Wartung"? (aka Maintainabilty) What is bad code?
  • 26. Why are we writing bad code?
  • 27.
  • 31. Netscape rewrote Netscape 4.0 and released it after three years as Netscape 6.0
  • 34. What can we do?
  • 35. Sushi chef rule Clean up as you do
  • 36. Hotel room rule Let someone clean up every day
  • 37. The Boy Scout Rule Leave the campground cleaner than you found it
  • 38. How can we improve?
  • 39. "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?
  • 42. Single Responsibility Principle Only one reason to change Robustness Focus Every entity should have a single responsibility
  • 43. 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; // ... }
  • 44. 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) { //... } }
  • 45. OpenClose Principle Open for extension Close for modification Every entity should be open for extension, but closed for modification
  • 46. 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; }
  • 47. 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(); } }
  • 48. 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(); }
  • 49. 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(); } }
  • 50. 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; }
  • 51. 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
  • 52. Liskov Substitution Principle Subtypes must be substitutable for their base types Inheritance and polymorphism
  • 53. public class Rectangle { public int Width { get; set; } public int Height { get; set; } public int GetArea() { return Width*Height; } }
  • 54. [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()); } }
  • 55. We need a Square!
  • 56. 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; } } }
  • 57. [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); } }
  • 58. 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; } }
  • 59. 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
  • 60. 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 {
  • 61. 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);
  • 62. 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 newPa { throw new NotImplementedException(); } public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passw { 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 totalRecord { throw new NotImplementedException(); } public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalReco { throw new NotImplementedException(); } public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) { throw new NotImplementedException(); }
  • 63. 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); }
  • 64. Dependency Inversion Principle Depend on Abstractions Interfaces, not concrete types Inject Dependencies into Classes Inversion of Control Hollywood Principle: "Don't call us, We call you" I tell an object its partners, and not the object chooses its partners
  • 65. 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 ---- }
  • 66. 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;
  • 67. 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 ---- }
  • 68.
  • 69. 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"); }
  • 71. Adam: "What you cant measure you cant improve!" Measure clean code
  • 72.
  • 73. • Dependency Diagrams (VS2010) • StyleCop • Code Analysis (VS2010) • Code Metrics (VS2010) • Nitriq Tools!
  • 74. • Code Auditor • ReSharper / CodeRush / Refactor Pro • Atomiq • SourceMonitor • NDepend And more... More Tools!
  • 75. No tool can replace a code review
  • 76. "Writing code a computer can understand is science. Writing code other programmers can understand is an art." Jason Gorman Its not easy
  • 79. Tests
  • 81. • Readable • Tests in place • No duplication "Wartung" What is clean code?
  • 82. • 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
  • 88. 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
  • 89. http://www.refactoring.com/ http://refactormycode.com/ All links and slides on http://blog.gfader.com/ Further Doing
  • 91. Better Software An introduction to good code Giordano Scalzo, 06/05/2009 Thanks to Giordano!
  • 93. Be a boy scout Leave the campground cleaner than you found it
  • 94. Be a boy scout Leave code cleaner than you found it All links and slides on http://blog.gfader.com Thank you!!!

Notas do Editor

  1. http://blog.gfader.com
  2. Click to add notes...Peter Gfader http://blog.gfader.com
  3. Z1 1936ENIAC 1943, ..
  4. Z1 1936ENIAC 1943, ..
  5. Z1 1936ENIAC 1943, ..
  6. Z1 1936ENIAC 1943, ..
  7. Adams theory on this is: “We will have an exponential growth as soon as code is writing code”
  8. Open Word and get suggestions!CorrectnessUsabilityEfficiencyReliabilityIntegrityAdaptabilityAccuracyRobustness Maintainability FlexibilityPortabilityReusabilityReadabilityTestabilityUnderstandabilityNot too many WTFsEasy to readEasy to maintainConsistent convention (naming, layout, design patterns)Follows SSW rulesCode Auditor 0No bugsDoes what it should do (Client’s needs)Easy to changeWritten in a language, that you can find dev&apos;s forPerformance
  9. Who is a dev? Testers? BA&apos;s? PM&apos;s?
  10. This is a VB programmer, so he probably needs that
  11. HTML spew, I don’t say more… beginner devs underneath covers
  12. Less code = less code to read?Shorter code = faster?Shorter code = less memory?
  13. To get things done?Speed?Meeting Deadlines?Taking Shortcuts..But after too many shortcuts there is no progress...
  14. DBASE was terrible!Look up wikipedia
  15. Sushi Chef rule - Clean up as you doThe Sushi Chef has done this certain routine of hand movements already 100 times before.He is just following this routine.He cleans up as he does his jobs.#1 Software devs do something slightly different every day#2 Devs want to get something done. The brain is in &quot;Get done mode&quot;. Clean up later
  16. What is code?Stuff that a machine reads
  17. High cohesion - better understandability, robustnessLow coupling - better maintainability, high resistance to changes
  18. Naming: Better?IAuthenticationProviderIMembershipProviderIPasswordProvider
  19. StyleCop: Great for your team! Agree on your team style and stick to itCode Analysis
  20. StyleCop: Great for your team! Agree on your team style and stick to itCode Analysis