78
Style & Design Principles Chapter 01: Code Style & Structure Nick Prühs

Style & Design Principles 01 - Code Style & Structure

Embed Size (px)

DESCRIPTION

Chapter 01 of the lecture Style & Design Principles taught at SAE Institute Hamburg. Introduction to naming conventions, type and member design, exception design and common .NET interfaces.

Citation preview

Page 1: Style & Design Principles 01 - Code Style & Structure

Style & Design PrinciplesChapter 01: Code Style & Structure

Nick Prühs

Page 2: Style & Design Principles 01 - Code Style & Structure

About Me

“Best Bachelor“ Computer ScienceKiel University, 2009

Master GamesHamburg University of Applied Sciences, 2011

Lead ProgrammerDaedalic Entertainment, 2011-2012

Co-Founderslash games, 2013

2 / 78

Page 3: Style & Design Principles 01 - Code Style & Structure

First Things First

• At npruehs.de/teaching you‘ll always find• these slides

• solutions to all assignments

• Ask your questions – any time!

• Each lecture will close with• further reading

• an optional assignment

• Contact me any time at [email protected]!

3 / 58

Page 4: Style & Design Principles 01 - Code Style & Structure

Objectives

• To get an idea of good code style and structure in general

• To understand the importance of consistent namingand code conventions

• To learn how to use common tools to write good code more easily

4 / 78

Page 5: Style & Design Principles 01 - Code Style & Structure

What is “good code”?

• Straight-forward and obvious• You’ll spend far more time reading code than writing.

• You’ll spend much time reading code you didn’t write.

• Loose coupling

• Well tested

• Reused code

• Efficient (?)

5 / 78

Page 6: Style & Design Principles 01 - Code Style & Structure

How to achieve “good code”?

Source: http://xkcd.com/844/ 6 / 78

Page 7: Style & Design Principles 01 - Code Style & Structure

How to achieve “good code”?

• Pair programming

• Code Reviews

• Client-first programming, Test-driven development

• Refactoring

• Unit Testing

• Great tools

• Static code analysis

7 / 78

Page 8: Style & Design Principles 01 - Code Style & Structure

Naming Conventions

• Greatly increase readability and usability

• Differ from language to language• We’ll take a look at C#, but many guidelines apply to

other languages as well.

8 / 78

Page 9: Style & Design Principles 01 - Code Style & Structure

C# Capitalization

• PascalCasing• Namespaces

• Types

• Member Names

• camelCasing• Method Parameter Names

9 / 78

Page 10: Style & Design Principles 01 - Code Style & Structure

Capitalization of Acronyms

• Both characters of two-character acronyms• Example: IO

• Only first character of three-character acronyms• Example: Xml, Html

• Never for camelCased identifiers (such as parameters)

10 / 78

Page 11: Style & Design Principles 01 - Code Style & Structure

Word Choice

• Easily readable:• HorizontalAlignment instead of AlignmentHorizontal

• Favor readability over brevity:• CanScrollHorizontally instead of ScrollableX

• No underscores

• No Hungarian notation

• No abbreviations• Abbreviations don’t work well with IDEs.

• Semantic names• GetLength instead of GetInt

11 / 78

Page 12: Style & Design Principles 01 - Code Style & Structure

Namespace Names

<Company>.<Product>.<Feature>.<SubNamespace>

• Plural names where appropriate• Example: System.Collections

• Don’t use the same name for namespace and type

• Don’t use common names such as Element, Component

12 / 78

Page 13: Style & Design Principles 01 - Code Style & Structure

Type Names

• Nouns for classes and structs• Example: List, Vector

• Derived classes can end with name of base class• Example: ArgumentException

• Adjectives for interfaces

• Prefix interface names with ‘I’• Example: IComparable

• Use descriptive names for type-parameters• Dictionary<TKey, TValue> instead of Dictionary<K, V>

• Singular names for non-flags enums• Color instead of Colors

13 / 78

Page 14: Style & Design Principles 01 - Code Style & Structure

Member Names

