james crisp and jim webber, thoughtworks arc310. platform code affordances tool support...

Post on 22-Dec-2015

220 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Learning to Live with the Static Typing Fascist and the Dynamic Typing Fanboy in your Enterprise...

James Crisp and Jim Webber, ThoughtWorks

ARC310

Roadmap

PlatformCode affordancesTool supportExtensibilityDevelopment ProcessData accessMetaprogrammingApplication developmentIntegration

Platform

Windows!.Net 3.5

Maybe Linux, via Mono

Platform

AnywhereWindowsLinuxMacCLRJVM

Readability

How concise and readable is thecode?How much code will I have to maintain?How productive can I be?

Attributes

class Person attr :id attr_accessor :name, :ageend

Named Parameters

p = Person.new(:first_name => "Freddy",:last_name => "Flintoff")

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

Default PropertyImplementationclass Person{ public string FirstName { get; set; }...

Initialisers

Person p = new Person { LastName = "Dundee", FirstName = "Mick" };

Meta Plumbing

class DomainObject def initialize(attributes = {}) attributes.each do |name, value| eval("@#{name} = value") end end end

Duck Typing

h = House.new( number => 20 )p = Phone.new( number => 123456 )

p = h

p.number >> 20

Type Inference

var p = new Person { LastName = "Smith"};

Who needs Duck Typing?

interface INumbered{ int Number { get; }}

class House : INumbered ...class Phone : INumbered ...

INumbered phone;INumbered house = new House();phone = house;phone.Number

Data

LINQ and Entity FrameworkCastle project

Active record for .NetBuilds on NHibernate

NHibernate too!

Design Time

Generate and Use theDatabasePersonDataContext 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);}

Data

Active Record ships with RailsGood for green field web appsObjects and properties mapped 1:1 to tables and columnsSimple API for searching and saving

Can use underlying platform – eg, Hibernate or NHibernate

Lambda Functions

What are Lambda functions?

From the functional programming community

Who?

Think: anonymous inline methodsC# 2.0 anonymous delegates with nicer syntax

Pass a function into acollectionList<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));

Lambda Functions

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

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

Metaprogramming & DSLs

Method Missing

DSLs

Code generation at run time

Method Missing

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)

Code Generation atRun Time

Create new properties, methods and classes on the fly

Redefine, wrap and rename methods

Eval() a string, and it will be code

Code Generating DSL

class Geek < ActiveRecord::Basehas_many :laptopshas_one :girlfriend

end

jim = Geek.new(:name => 'Jim' )laptop = Laptop.new(:brand=> 'dell')jim.laptops << laptop

rSpec DSL

describe Geek do before(:each) do @geek = Geek.new end

it "should have no laptops initially" do @geek.laptops.count.should == 0 end

....

Autogen andMetaprogramming

Can generate useful code from metadata at compile time

E.g. Domain objects from database schemasE.g. Service proxies from WSDLEtc

Attributes for metaprogrammingAnd the reflection APIs if I have to...

DSLs

Some support for fluent interfacesin NUnit etc

Assert.That(...);Assert.IsNotNull(...);

Can create our own DSLs by using cunning class name conventions

E.g. nBehave for BDDLike TDD but focussed on behaviour rather than implementation

nBehave DSL

override public void Specify(){ Given(new RubyProgrammer()). When(new BuildingProperSoftware()). Then(new RubyProgrammerShouldBeFired());} Tooling available to turn

this code into development stories for

xBehave

Extensible Type System

All classes are open and can beextendedEg, 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

Adding new methods

class String def url? self.starts_with? "http://" endend

>> "hi".url?=> false>> "http://jamescrisp.org".url?=> true

Extensible Type System

We’ve always had interfaces andabstract classes from the underlying .Net frameworkNow we have extension methods too...

Defining Extension Methods

namespace JimWebber{ public static class WebUriValidator { public static bool IsValidUri(this string str) { return str.ToLower().StartsWith("http"); } }}

