Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Tuesday, August 25, 2015

What is a class?

Holds state (properties or fields)
Has behaviour (methods)

What is a closure?

“A closure is a block of code which can be executed at a later time, but which maintains the environment in which it was first created ie it can still use the local variables of the method which created it, even after that method has finished executing”
http://stackoverflow.com/questions/428617/what-are-closures-in-net

Closing over something that may go out of scope

// Action is a delegate which doesn't return a value Action action = CreateAction(); //Here we can see that the action returned by CreateAction still has access to the counter variable, //and can indeed increment it, even though CreateAction itself has finished. action(); action(); } static Action CreateAction() { int counter = 0; Action a = delegate { counter++; Console.WriteLine("counter={0}", counter); }; return a; }

 

A Function:

// setting up state of function Func<int, int> fn2 = GetMultiplier(2); //var fn3 = GetMultiplier(3); Console.WriteLine(fn2(2)); //outputs 4 Console.WriteLine(fn2(3)); //outputs 6 //Console.WriteLine(fn3(2)); //outputs 6 //Console.WriteLine(fn3(3)); //outputs 9 } static Func<int, int> GetMultiplier(int a) { int multiplier = a; Func<int, int> multiplierFunction = delegate(int b) { return multiplier * b; }; return multiplierFunction; }


and again:

Action a = GiveMeAction(); a(); // i = 1 a(); // i = 2 a(); } static Action GiveMeAction() { int i = 0; Action a = delegate { i++; }; // Returning a method/function which captures the i scope (closure) return a; }
https://www.youtube.com/watch?v=gBO_4BMbsO8

asdf

// A delegate that accepts a string and returns a string Func<string, string> myFunc = delegate (string var1) { return "some value"; }; string myVar = myFunc("something"); Console.Out.WriteLine($"myVar is {myVar}");

When to use closures?

LINQ is built using clousures

  • Simplify interfaces
  • Delayed execution
| | # 
# Friday, August 21, 2015
( Chrome | Git | Notepad++ | SSMS )

Show bookmarks in Chrome – Ctrl Shift B

Delete line SSMS – Shift Delete

Notepad++ in shell (npp) - http://superuser.com/a/802913/12214

Git difftool setup
cd ~ 
which is c:\Users\Dave\.gitconfig

[diff]
    tool = vsdiffmerge
[difftool]
      prompt = false
[difftool "vsdiffmerge"]
      cmd = '"C:/Program Files (x86)/Microsoft Visual Studio 14.0/Common7/IDE/vsdiffmerge.exe"' "$LOCAL" "$REMOTE" //t
      keepbackup = false
      trustexitcode = true
[merge]
      tool = vsdiffmerge
[mergetool]
      prompt = false
[mergetool "vsdiffmerge"]
      cmd = '"C:/Program Files (x86)/Microsoft Visual Studio 14.0/Common7/IDE/vsdiffmerge.exe"' "$REMOTE" "$LOCAL" "$BASE" "$MERGED" //m
      keepbackup = false
      trustexitcode = true