• Verbs for methods and events• Example: AddComponent, ComponentAdded

• Nouns or adjectives for fields• Example: Duration, Invulnerable

• Nouns for properties

• Plurals for collections• Items instead of ItemList

14 / 78

Page 15: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #1

• Be positive!• Enabled = true instead of Disabled = false

• CaseSensitive = true instead of CaseInsensitive = false

15 / 78

Page 16: Style & Design Principles 01 - Code Style & Structure

Tabs vs. Spaces

• Holy war between two fractions of programmers

• Some are for tabs…• Seperation of visual representation from data

• Customizable

• Faster

• Specifically meant for indentation

• … while others are for spaces.• Always one column

• Supported by IDEs anyway

16 / 78

Page 17: Style & Design Principles 01 - Code Style & Structure

Tabs vs. Spaces

• Most important rule:

Stay consistent.

• … or it might even blow up your version control.

17 / 78

Page 18: Style & Design Principles 01 - Code Style & Structure

Tabs vs. Spaces

„That said, only a moron would use tabs to format their code.”

- Jeff Atwood

18 / 78

Page 19: Style & Design Principles 01 - Code Style & Structure

Tools – StyleCop

• Analyzes C# source code to enforce a set of style and consistency rules

• Helps developers avoid common pitfalls and mistakes

• Settings file can be checked in to version control

19 / 78

Page 20: Style & Design Principles 01 - Code Style & Structure

Tools – StyleCop

StyleCop Settings Dialog in Visual Studio 2012 20 / 78

Page 21: Style & Design Principles 01 - Code Style & Structure

Tools – StyleCop

Part of a StyleCop Settings File

<StyleCopSettings Version="105"><GlobalSettings><StringProperty Name="MergeSettingsFiles">NoMerge</StringProperty><CollectionProperty Name="RecognizedWords">

<Value>Bresenham</Value><Value>Dijkstra</Value><Value>Endre</Value>

<Value>Fredman</Value><Value>multigraph</Value>

<Value>Stee</Value><Value>Tarjan</Value><Value>Tarjan's</Value>

<Value>unweighted</Value></CollectionProperty></GlobalSettings><Analyzers><Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">

<Rules><Rule Name="DocumentationTextMustContainWhitespace">

<RuleSettings><BooleanProperty Name="Enabled">False</BooleanProperty>

</RuleSettings></Rule><Rule Name="ConstructorSummaryDocumentationMustBeginWithStandardText">

<RuleSettings><BooleanProperty Name="Enabled">False</BooleanProperty>

</RuleSettings></Rule>

21 / 78

Page 22: Style & Design Principles 01 - Code Style & Structure

Tools – StyleCop

StyleCop Warnings in Visual Studio 2012 22 / 78

Page 23: Style & Design Principles 01 - Code Style & Structure

Tools – Resharper

• Static code analysis

• Many, many shortcuts and quick fixes

• Improved refactoring

• Improved search features

• Code templates

23 / 78

Page 24: Style & Design Principles 01 - Code Style & Structure

Tools – Resharper

R# Static Code Analysis in Visual Studio 2012

24 / 78

Page 25: Style & Design Principles 01 - Code Style & Structure

Tools – Resharper

R# Suggestions in Visual Studio 2012

25 / 78

Page 26: Style & Design Principles 01 - Code Style & Structure

Tools – Resharper

R# Suggestions in Visual Studio 2012

26 / 78

Page 27: Style & Design Principles 01 - Code Style & Structure

Tools – Resharper

R# Suggestions in Visual Studio 2012

27 / 78

Page 28: Style & Design Principles 01 - Code Style & Structure

Tools – Eclipse

Eclipse Java Code Style Clean Up Settings

28 / 78

Page 29: Style & Design Principles 01 - Code Style & Structure

Tools – Eclipse

Eclipse Java Code Style Clean Up Settings

29 / 78

Page 30: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Struct

Make a type a struct instead of a class if it…

• Logically represents a single value,

• Has a valid state if all data is set to zero,

