Learning to Live with the Static Typing Fascist and the ... - James Crisp

bricklayerbelchedInternet and Web Development

Feb 5, 2013 (4 years and 6 months ago)

106 views

James Crisp and Jim Webber,
ThoughtWorks

ARC310

Platform

Code affordances

Tool support

Extensibility

Development Process

Data access

Metaprogramming

Application development

Integration

Windows!

.Net 3.5


Maybe Linux, via Mono

Anywhere

Windows

Linux

Mac

CLR

JVM

How concise and readable is the

code?

How much code will I have to maintain?

How productive can I be?


class Person


attr :id


attr_accessor :name, :age

end

p = Person.new(



:first_name => "Freddy",



:last_name => "Flintoff")


p.update(:age => 72, :sex=>'m')


class Person

{


public string FirstName


{


get; set;


}

...

Person p = new Person {


LastName = "Dundee",


FirstName = "Mick" };

class DomainObject


def initialize(attributes = {})


attributes.each do |name, value|


eval("@#{name} = value")


end


end

end


h = House.new( number => 20 )

p = Phone.new( number => 123456 )


p = h


p.number


>> 20


var p = new Person {


LastName = "Smith"};

interface INumbered

{


int Number { get; }

}


class House : INumbered ...

class Phone : INumbered ...


INumbered phone;

INumbered house = new House();

phone = house;

phone.Number




LINQ and Entity Framework

Castle project

Active record for .Net

Builds on NHibernate

NHibernate too!


PersonDataContext pdc = new


PersonDataContext();

pdc.CreateDatabase();


var adults = from p in pdc.Persons


where p.Age > 18


select p;


foreach (Person adult in adults)

{


Console.WriteLine(adult.FirstName + " " +


adult.LastName);

}

Active Record ships with Rails

Good for green field web apps

Objects and properties mapped 1:1 to tables
and columns

Simple API for searching and saving


Can use underlying platform


eg, Hibernate
or NHibernate

What are Lambda functions?


From the functional programming
community

Who?


Think: anonymous inline methods

C# 2.0 anonymous delegates with nicer syntax

List<Person> people =


new List<Person>();

people.Add(new Person {


FirstName = "James",


LastName = "Crisp", Age = 8 });


people.Add(new Person {


FirstName = "Jim",


LastName = "Webber", Age = 32 });


people.ForEach(p =>


Console.WriteLine(p.FirstName + " " +


p.LastName));



codgers = people.find {|p| p.age > 30}


codgers.each {|c| print c.name }








Method Missing


DSLs


Code generation at run time


If a method is not defined, falls through to
‘method_missing’.


ActiveRecord (part of Rails) uses this to
“generate” properties on domain objects at
run time.


Allows DSLs like :

Person.find_by_name_and_age('Jim', 84)


Create new properties, methods and
classes on the fly


Redefine, wrap and rename methods



Eval() a string, and it will be code


class Geek < ActiveRecord::Base


has_many :laptops


has_one :girlfriend

end


jim = Geek.new(:name => 'Jim' )

laptop = Laptop.new(:brand=> 'dell')

jim.laptops << laptop




describe Geek do


before(:each) do


@geek = Geek.new


end



it "should have no laptops initially" do


@geek.laptops.count.should == 0


end



....



Can generate useful code from metadata at
compile time

E.g. Domain objects from database schemas

E.g. Service proxies from WSDL

Etc

Attributes for metaprogramming

And the reflection APIs if I have to...


Some support for fluent interfaces

in NUnit etc

Assert.That(...);

Assert.IsNotNull(...);


Can create our own DSLs by using cunning
class name conventions

E.g. nBehave for BDD

Like TDD but focussed on behaviour rather than
implementation

override public void Specify()

{


Given(new RubyProgrammer()).


When(new BuildingProperSoftware()).


Then(new


RubyProgrammerShouldBeFired());

}

Tooling available to turn this
code into development
stories for
xBehave

All classes are open and can be

extended

Eg, Rails extends Ruby's number class:


>> 5.days.from_now


=> Sun Aug 05 14:28:12 +1000 2007


Existing methods can be removed, wrapped
or renamed


Frameworks often designed around re
-
usable Mixins rather than inheritance

class String


def url?


self.starts_with? "http://"


end

end


>> "hi".url?

=> false

>> "http://jamescrisp.org".url?

=> true


We’ve always had interfaces and

abstract classes from the underlying .Net
framework

Now we have extension methods too...

namespace JimWebber

{


public static class WebUriValidator


{


public static bool


IsValidUri(this string str)


{


return


str.ToLower().StartsWith("http");


}


}

}

using JimWebber;

class Program

{


static void Main(string[] args)


{


string s ="http://jim.webber.name";


bool b = s.IsValidUri();


}

}

Unit Testing

TDD


NUnit

BDD


nBehave

nMock


Interfaces easy, classes slightly
trickier

[TestFixture]

public class PersonTest

{


[SetUp]


public void GivenAPersonExists()


{..}


[TearDown]


public void PersonShouldBeRemoved()


{..}




[Test]


public void PersonShouldBeOlderThanZero()


{


...


Assert.That(p.Age > 0);


}

}

InterfaceToBeMocked aMock =


mocks.NewMock<IPerson>();


Stub.On(aMock).GetProperty("Age")


.Will(Return.Value(32));


Expect.Once.On(aMock)


.GetProperty("FirstName")


.Will(Return.Value("Jim"));

TDD

Unit test framework part of standard

libraries


BDD

rSpec, rBehave


Mocks

Mocha, rMock, FlexMock, etc




def test_person_is_called_james do


assert_equal 'James', @person.name

end


OR after a little bit of meta programming


test 'person is called James' do


assert_equal 'James', @person.name

end

p = mock('person')


p.stubs(:age).returns(26)


p.expects(:name).returns('James')

Visual Studio

Intellisense, debugger, PowerShell, etc

Continuous Integration

CruiseControl.Net and friends

Build Process

NAnt, MSBuild, NMaven, etc

PS C:
\
Users
\
Jim Webber> $name = "Jim Webber"

PS C:
\
Users
\
Jim Webber> $name

Jim Webber

PS C:
\
Users
\
Jim Webber> $name.ToLower()

jim webber

PS C:
\
Users
\
Jim Webber>


PS C:
\
Users
\
Jim Webber> ([xml](new
-
object
System.Net.WebClient).DownloadString("http://jim.webber
.name/feeds/atom.aspx")


).feed.title

World Wide Webber

IDE

Visual Studio with Iron Ruby

IntelliJ, e
-
Edit, TextMate provide syntax
highlighting and script support.


Build Process: Rake


Continuous Integration

CruiseControl.rb and friends



C:
\
ruby>ruby script/console

>> p = Person.new( :name => 'Jim' )

=> #<Person:0x49c8d40


@attributes={"name"=>"Jim"}, ...>

>> p.save

>> name = 'Jim'

>> Person.find(:first, ['name = ', name])

=> #<Person:0x69c1d40


@attributes={"name"=>"Jim"}, ...>


C:
\
ruby> gem install mocha


Bulk updating Gem source index for:
http://gems.rubyforge.org


Successfully installed mocha
-
0.5.3


Installing ri documentation for mocha
-
0.5.3...

Installing RDoc documentation for mocha
-
0.5.3...

Apache Incubator project

Supports repositories for dependencies

Across the Internet

Plugs into the standard Maven build cycle

Will have VS integration

Extensible through Mono
-
based plugins


Also could use Ivy for dependency
management...

Warning:
NMaven

currently
immature

Rails is the most famous and popular

Ruby framework


Rails provides (among other things):

Neat MVC framework and route mapping

Template based views

Domain focussed business layer

Active Record and DSLs for persistence

Easy AJAX and Web 2.0 support

Auto
-
generated code (write time and run time)

Fast change cycle (edit file
-
> refresh page)

Plug
-
ins for code re
-
use

ASP.Net

Plus new ASP.Net AJAX functionality

Combine ASP.Net with Entity Framework for
Rails
-
like functionality


Silverlight

For richer client functionality

Most Ruby dev is
Rails and Web 2.0


There are GTK /
Gnome bindings for
Ruby and some rich
client Ruby apps.


WPF under .NET

WPF

Clear separation of markup and

business logic

Whizzy acceleration and goodness from
DirectX 10


Also the older WinForms stuff is available

WCF

WS
-
*

SOAP, WSDL, WS
-
Sec, WS
-
SecPol, WS
-
Trust, WS
-
Federation, WS
-
Coordination. WS
-
AtomicTransaction, WS
-
KitchenSink...

REST Support

URI templates, [WebGet], etc

Enterprise
-
y stuff too

Queues



REST
-
centric

Web services are produced like web pages,
using same framework and routing

Message Queues using Reliable
-
Msg or
underlying JMS or MSMQ

WS
-
* support

SOAP4R

Use underlying platform for WS
-
*, eg, WCF or
Java frameworks like XFire

.Net has XmlSerializer (and friends)

Dom, XPath, templates, etc


VB has XML literal support...

Dim x As XElement =


<date>


<year>2006</year>


<month>01</month>


<day>01</day>


</date>

var x = new XElement("Date");

x.Add(new XElement("Year", "2006"));

x.Add(new XElement("Month", "01"));

x.Add(new XElement("Day", "01"));

XPath and Document Object Model

well supported


To generate complex XML (eg, LIXI), the
best way is templating using Erb


All objects have to_xml method with
serialises properties to xml


XML Builder is nice to work with and
leverages Ruby's flexible method_missing

>> builder.date {

?> builder.year "2006"

>> builder.month "01"

>> builder.day "01"

>> }



<date>


<year>2006</year>


<month>01</month>


<day>01</day>

<date>

When to go Ruby versus

when to use C# and .Net?


Enterprise “heavy lifting?”


Cross
-
language enterprise development?

And what about mixing C# and IronRuby...?

Ask James and Jim!

ARC 310

Don’t Forget!

ARC 310