RSS Planet TW

http://blogs.thoughtworks.com/

Planet TW - http://blogs.thoughtworks.com

Last checked 7 months ago.

6 people have subscribed to this feed.

Feed frequency

post frequency (last month)

PostRank™ filter

latest 15 posts

« older items




Thursday February 14th, 2008

7.2

Ricky Lui: Services != Distributed Object

From Planet TW, 8 months ago, 0 comments Comment

(The title quotes Joshua Grahamт€™s comment here) I agree completely with Josh. In a casual conversation with Tim Cochran of Thoughtworks, we both felt that using RESTful controllers does not mean exposing all of your model objects, or database tables. Thoughts still need to go into designing the right interfaces.

In Rails, examples of RESTful controllers are usually CRUD controllers of ActiveRecord objects. (and the ActiveRecord objects are just straight mapping to database columns). My given example in the previous post is exactly like that, and thatт€™s because script/generate and scaffolding just make it so easy.

However, thatт€™s not an excuse not to think about what to expose, and what to hide. In our current project we have a rails app (say an HR app) that needs to obtain/update the Account information on another rails app (say an sales app). On the sales app side, letт€™s say Account is an ActiveRecord that has the following fields:

id: integer
number: integer
name:string
description: string
balance:integer
sales_person_number: integer

and there is already an AccountsController, with associated HTML forms, for CRUD-ing all the fields on an Account.

On the HR app, we are interested only in the sales_person_number of the account. So we instead implemented a brand new SalesPersonAssignmentsController on the sales app, to assign a sales person, so that

POST http://sales.app/sales_person_assignments params => {:sales_person_number => 666} # Give sales_person an account to look after

returns an empty HTTP response, with status code 201 CREATED, and the т€˜Locationт€™ header : "/sales_person_assignments/123"
# The sales app had given account #123 for the salesperson to look after

We havenт€™t implemented any security measures yet, to prevent the HR app to hit other actions on the sales appт€™s AccountsController. But at least the intention is that the HR app will only hit the SalesPersonAssignmentsController only, and nothing else, on the sales app. That hopefully limits the integration points, and make the change on one app have less impact on another app.

Conclusion: I think encapsulation, loosely-coupled systems, are good ideas. They donт€™t call me Captain Obvious for nothing :)

1.0

Ola Bini: Soft and hard layers

From Planet TW, 8 months ago, 0 comments Comment

I hadn't read this specific c2 post, but it's funny how much of what I write is just a rehash of stuff Cunningham and company came up with 15 years ago. Well. I guess that's why they're the masters and I'm not.

Incidentally, this is my 300th blog post, since starting this blog a little bit more than 2 years ago. Time rushes by, don't it?
5.6

Ola Bini: Scala exploration status

From Planet TW, 8 months ago, 0 comments Comment

Someone asked in a comment where my Scala exploration were going. It's a fair question.

I did a first implementation of the core of the system I was using. Most of if was tested using Specs (which incidentally is very good, and even more importantly - have a responsive creator). Now, I realized a while back that the implementation weren't really using Scala properly. I had mostly used the imperative way of doing things. So I'm planning a rewrite of these parts, using pattern matchin, case classes and more recursive algorithms correctly. It's kinda funny. I didn't expect this to happen since I have so much experience with functional languages. But apparently, the fact that Scala looks like Java in many regards makes it very easy to slip into the Java imperative mode. Not good.

Right now I'm spending some time working on the next release of JtestR, writing on a book, and doing some pesky day time work. =) Also, JRuby needs to have its 1.1 release. I expect to get back to Scala within one or two weeks, though.

Akshay Dhavle: Functional Goals

From Planet TW, 8 months ago, 0 comments Comment

After this post, I have had a number of conversations with people about what I really meant by setting functional targets instead of story point (velocity) targets. In one such discussion, I was given an example where someone set a goal to run for 90 minutes!!

At first glance you might not find the last statement worth the exclamation marks at the end of it. But this is exactly the difference between functional targets and velocity targets. I think it's wrong to set a target of running for 90 minutes. The real goal is to burn X number of calories. Or to travel X number of kilometers.

Once you set your goal right, you are open to find better ways of achieving it. If your goal is burning calories, you'd probably do it better (faster) by skipping rope for 30 minutes than by running for 90 minutes.

Now all you have to worry about is
  • the rate at which you are actually burning calories AND
  • what can you do to improve this rate