| | # 
# Sunday, August 16, 2015
( C#6 | Functional )

http://mikehadlow.blogspot.co.uk/2015/08/c-program-entirely-with-static-methods.html

and my fork: https://github.com/djhmateer/FunctionalDemo

"More concise and easier to test"

"Gone are interfaces and instance classes to be replaced by static methods, higher-order functions and closures"

Procedural –> Object-Oriented –> Functional

OO code .. "is typical of much well-constructed C# code that you will find in the wild"

OO Example

Why is composition root a static class?
Put properties below the ctor?
Why class properties and not a class field?
Why Console.Out.Writeline and not Console.WriteLine.. no real difference
RunCustomerReportBatch – interesting how to test this method, when it returns void, so have to test it’s dependencies’ results (the mocks)

public Report CreateCustomerReport(Customer customer) { // C#6 string interpolation var body = $"This is the report for {customer.Email}!"; return new Report(customer.Email, body); }

So this is exciting – new C#6 features.  Stable release of C#6 was on 20th July 2015 as part of .NET4.6. 

image
However I’m targeting 4.5.2, and not 4.6 (which is installed).  In fact it works targeting 4.5

C#6 requires the new Roslyn compiler http://stackoverflow.com/a/28921749/26086  but the compiler can target older versions of the framework for some features eg string interpolation as it results in a call to String.Format.

image

Functional Example

private static void Main() { // Action is a delegate. Doesn't return a value Action runProcessing = () => RunProcessing(Log); runProcessing(); } public static void RunProcessing(Action<string> log) { log("test"); } public static void Log(string message) { Console.WriteLine("log: {0}", message); }

Composing, then running a method which has a dependency.

 

Notes:

http://www.programgood.net/2014/10/24/70483FunQuestions.aspx going through Action and Func

http://www.pluralsight.com/courses/csharp-fundamentals-2
Functional bit

| | # 
# Thursday, July 30, 2015

Make the code better?  Or write tests to understand problem, and rewrite the code.

  • Enterprise environment in mind
  • Simplicity is key
  • Code will last for many many years
  • High churn rate of overseas developers
  • Favour pragmatism
  • Favour delivery of code

https://github.com/NotMyself/GildedRose

Solution builds in VS2013, single test runs fine with xunit and R# test runner.  Got under git source control

The Problem

  • All items have a SellIn value which denotes the number of days we have to sell the item
  • All items have a Quality value which denotes how valuable the item is
  • At the end of each day our system lowers both values for every item

    Strategy

  • Built tests, and refactored as much simple stuff as possible with tools

    Core method is UpdateItemQuality (which I'd like to break apart using CQS ie a command or query, however this kata is about the logic)

    Problem with UpdateItemQuality

    Lots of nested if's... tricky to understand all the logic.

    Try breaking apart core method into

    • Dexterity (normal)
    • AgedBrie (gets better with time)
    • Sulfuras
    • BackStagePasses

    Will it work putting each bit of logic in a separate method?  Yes it did work quite well.

    public Item UpdateItemQuality(Item item) { if (item.Name == "+5 Dexterity Vest") item = UpdateItemAsDexterity(item); if (item.Name == "Aged Brie") item = UpdateItemAsAgedBrie(item); if (item.Name == "Sulfuras, Hand of Ragnaros") item = UpdateItemAsSulfuras(item); if (item.Name == "Backstage passes to a TAFKAL80ETC concert") item = UpdateItemAsBackStage(item); if (item.Name == "Conjured Item") item = UpdateItemAsConjured(item); return item; } private Item UpdateItemAsDexterity(Item item) { item.SellIn -= 1; if (item.SellIn > 0) item.Quality -= 1; else item.Quality -= 2; if (item.Quality < 0) item.Quality = 0; return item; }

    Enums for item names?  Curly brackets would usually use in if's.

    Google around for other ideas

    | | # 
    # Tuesday, July 28, 2015

    https://github.com/emilybache/GildedRose-Refactoring-Kata

    https://github.com/NotMyself/GildedRose

    Going through a refactoring to see how Steve does it.

    namespace GildedRose.Console { class Program { // not allowed to mess with this private field... camel case? IList<Item> Items; static void Main(string[] args) {

    R# highlights: namespace issues, field camelCase, and args not being used..

    Extract to a ServiceClass

    var service = new ItemQualityService(); service.UpdateQuality(app.Items);

    He pulled out to a new file very quickly, and checked in.
    namespace GildedRose.Console { public class ItemQualityService { public void UpdateQuality(IList<Item> Items)

    foreach loop extracting out

    public class ItemQualityService { public void UpdateQuality(IList<Item> Items){ foreach (Item item in Items){ UpdateQuality(item); } } private void UpdateQuality(Item item){

    there was loads of stuff inside.  Now extracted out.

    Adding tests

    install-package fluentassertions

    public class ItemQualityService_UpodateItemQualityShould { [Fact] public void ReduceNormalItemQualityByOne() { var qualityService = new ItemQualityService(); var normalItem = new Item{Name = "+5 Dexterity Vest", SellIn = 10, Quality = 20}; qualityService.UpdateItemQuality(normalItem); normalItem.Quality.Should().Be(19); } }

    Great to get the code under source control!

    Extract static Method

    var normalItem = GetNormalItem();

    Ctrl Shift R - R#
    private static Item GetNormalItem(int sellIn = DEFAULT_STARTING_SELLIN, int quality = DEFAULT_STARTING_QUALITY) { return new Item { Name = "+5 Dexterity Vest", SellIn = sellIn, Quality = quality }; }

    Extract Field

    public class ItemQualityService_UpdateItemQualityShould { // newing up in a field private ItemQualityService itemQualityService = new ItemQualityService();

    Instead of a ctor.

    Magic Numbers

    [Fact] public void ReduceNormalItemSeelInByOne() { var qualityService = itemQualityService; var normalItem = GetNormalItem(); int startingSellIn = normalItem.SellIn; qualityService.UpdateItemQuality(normalItem); normalItem.SellIn.Should().Be(startingSellIn-1); }

    Simple way of not having .Be(19) in the test

    Constants

    private const int SYSTEM_MAX_QUALITY = 50; private const int DEFAULT_STARTING_SELLIN = 10; private const int DEFAULT_STARTING_QUALITY = 20;

    SystemMaxQuality is recommended naming convention

    Behaviour into StoreItem

    // not allowed to touch this public class Item { public string Name { get; set; } public int SellIn { get; set; } public int Quality { get; set; } }

    As part of the spec is not to touch this class, we're going to create a wrapper for it.
    public class StoreItem { private readonly Item _item; public StoreItem() { } public StoreItem(Item item) { this._item = item; } public string Name { get { return _item.Name; } set { _item.Name = value; } } public int SellIn { get { return _item.SellIn; } set { _item.SellIn = value; } } public int Quality { get { return _item.Quality; } set { _item.Quality = value; } } }

    StoreItem wraps Item, or delegates to it.  Can work with StoreItems now instead.  Putting the UpdateQuality method on StoreItem
    private static StoreItem GetNormalItem(int sellIn = DEFAULT_STARTING_SELLIN, int quality = DEFAULT_STARTING_QUALITY) { return new StoreItem( new Item { Name = "+5 Dexterity Vest", SellIn = sellIn, Quality = quality } ); }

    then a test:

    Long Method Smell, Conditional Complexity Smell

    public void UpdateQuality() { if (this.Name != "Aged Brie" && this.Name != "Backstage passes to a TAFKAL80ETC concert") { if (this.Quality > 0) { if (this.Name != "Sulfuras, Hand of Ragnaros") { this.Quality = this.Quality - 1; } } } else { if (this.Quality < 50) { this.Quality = this.Quality + 1; if (this.Name == "Backstage passes to a TAFKAL80ETC concert") { if (this.SellIn < 11) { if (this.Quality < 50) { this.Quality = this.Quality + 1; } } if (this.SellIn < 6) { if (this.Quality < 50) { this.Quality = this.Quality + 1; } } } } } if (this.Name != "Sulfuras, Hand of Ragnaros") { this.SellIn = this.SellIn - 1; } if (this.SellIn < 0) { if (this.Name != "Aged Brie") { if (this.Name != "Backstage passes to a TAFKAL80ETC concert") { if (this.Quality > 0) { if (this.Name != "Sulfuras, Hand of Ragnaros") { this.Quality = this.Quality - 1; } } } else { this.Quality = this.Quality - this.Quality; } } else { if (this.Quality < 50) { this.Quality = this.Quality + 1; } } } }

    Plan is to head towards UpdateQuality be a delegating method to different Strategies.

    image

    Summary

    After exploring the code, and where it went:

    • Didn't like the complexity
      • Didn't like the number of UpdateQuality methods everywhere
      • Didn't like passing this (StoreItem) into a Strategy..
    • Liked the tests
    | | # 
    # Monday, July 27, 2015

    example - a big long aspx page which does lots in the save_Click code behind

    •      Do guarding UI stuff in code behind
    •      Call Service
    •      Update UI based on strongly typed return ie IsSuccessful, and ResultMessage

    image

    public partial class ApproveProposal2 : BasePage { // Initialisaing the field at declaration private ArticleProposalApprovalService _approvalService = new ArticleProposalApprovalService(); private void save_Click(object sender, System.EventArgs e) { if (dueDate.Text.Length < 1) { this.errorMessage.Text = "Please enter a due date."; this.errorMessage.Visible = true; return; } var result = _approvalService.Save(articleProposalId, dueDate.Text, sendEmail.Checked); if (result.IsSuccessful) { this.articleProposalInfo.Refresh(); this.errorMessage.Text = "Proposal due date processed."; this.dueDate.Enabled = false; this.save.Enabled = false; } else { this.errorMessage.Text = result.ResultMessage; } this.errorMessage.Visible = true; } } public class ArticleProposalApprovalService { private AuthorNotificationService _authorNotificationService = new AuthorNotificationService(); public ArticleProposalSaveResult Save(int articleProposalId, string dueDate, bool shouldSendEmail) { var result = new ArticleProposalSaveResult(); try { ArticleProposal proposal = new ArticleProposal(articleProposalId); if (proposal.ProposalText.Length < 1) { result.ResultMessage = "Proposal not found."; return result; } User user = new User(proposal.AuthorId); if (user == null) { result.ResultMessage = "Author " + proposal.AuthorId.ToString() + " not found"; return result; } proposal.DueDate = Convert.ToDateTime(dueDate); if (shouldSendEmail) { _authorNotificationService.NotifyAuthorProposalAccepted(user, proposal); } proposal.Save(); result.IsSuccessful = true; return result; } catch (Exception ex) { WriteError("approveProposal.asax.cs::next_Click : " + ex.ToString()); result.ResultMessage = "An exception occured while saving your information. Please try again later."; return result; } }

    Lots of code.  It is better than the original though!

    | | # 
    # Friday, July 24, 2015

    "Like cleaning your room.. good to do often"

    Like editing.. first draft, to final version

    Over time software rots.. incurs Technical Debt

    • Duplication
    • Excess coupling
    • Quick fixes
    • Hacks

    Why Refactor

    • Improves design
    • Improves readability
    • Removes defects
    • ... so helps you program faster (as we'll keep on making changes to the system)

    When Refactor

    PDD - Pain Driven Development!

    Part of code reviews

    The Refactoring Process

    • Check in code into source control
    • Verify existing behaviour
    • In no unit tests, write charaterisation tests..
      • ie write a test you know will fail
    • Refactor

    Tips

    • Small steps
    • Check in often

    Simple Refactorings

    0.5) Code cleanup eg Ctrl K D to format, Removed Unused usings, remove redundant qualifiers (greyed out in R#), remove dead code

    Refactor towards testable code

    1.Parameters - make clearer

    2.Magic numbers - eg a constant, or a field, Enums??

    Organising Code Smells

    • The Bloaters
    • The OO Abusers
    • The Change Preventers
    • The Dispensers
    • The Couplers
    • The Obfuscators
    • Environment Smells
    • Test Smells

    The Bloaters

    • The Long Method.. prefer short methods...1 screen (actually Steve McConnell that up to 100 lines is easier to develop) .  > LOC is just an indicator that maybe the function is doing too much
    • Long / Nested loops
      • make easier to understand by extracting to another method

    3.Extract methods / into a Service class - make it easier to test.  Not necessarily smaller methods

    4.Stuff in right abstraction level.. eg data access, business logic.. caching..

    5. Primitive obsession eg use ints, strings.  Use objects to help. eg DrawLine(1,2,3,4,5), DrawLine(startPoint, endPoint, colour).  Email type, FileType (rather than strings)

    6. Long parameter lists into a method... why not pass in an object

    Obfuscators

    7.Regions - don't use?

    8.Comments..untrustworthy..should be used to say Why.. not What or How.  Hanselman wants context.. links to instructions from code.. ie wiki.. why.. or links to github issues.  Why.. if this is bad, why??

    9.Poor names eg GeneratePrimeFactorsOf.. not encodings ie bnThing.. suffix it.  UserNameTextBox, UserNameLabel

    | | # 
    # Tuesday, July 14, 2015
    ( SOLID )

    http://bit.ly/coffeeheuristics

    Pretty good fit for the Observer pattern

    IObserver<T> is part of the framework, but no implementations.  They are in ReativeExtensions

    SRP as only has 1 reason to change - ie should just react to WarmerPlateStatus values.. ie it just sets the WarmerPlate to a different state.

    Dependency Inversion Principle - injecting in.. doesn't depend on details

    Very easy to test

    Use Rx to poll every second:

    • GetBrewButtonStatus
    • GetBoilderStatus
    • GetWarmerPlaceStatus
    | | # 
    # Friday, July 10, 2015
    ( SOLID )

    Why write better code?

    • Long term productivity
    • Maintainability

    Make clearer code

    Make it obvious what a method does ie name, return type, Command/Query

    CQS - Command Query Separation

    If follow CQS can trust the codebase / easier to reason about the code without fully understanding the implementation details.

    Commands - has side effects eg Write file to disk.  Returns void.
    Query - returns data (safe to invoke... does not affect anything...so can have confidence to use)

    Fail fast and give good exception messages

    Nullable References are Evil

    Value types eg ints, decimals, bools are non-nullable by default

    Ref types eg Classes are nullable.

    • Never return null.. if need the concept of a value not being present then
      • Read returns a Maybe of string.. invalid states are impossible
    // Return value may be there, and may not be // and don't want to return null as it is tainted // want a collection of 0 or 1 strings // IEnumerable<string> is too wide as it could have 10 elements // Maybe<T> can return 0 of 1 <T> public Maybe<string> Read(int id) { var path = this.GetFileName(id); if (!File.Exists(path)) return new Maybe<string>(); var message = File.ReadAllText(path); return new Maybe<string>(message); } public void Tester() { // this method may, or may not return a string Maybe<string> thing = Read(49); var message = thing.DefaultIfEmpty("").Single(); }

    SOLID

    Productive, Maintainable, through decomposition

    • Single Responsibility (SRP)
    • Open Closed (OCP)
    • Liskov Substitution (LSP)
    • Interface Segregation (ISP)
    • Dependency Inversion (DIP)

    Single Responsibility Principle

    • A class should have only 1 reason to change  (do 1 thing and do it well)
    • Separation of concerns eg caching/logging

    Interface Segregation Principle

    Favour Role Interfaces - defines very few members.. even 1

    over Header Interfaces - extracted..essentially all the methods.. big interfaces

    Dependency Inversion

    Favour composition over inheritence

    Decorator (Russian Doll)

    | | # 
    # Thursday, July 09, 2015
    ( SOLID )

    Cross cutting concerns - Logging, Caching... can be factored away with decorators

    Business logic left in the class

    Solid is a reaction to design smells

    rigidity

    solid is supple, allowing us to change in direction and requirements as we go along

    Code Review

    Faced with a codebase I still don't understand, my strategy is:

    • Get it compiling!
    • Run unit tests
    • Make new unit tests to step through code
    • Make a diagram of how it all works
    • Start a new project, and just rip out the simplest section (Saving) to understand pattern
    • Explore different parts of code eg SpySink for testing how logging works
    | | #