• Has an instance size < 16 bytes,

• Is Immutable, and

• Won’t have to be boxed frequently

30 / 78

Page 31: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Struct

Make a type a struct instead of a class if it…

• Logically represents a single value,

• Has a valid state if all data is set to zero,• This is the case for array initialization, for example.

• Has an instance size < 16 bytes,

• Is Immutable, and

• Won’t have to be boxed frequently

31 / 78

Page 32: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Struct

Make a type a struct instead of a class if it…

• Logically represents a single value,

• Has a valid state if all data is set to zero,

• Has an instance size < 16 bytes,• Value type assignments copy all values

• Is Immutable, and

• Won’t have to be boxed frequently

32 / 78

Page 33: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Struct

Make a type a struct instead of a class if it…

• Logically represents a single value,

• Has a valid state if all data is set to zero,

• Has an instance size < 16 bytes,

• Is Immutable, and• Passing (and returning) by value implicitly creates a copy

• Value types that can be changed will be confusing!

• Won’t have to be boxed frequently

33 / 78

Page 34: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Struct

Make a type a struct instead of a class if it…

• Logically represents a single value,

• Has a valid state if all data is set to zero,

• Has an instance size < 16 bytes,

• Is Immutable, and

• Won’t have to be boxed frequently• Happens when they’re cast to a interface

• Allocated on heap and garbage collected, then!

34 / 78

Page 35: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Interface

• Use interfaces for polymorphic value type hierarchies• Example: IComparable, IConvertible

• If an interface does more than exactly one thing, that’s a warning sign.

35 / 78

Page 36: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Interface

36 / 78

Page 37: Style & Design Principles 01 - Code Style & Structure

Type Design – Class vs. Interface

• Favor (abstract) classes over interfaces• Adding members to an interface is a breaking change!

• Seperating of contract from implementation with an interface is a myth…

• … whereas doing so with an abstract class is not.

37 / 78

Page 38: Style & Design Principles 01 - Code Style & Structure

Type Design – Enums

• Favor enums over static constants

• Provide a zero value for simple enums (e.g. None)

• Don’t use enums for open sets

• Don’t use flag enums if some combinations can be invalid

38 / 78

Page 39: Style & Design Principles 01 - Code Style & Structure

Member Design –Property vs. MethodMake a member a method instead of a property if it…

• Is significantly slower than a field access would be,

• Is a conversion operation (such as ToString),

• Returns a different result each time it is called,

• Has an observable side effect,

• Returns a copy of an internal state, or

• Returns an array

39 / 78

Page 40: Style & Design Principles 01 - Code Style & Structure

Member Design – Properties

• Preserve previous value if a property setter throws an exception

• Don’t throw exceptions from property getters.• Use a method in that case.

40 / 78

Page 41: Style & Design Principles 01 - Code Style & Structure

Gotcha!

Don‘t throw exceptions from

static constructors!

41 / 78

Page 42: Style & Design Principles 01 - Code Style & Structure

Member Design – Methods

• Shorter overloads should simply call longer ones• public int IndexOf(string s)

• public int IndexOf(string s, int startIndex)

• public int IndexOf(string s, int startIndex, int count)

• Use descriptive parameter names

• Avoid varying names or inconsistent ordering

• Make only the longest overload virtual

• Allow null to be passed for optional parameters• Default arguments are not CLS-compliant!

42 / 78

Page 43: Style & Design Principles 01 - Code Style & Structure

Member Design – Extensions

Use an extension method, if ...

• It adds functionality relevant to everyimplementation of an interface, or

• An instance method would introduce unwanteddependencies

43 / 78

Page 44: Style & Design Principles 01 - Code Style & Structure

Member Design –Operator Overloads• Make sense for types that feel like primitive types

• Should be defined symmetrically

• Provide methods with friendly names, as well• Some languages don‘t support operator overloads.

44 / 78

Page 45: Style & Design Principles 01 - Code Style & Structure

Member Design –Parameters• Use the least derived required paramter type

• Validate all arguments