Using Extension Methods

using JimWebber;class Program{ static void Main(string[] args) { string s ="http://jim.webber.name"; bool b = s.IsValidUri(); }}

Testing

Unit Testing TDD – NUnit BDD – nBehavenMock – Interfaces easy, classes slightly trickier

NUnit

[TestFixture]public class PersonTest{ [SetUp] public void GivenAPersonExists() {..} [TearDown] public void PersonShouldBeRemoved() {..} [Test] public void PersonShouldBeOlderThanZero() { ... Assert.That(p.Age > 0); }}

nMock Example

InterfaceToBeMocked aMock = mocks.NewMock<IPerson>();

Stub.On(aMock).GetProperty("Age") .Will(Return.Value(32));

Expect.Once.On(aMock) .GetProperty("FirstName") .Will(Return.Value("Jim"));

Testing

TDDUnit test framework part of standardlibraries

BDDrSpec, rBehave

MocksMocha, rMock, FlexMock, etc

Unit Test Example

def test_person_is_called_james do assert_equal 'James', @person.nameend

OR after a little bit of meta programming

test 'person is called James' do assert_equal 'James', @person.nameend

Mocha Example

p = mock('person')

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

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

Tool Support

Visual StudioIntellisense, debugger, PowerShell, etc

Continuous IntegrationCruiseControl.Net and friends

Build ProcessNAnt, MSBuild, NMaven, etc

PowerShell

PS C:\Users\Jim Webber> $name = "Jim Webber"PS C:\Users\Jim Webber> $nameJim WebberPS C:\Users\Jim Webber> $name.ToLower()jim webberPS C:\Users\Jim Webber>

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

Tool Support

IDE Visual Studio with Iron RubyIntelliJ, e-Edit, TextMate provide syntax highlighting and script support.

Build Process: Rake

Continuous IntegrationCruiseControl.rb and friends

Console

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"}, ...>

Gems

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...

NMaven

Apache Incubator projectSupports repositories for dependencies

Across the InternetPlugs into the standard Maven build cycleWill have VS integrationExtensible through Mono-based plugins

Also could use Ivy for dependency management...

Warning: NMaven currently immature

Web Apps RAILSRails is the most famous and popularRuby framework

Rails provides (among other things):Neat MVC framework and route mappingTemplate based viewsDomain focussed business layerActive Record and DSLs for persistenceEasy AJAX and Web 2.0 supportAuto-generated code (write time and run time)Fast change cycle (edit file -> refresh page)Plug-ins for code re-use

Web Apps

ASP.NetPlus new ASP.Net AJAX functionality

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

SilverlightFor richer client functionality

Rich Client

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

Rich Client

WPFClear separation of markup andbusiness logicWhizzy acceleration and goodness from DirectX 10

Also the older WinForms stuff is available

Integration

WCF WS-*

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

REST SupportURI templates, [WebGet], etc

Enterprise-y stuff tooQueues

Integration

REST-centricWeb services are produced like web pages, using same framework and routingMessage Queues using Reliable-Msg or underlying JMS or MSMQWS-* support

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

XML and Friends

.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>

C# Not Tightly Coupled toXMLvar x = new XElement("Date");x.Add(new XElement("Year", "2006"));x.Add(new XElement("Month", "01"));x.Add(new XElement("Day", "01"));

XML and Friends

XPath and Document Object Modelwell 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

XML Builder

>> builder.date { ?> builder.year "2006" >> builder.month "01" >> builder.day "01" >> } <date> <year>2006</year> <month>01</month> <day>01</day><date>

Coexisting in theenterprise

When to go Ruby versuswhen to use C# and .Net?

Enterprise “heavy lifting?”

Cross-language enterprise development?

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

Questions?Ask James and Jim!

ARC 310

Evaluation FormsDon’t Forget!

ARC 310

top related