So instead of planning to complete 30 points next iteration (going by yesterday's weather, etc), I'd plan to achieve a set of features and keep optimizing the rate at which I am able to produce features assuming that I never compromise quality in wake of going faster.

Simon Brunning: Who do you have to call a twat to get your comment deleted?

From Planet TW, 8 months ago, 0 comments Comment

Via Rosie, Max, 19 is the funniest thing I've read in ages.

Of course, he's nineteen, so of course he's a tosser. Had this been up on facebook, it would blend in perfectly. It's just on the Grauniad travel front that he's going to attract such opprobrium.

10

Ola Bini: Silly Io experiment

From Planet TW, 8 months ago, 0 comments Comment

I have known for some time that Io is quite powerful as a language. I wanted to check if it was also suited for creating DSLs. Since I'm lazy I didn't want to create a new DSL just for this, so I decided to appropriate the associations language from ActiveRecord.

The process I followed was this - first come up with something that looks passably nice, then try to implement it. The only requirements was that the names of the associations were saved away somewhere, once per prototype for each model. This is the syntax I came up with (well OK, I didn't work very long on it...):
Post := IoRecord {
has many authors
belongs to blog
belongs to isp
}

Author := IoRecord {
has many blogs
has many posts
has one name
}
Actually, this looks almost readable, right? It's all valid Io code. The question is, how do we get it to do what we want? Without further ado, here's an implementation that gives us enough:
IoRecord := Object clone do(
init := method(
self belongings := list
self hasOnes := list
self hasManies := list
self hasFews := list
)

appender := method(msg,
blk := block(
call sender doMessage(msg) append(call message next name)
call message setNext(call message next next)
)
blk setIsActivatable(true)
)

collector := method(
meths := call argCount / 2
waiter := Object clone
for(index, 0, meths-1,
waiter setSlot(call argAt(index*2) name,
appender(call argAt(index*2+1)))
)
waiter
)

belongs := collector(
to, belongings
)

has := collector(
many, hasManies,
one, hasOnes
)

curlyBrackets := method(
current := self clone
call message setName("do")
current doMessage(call message)
)
)
Since I'm a bad person and really enjoys metaprogramming, I had to get rid of most of the duplication the first implementation contained. Let's say it like this: the first version didn't have the collector and appender methods. And boy do they make a difference. This is real metaprogramming. Actually, these two methods are actually macros, almost as powerful as Common Lisps. Notice that the words we send in to collector doesn't actually get evaluated. This is one of the reasons we don't need to use symbols - we can just take the unevaluated messages and take their name. In the appender macro we're doing something really funky where we use setNext.

The final effect of that setNext call is that in something like "has many foobar", Io will not try to evaluate foobar at all. In fact, even before Io tries this, we remove the foobar message from the chain and inserts the next message instead.

Oh, right, and the Io lexer actually inserts a synthetic message called "curlyBrackets" when it finds curly brackets. The brackets themselves actually act exactly like parenthesis. You can try this out in Io by changing the closing parenthesis to a closed curly bracket instead - Io doesn't care. Your brackets doesn't have to match up in type, just in cardinality.

Of course, this is just the beginning. Io will blow your mind.

The thing I'm finding myself missing is a good literal syntax for hashes and lists. I'm thinking about implementing something for that. Also, using atPut is starting to get annoying. I want square brackets access. Shouldn't be too hard, since Io does the same thing with square brackets as it does with curly brackets. Almost, at least.

And btw, the Io standard library... Not sure what I think about it. I miss many things from the Ruby core library actually. Now, Io combined with the Ruby libraries, that might be fun?
1.0

Abdul Salam: Refactoring vs Redesign??? or Restructuring

From Planet TW, 8 months ago, 0 comments Comment

Is it refactoring or a redesign?
Its a 'big refactoring'.
We spent the last two weeks on refactoring.
You guys are doing redesign and calling it as refactoring.

I am sure that most of us would have come across questions/statements like the above on various occassions. The above statements initially gave me a sense that its the magnitude of the change that differentiates between a refactoring and redesign.

Last evening I had a chance to chat with Martin Fowler regarding this and here is Martin's words.
"Rather than Refactoring vs Redesign I would like to see it Refactoring vs Restructuring. Refactoring is one of the ways to restructure your code. You can restructure your code by rewriting a class also. Refactoring is my preferred way of restructuring. While each transformation(refactoring) will result in a small change, a sequence of transformations(refactorings) can produce a significant restructuring.".

More about refactoring can be found here.
10

Daniel Manges: Using DRb to Preserve a SeleniumDriver

From Planet TW, 8 months ago, 0 comments Comment

Selenium is a great tool for web acceptance testing, but working on tests can be laborious. In addition to the general slowness of actually testing through the browser, starting a SeleniumDriver takes about 6 seconds on my MacBook.

SeleniumDriver Benchmark


require "rubygems"
gem "Selenium"
require "selenium"

benchmark = Benchmark.measure do
  driver = Selenium::SeleniumDriver.new(
    "localhost", 4444,
    "*firefox", "http://localhost:3000"
  )
  driver.start
  driver.stop
end
benchmark.to_s
#=> "  0.000000   0.000000   0.000000 (  6.294741)"

If the selenium driver could stay open between test runs, running a test could be much faster. Fortunately, DRb makes this easy. Here are the rough steps.

SeleniumDriver DRb Server

First, start a SeleniumDriver and place it in a DRb service.


require "rubygems"
gem "Selenium"
require "selenium"
require "drb"

SERVER = "druby://:51785"

driver = Selenium::SeleniumDriver.new(
 "localhost", 4444,
 "*firefox", "http://localhost:3000"
)
driver.start
DRb.start_service SERVER, driver
puts "Ready"
DRb.thread.join  

The DRb.thread.join call at the end of this script means the script won't exit. Run it from a terminal, use Ctrl+C to stop it.

SeleniumDriver DRb Client

The next step is to use this instance when running tests. DRb provides a class that functions as a proxy to the object running in the server. In this case, that's the selenium driver.


DRb.start_service
driver = DRbObject.new(nil, SERVER)
class << driver
  # make sure type hits method_missing to delegate to driver
  undef_method :type
end

Using the DRbObject as a proxy to the SeleniumDriver requires hacking the type method to make sure it delegates properly.

SeleniumDriver with DRb Benchmark

Here's the benchmark for this version:


benchmark = Benchmark.measure do
  DRb.start_service
  driver = DRbObject.new(nil, SERVER)
  class << driver
    # make sure type hits method_missing to delegate to driver
    undef_method :type
  end
end
benchmark.to_s
#=> 0.000000   0.000000   0.000000 (  0.070634)

The time to start the driver is now negligible.

I've been using this for a few days, and it is working well. If you actually want to try this, here are a couple tweaks to the code that you'll want to make.

Stopping the Server

To stop the SeleniumDriver when stopping the process, wrap DRb.thread.join like this:


begin
  DRb.thread.join
rescue Interrupt
  begin
    puts "Stopping..."
    driver.stop
  rescue Exception
    puts "failed stopping selenium driver"
  end
end

Checking the Client Connection

DRbObject does not check the connection when it's first initialized. You may want to force it to check the connection by doing something like this:


begin
  DRb.start_service
  driver = DRbObject.new(nil, SERVER)
  driver.respond_to?(:anything?)
rescue DRb::DRbConnError
  # do something
  # fail over to non-DRb driver?
end

A call to respond_to? will check to see if the DRb server is available. You may want print out an informative message or fail over to using a non-DRb driver if it cannot connect.

Simon Brunning: Links for 2008-02-13 [del.icio.us]

From Planet TW, 8 months ago, 0 comments Comment

1.0

Thamarai Poomalai Selvan: AnonymousClassLoader in OpenJDK Mlti-Language VM (MLVM)

From Planet TW, 8 months ago, 0 comments Comment

When we implement JIT interpreter for dynamic languages on JVM, we typically deal with set of data (Environment) and Operations (Methods, Lambda etc).

Design and loading of class definition for data and operations on JVM, has following challenges (pains),

a) We can't define a light weight / anonymous methods in JVM on the fly.

Method definition must live in a class. (Relationship between class that defines method and data could be composition or inheritance).

b) We can't load multiple class definitions of same class / overwrite previously loaded class definition with new one, in the same class loader.