• params keyword is useful for arbitrary (but small) numbers of parameters• Pay attention on parameter order

• Be aware that null is a valid params array argument

45 / 78

Page 46: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #2

Guess what this code means?

widget.repaint(false);

46 / 78

Page 47: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #2

Guess what this code means?

widget.repaint(false);

• Function argument is called immediate• true means immediate painting

• false means deferred painting

• Better use method overloads or enums!

47 / 78

Page 48: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #3

Guess what this code means?

var opacitySlider = new Slider(true);

48 / 78

Page 49: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #3

Guess what this code means?

var opacitySlider = new Slider(true);

• Function argument is called horizontal• true means horizontal slider

• false means vertical slider

• Better use subclasses!• „Heck, who knows someday you’ll need a diagonal

slider!”

49 / 78

Page 50: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #4

Guess what this code means?

stackView.updateHeight(false);

50 / 78

Page 51: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #4

Guess what this code means?

stackView.updateHeight(false);

• Immediate or not?

• Don‘t update height?

• Update width???

51 / 78

Page 52: Style & Design Principles 01 - Code Style & Structure

Boolean Trap #5

The more, the merrier!

event.initKeyEvent("keypress", true, true, null, null, false, false, false, false, 9, 0);

52 / 78

Page 53: Style & Design Principles 01 - Code Style & Structure

Exceptions

• Help you deal with any unexpected or exceptional situations that occur when a program is running

• Exceptions are types that all ultimately derive from System.Exception.

• Generated by the common language runtime (CLR), by the .NET Framework or any third-party libraries, or by application code.

53 / 78

Page 54: Style & Design Principles 01 - Code Style & Structure

Benefits of Exceptions

• Integrate well with object-oriented languages• Does not require changing the method signature

• Can’t be ignored, whereas error codes can

• Exception objects contain detailed information about the error, such as the state of the call stack and a text description of the error.

• Possibility of defining an Unhandled Exception Filter (UEF)

• Supported by debuggers

54 / 78

Page 55: Style & Design Principles 01 - Code Style & Structure

Gotcha!

Don’t return error codes!

55 / 78

Page 56: Style & Design Principles 01 - Code Style & Structure

Exception Design

• Exceptions provide consistent error reporting• No bool return value required

• No HRESULT

• No GetLastError

• Don’t return error codes.• If your error code is for the developer, add additional

information to the exception message instead.

• If your error code is for the exception handler, add a new exception type instead.

56 / 78

Page 57: Style & Design Principles 01 - Code Style & Structure

Throwing Exceptions

• Throw the most specific exception that makes sense.• ArgumentException

• ArgumentNullException

• Provide rich and meaningful error messages.

• Introduce a new exception type only if it should be handled differently than existing exception types.

57 / 78

Page 58: Style & Design Principles 01 - Code Style & Structure

Handling Exceptions

• Use a try block around the statements that might throw exceptions.

• Once an exception occurs in the try block, the flow of control jumps to the first associated exception handler that is present anywhere in the call stack.

• If no exception handler for a given exception is present, the program stops executing with an error message.

58 / 78

Page 59: Style & Design Principles 01 - Code Style & Structure

Handling Exceptions

Unhandled exception reported by Microsoft Visual Studio 2012

59 / 78

Page 60: Style & Design Principles 01 - Code Style & Structure

Exception Best Practice

60 / 78

Page 61: Style & Design Principles 01 - Code Style & Structure

Exception Best Practice

• Do not catch an exception unless you can handle it and leave the application in a known state.

• Do not catch non-specific exceptions, such as System.Exception.

• Use a finally block to release resources, for example to close any streams or files that were opened in the try block.

61 / 78

Page 62: Style & Design Principles 01 - Code Style & Structure

Gotcha!

Never use empty catch blocks!

62 / 78

Page 63: Style & Design Principles 01 - Code Style & Structure

Common Exceptions

• Thrown by your application or the framework• InvalidOperationException

• ArgumentException

• ArgumentNullException

• ArgumentOutOfRangeException