Class loader keeps track of all loaded class in its System Dictionary. When we try to reload class definition (even though class definition is changed after first load), class loader checks for any entry in System dictionary for a given class name. If so, it will return class definition of system dictionary entry.

To circumvent above issue, we instantiate (custom) new class loader every time when class definition changes.

c) Garbage collection issue

Class loader is another Java class in JDK. When a class (Let's call host class) instantiates our custom class loader; say CL1, class loader of host class (could be system class loader or ext class loader or another custom class loader) can reach CL1 class loader. Make sure custom class loaders like CL1 are eligible for GC (there by all classes loaded by that class loader) when they are no longer useful.

OpenJDK Mlti-Language VM, introduces java.dyn.AnonymousClassLoader that alleviates above pain points,

1) No System Dictionary in AnonymousClassLoader and AnonymousClassLoader is independent of existing class loaders in JDK. (Refer AnonymousClassLoader.java)

2) We can load multiple definition of same class using same instance of AnonymousClassLoader and it is responsibility of the user to choose preferred class definition among loaded class definitions to create instance. (Refer testAPI method of DVMTest.java)

3) Classes defined by AnonymousClassLoader are not reachable by class loader of host class. Making not-in-use class definitions available for GC is simple.

Above points are not theory, we have tested and working prototype ready. If you want to try yourself, refer my previous post on building MLVM.