• Thrown by the CLR• NullReferenceException

• IndexOfOutRangeException

• StackOverflowException

• OutOfMemoryException

63 / 78

Page 64: Style & Design Principles 01 - Code Style & Structure

Collection Design

• Inherit from Collection<T>, ReadOnlyCollection<T> or KeyedCollection<TKey, TItem>

• Implement IEnumerable<T>• Allows foreach iteration of your collection.

• Implement ICollection<T> or IList<T> where it makes sense

• Implement an indexer where it makes sense

64 / 78

Page 65: Style & Design Principles 01 - Code Style & Structure

Gotcha!

Don’t implement ICloneable!

65 / 78

Page 66: Style & Design Principles 01 - Code Style & Structure

The interface ICloneable

• Contract doesn’t define whether cloning an object returns a deep or shallow copy

• Define your own Clone method if required, without implementing the interface

66 / 78

Page 67: Style & Design Principles 01 - Code Style & Structure

Hint

Implement IEquatable<T>

on value types!

67 / 78

Page 68: Style & Design Principles 01 - Code Style & Structure

The interface IEquatable

• Defines a method for determining equality of object instances

• Implement on value types to prevent boxing

• Override Object.Equals, == and != operators as well

68 / 78

Page 69: Style & Design Principles 01 - Code Style & Structure

Hint

Implement IComparable<T>

where it makes sense!

69 / 78

Page 70: Style & Design Principles 01 - Code Style & Structure

The interface IComparable

• Defines a type-specific comparison method for ordering or sorting type instances.

• Override <, >, <= and >= operators as well

70 / 78

Page 71: Style & Design Principles 01 - Code Style & Structure

Equals, GetHashCode &ToString• If Object.Equals returns true for any two objects, GetHashCode must return the same value for these objects.• Dictionaries, which are implemented as Hashtables in

.NET, will place two equal objects in different buckets otherwise, and lookup might fail in that case.

• Override ToString wherever it makes sense.• Provides more useful debug output.

71 / 78

Page 72: Style & Design Principles 01 - Code Style & Structure

Gotcha!

GetHashCode must return the exactly same value across the

lifetime of an object!

72 / 78

Page 73: Style & Design Principles 01 - Code Style & Structure

Assignment #1

1. Field Declaration

What’s wrong with the following declaration for the count of items in a collection?

private int m_itemcnt;

73 / 78

Page 74: Style & Design Principles 01 - Code Style & Structure

Assignment #1

2. Vector Type

Implement a type for a two-dimensional vector with integer coordinates!

74 / 78

Page 75: Style & Design Principles 01 - Code Style & Structure

Assignment #1

3. Direction Type

Implement a type for cardinal directions!

75 / 78

Page 76: Style & Design Principles 01 - Code Style & Structure

Assignment #1

4. Grid Type

1. Implement a type for a generic two-dimensional grid!

2. Add support for iteration, indexing and copying!

3. Allow comparison of grids by comparing all of their entries!

76 / 78

Page 77: Style & Design Principles 01 - Code Style & Structure

References

• Stack Overflow. What does a good programmer's code look like? http://stackoverflow.com/questions/366588/what-does-a-good-programmers-code-look-like, March 2015.

• Cwalina, Abrams. Framework Design Guidelines. 2nd Edition. Addison-Wesley, 2011.

• Hidayat. hall of api shame: boolean trap. http://ariya.ofilabs.com/2011/08/hall-of-api-shame-boolean-trap.html, August 24, 2011.

• Atwood. Death to the Space Infidels!http://www.codinghorror.com/blog/2009/04/death-to-the-space-infidels.html, April 13, 2009.

• MSDN. System Namespace. http://msdn.microsoft.com/en-us/library/System%28v=vs.110%29.aspx, March 2015.

77 / 78

Page 78: Style & Design Principles 01 - Code Style & Structure

Thank you for your attention!

Contact

Mail

[email protected]

Blog

http://www.npruehs.de

Twitter

@npruehs

Github

https://github.com/npruehs

78 / 78