QR code for building MLVM :
5.2

Richard Durnall: Interview: Lean Software Development with Mary Poppendieck

From Planet TW, 8 months ago, 0 comments Comment

About Mary Poppendieck:: Mary is a former programmer and IT manager turned Lean Software Development Evangelist, Author and Trainer. Mary, with her husband Tom, is the author of the award winning books Lean Software Development: An Agile Toolkit and Implementing Lean Software Development: From Concept to Cash.

Q. What does the term Lean software development mean to you?

Lean software development is applying lean principles to software development.

Q. What level of improvement have you seen from teams transitioning from traditional waterfall software development models to Lean software development models?

I never even heard of the word waterfall until 1998 when I retired from my job at 3M and got involved in my first government software project – which was “waterfall and proud of it”. It was also pretty much of a disaster. So it’s hard for me to think of “waterfall” as traditional. And in fact, I haven’t seen many waterfall models in action – except for that one I ran into in 1998. So I’m not quite sure how to answer your question. I can say that when organizations start using a disciplined test-driven development process combined with short iterations, they often report 30-50% defect reduction and dramatic productivity improvements. But productivity is tricky to measure – so I won’t put a number on that.

Q. To date within the IT community we have applied Lean to the software development process to gain efficiencies. Do you feel that there is an opportunity to use this knowledge to work with our business partners to apply Lean principles to improve the processes that our applications automate?

I find it often works the other way around. People with lean operational processes need software to support the process and urge the software development group to become lean so as to provide them with better support. In fact, I did a workshop at a bank which processed mortgage papers. The paper handling process was vastly improved through lean techniques, but the teams were unable to get software changes they needed – even though their process was driven by workflow software. In another case, an insurance company, the IT department was unable to support business teams. At both companies, I suggested that a couple of developers simply be assigned to each lean team to make the software changes the team needed in a Just-in-Time manner.

Q. Hand-offs are viewed as being wasteful. There is often a hand-off from business to IT but there is also a common hand-off from IT to operations and support. Do you have any suggestions on how this second hand-off can be handled?

Both handoffs are equally harmful. The very words “business” and “IT” indicate that people think (more…)

Wednesday February 13th, 2008

5.2

Tim Goodwin: Behavior Driven Development

From Planet TW, 8 months ago, 0 comments Comment

At the recent Alt.NET UK conference, one of the topics that received a fair bit of conversation and debate was Behavior Driven Development and Test Driven Development. Specifically whats the difference? And is the difference just semantics?

To me, the differences are just semantics but its those semantics that make it such a valuable approach.

A recent post from Dan North sums it up pretty good:

My goal as a developer is to deliver a system that behaves in a particular way. Whether or not it has tests is an interesting metric, but not the core purpose. “Test-driven” development will cause me to have lots of tests, but it won’t necessarily get me nearer the goal of delivering business value through software. So you can use goal-oriented vocabulary in your development process as well as your code to help maintain perspective on what you are trying to achieve.

The true benefit comes from finding an alternate way of thinking/approaching/communicating the problem.

This is an area I'd like to see the .NET community improve in.
There tends to be too much focus on a new tool or new framework being the solution to a given problem, which ultimately leads to misuse or use without understanding.

It's important to remember that the tool should not be the solution to the problem, it should support solving the problem.
1.0

Ola Bini: Java Annotations

From Planet TW, 8 months ago, 0 comments Comment

I feel that a few rants are about to burst in me. Let me take this first; this is not a rant, though. Just a very large exclamation:

Java Annotations are NOT a way to implement DSLs, and will never be.

Java annotations are really nice, but seriously, they are NOT manna from heaven.

Simon Brunning: Links for 2008-02-12 [del.icio.us]

From Planet TW, 8 months ago, 0 comments Comment

Tuesday February 12th, 2008

10

Szczepan Faber: 10 rules of (unit) testing

From Planet TW, 8 months ago, 0 comments Comment

There you go, those are my 10 rules of (unit) testing. It's nothing exciting, really. Everyone is so agile these days. Are you agile? I bet you'd say: I was born agile. Here I come with my own 10 commandments. I came up with those while doing research on mock frameworks ...

« older items