Thursday, June 28, 2007

Logging and Unit-Testing

Imagine the following situation:

1 public class SomeService {

2 private static ILogger _logger = new Logger<SomeService>();

3 //...

4 public void DoSomething() {

5 _logger.Debug("I log something cheap {0}", _service.DoSomething());

6 //...

7 if (_logger.IsDebugEnabled()) {

8 _logger.Debug("I log something expensive {0}", _service.DoSomethingElse());

9 }

10 }



How do we want to test that logging works in this situation?
A proposed solution was:

13 [Test]

14 public void should_log_something() {

15 using(disable_appenders_and_introduce_new_appender = new MagicStringAppender()) {

16 _service_under_test.DoSomething();

17 Assert(disable_appenders_and_introduce_new_appender.AllMessages.Contains("I log ...");

18 }

19 }



And here is what I don't like about it:
  1. Static creation of ILogger: by this we make ourselves dependent of the concrete implementation of Logger class. This will pull other dependencies (like log4net) in the environment, despite the fact that these are irrelevant for the test. The logger will be created when the class(type) is instantiated.
  2. The check-before logging for expensive log operations, is too low-level. A macro might help (TRY_LOG_DEBUG(...)), or maybe delaying the expensive operation into a lazy delegate: _logger.Debug(Func a_delayed_string_generator). The only objection might be that wrapping the costly operation in a delegate creates an extra object, making in the worst case scenario, the logging even more expensive. (From what I know, delegates & closures are pretty cheap).
  3. Maybe we don't know which operations are cheap and which are expensive, maybe in time a cheap log call will evolve to an expensive one. I would prefer a uniform lazy_delegate or macro solution.
  4. We are trying to unit-test a scope which is too big: if the service sends a message to the logger interface, if log4net (and its wrapper) receive the message, if according to the configuration, the log message is sent to the right appender, etc... Suppose that we change the config, and log4net, and the test fails. Then we have a lot of fun debugging. We will say: "why isn't working, I haven't changed anything in months". Because the scope is too big, we have no chance to do a binary chop.
  5. We have built another big machinery to manipulate log4net at the wrong end. This machinery must be maintained and support (for example when we want to switch to another log engine)
What I would do (probably better):
  1. Explicitly specify that we want to log in constructor. Either inject an ILogger or an ILoggerFactory.
  2. Test only that the service sends a message to the ILogger interface (a mock or a stub recorder)
  3. Try to use a delegate for delayed/expensive computations.
  4. Use a main logger for the critical exceptions (like OutOfMemory)
---
Update:
- the post it is not about what am I trying to log, it is about "how" I am trying to log. (suppose the expensive operation is dumping a complex object tree to a human-readable-not-xml representation)
- I am not a proponent for logging-testing, but some people would like to do that (logging gives a chill-fuzzy feeling: "I don't know what I have implemented, QA also doesn't have a clue, and now we are relying on log files, on a production-customer-machine. hmmm..."

Friday, June 15, 2007

F# FizzBuzz

I'm trying to learn F# as the "pragmatic-learn-a-new-changing-the-way-you-think-programming-language-every-year" (sorry about that, it must be the german influence).

Here are my FizzBuzz exercises, based on F# Active Patterns:

First try:

let (| fizz|_ |) x = if x % 3 = 0 then Some("fizz") else None

let (| buzz|_ |) x = if x % 5 = 0 then Some("buzz") else None

let (| fizzbuzz|_ |) x = if x % 15 = 0 then Some("fizzbuzz") else None

let print_fizzbuzz (x:int) =

let display text = print_string text; print_newline() in

match x with

| fizzbuzz text -> display text

| fizz text -> display text

| buzz text -> display text

| _ -> x.ToString() |> display

let _ = for i = 1 to 20 do print_fizzbuzz i done



Second try: refactor the recognizers to a single parameterized recognizer:


let (| is_multiple|_ |) n text x = if x % n = 0 then Some(text) else None

let print_fizzbuzz (x:int) =

let display text = print_string text; print_newline() in

match x with

| is_multiple 15 "fizzbuzz" text -> display text

| is_multiple 5 "fizz" text -> display text

| is_multiple 3 "buzz" text -> display text

| _ -> x.ToString() |> display

let _ = for i = 1 to 20 do print_fizzbuzz i done


(* we do get a warning that the syntax for the parameterized recognizers is under review and it might change in the future release *)

Please post or backlink for improvements :D

Tuesday, June 05, 2007

APIs, handling dependencies, agile architecture

Somebody said recently that Resharper is "not so lovely" since it cannot handle thousand of files... My argument is that the need to work simultaneously (in a solution) is a smell, and the fact that Resharper crashes at type-parsing with a "System.OutOfMemoryException" exception should amplify the smell (increase our awareness).

I think we have only two cases: inside the membrane, or outside the membrane. The core of the cell represents a service implementation, the membrane represents service definition, outside the membrane are the service consumers/users. Actually outside the membrane, is inside another membrane: the whole architecture should be splitted in components.

If we are inside we are working on the implementation of a certain service(object, component). Inside a component we have limited visibility, up to a component interface (the membrane). Maybe some other interfaces, or stand-alone components (without external dependencies, for examples enumerating). All refactorings, type-parsing should occur without problem in this component.

If we are outside, we are service consumers. But we cannot talk to the "core" of the cell, we see only the membrane: the component interface. So we are not influenced by the changes in the implementation of the service (aka the "core").

What happens if you are a producer and you need to modify service definition. If we don't have a few consumers, we could load all the required components in a solution (producer + all consumers), and refactor the whole thing. If we have many consumers, we need to use public API techniques: we declare the whole interface as obsolete, we declare and implement the new one. After x weeks we delete the old interface (the consumers are responsible for refactoring their own code).

Isolating the change, is a fundamental principle in designing maintainable architectures. In a world without membranes, we are just hurting each other.

Tuesday, April 10, 2007

Higher-Level Abstractions on Enumerations

I am not the only one missing a higher-level of abstraction in .Net.
I feel that I wrote thousand times find, select, collect as foreach ...
statement, without the clarity (declarativeness) needed.
Here is my shot
(very lightweight at it):


Thursday, February 01, 2007

Static Considered Harmfull

Let's imagine the following situation:


static class Service {
static void DoSomething(...)
}

class Client {
Client() {}

void Action() {
Service.DoSomething(...)
}
}



We have the following smells:

1. Tight-Coupling
- The client object is tight-coupled with the Service class.
- We cannot exchange, polymorphically, the Service.DoSomething(...)
with another service FunkyService?.DoSomething.


2. "Lying" Constructor
- The client's constructor doesn't declare all the dependecies.

3. Tight-Coupling Propagation
- If the class Service has dependencies to other static classes
(methods, instances, properties), than these dependencies propagate into
the client. The "inoffensive" Service.DoSomething(...) is just the tip of an iceberg of singletons.

Proposed Solution:
In an OO world, responsabilities are realized by objects.
Unfortunately in static-typed langugages classes ARE NOT objects.
(in smalltalk/ruby they are, we don't have this problem)

So let's do it right from the beginning:


interface IService {
void DoSomething(...)
}

[Inject]
class Service {
void DoSomething(...)
}

class Client {
Client(IService service) { _service = service }
void Action(service.DoSomething(...));
}



Benefits:
- we are unattached from the implementation of the IService.DoSomething
- we have explicitely defined the responsability of the client to delegate/ask a
query to the IService implementor
- We can provide different implementations to the IService
- UnitTesting is easier: if the implementation of the IService has been tested,
then in the Client's unit-tests we are only interested in the call to IService,
which we can mock.
- Instance creation is handled by dependency injection container
(if you need only one, create just only one)


An example in ruby (classes are factory objects):
http://onestepback.org/articles/depinj/

Wednesday, October 04, 2006

A bile on the the death of agile and an other post about the flip side of agile as religion vs. agility at google: Good Agile, Bad Agile

Monday, September 11, 2006

Liskov Substitution in Dynamic Languages

A nice discussion on Michael S. Feathers blog.

Jim Weirich observes:


The original LSP is defined in terms of types and subtypes, not classes and subclasses. In Ruby, we try to remind people that type is not related to class. It seems to me that LSP still applies to dynamic languages, even if there is no direct language construct for type.


Also a link to dynamic/static type contracts (interfaces).

Thursday, September 07, 2006

Gmail Tricks

found here:


Gmail has an interesting quirk where you can add a plus sign (+) after your Gmail address, and it'll still get to your inbox. It's called plus-addressing, and it essentially gives you an unlimited number of e-mail addresses to play with. Here's how it works: say your address is pinkyrocks@gmail.com, and you want to automatically label all work e-mails. Add a plus sign and a phrase to make it pinkyrocks+work@gmail.com and set up a filter to label it work (to access your filters go to Settings->Filters and create a filter for messages addressed to pinkyrocks+work@gmail.com. Then add the label work).

More real world examples:

Find out who is spamming you: Be sure to use plus-addressing for every form you fill out online and give each site a different plus address.

Example: You could use
pinkyrocks+nytimes@gmail.com for nytimes.com
pinkyrocks+freestuff@gmail.com for freestuff.com
Then you can tell which site has given your e-mail address to spammers, and automatically send them to the trash.

Automatically label your incoming mail: I've talked about that above.

Archive your mail: If you receive periodic updates about your bank account balance or are subscribed to a lot of mailing lists that you don't check often, then you can send that sort of mail to the archives and bypass your Inbox.

Example: For the mailing list, you could give pinkyrocks+mailinglist1@gmail.com as your address, and assign a filter that will archive mail to that address automatically. Then you can just check in once in a while on the archive if you want to catch up.




Wednesday, September 06, 2006

Software Development as Turkey

from Darren Hobbs entry:


You can't achieve the same effect when roasting a turkey by doubling the temperatuire and halving the cooking time. Similarly a project cannot have the number of people doubled and the duration halved and get the same result. The rate of knowledge crunching is not increased by adding more people.





Closures in Java

Another post with links.

From Debasish blog, a link to Gilad Bracha's blog entry (with some nice comments)
Pick from post:


One question that naturally arises is "what took you so long?".
...
Since the late 90s, I've brought the topic up now and again. At times, even I have reluctantly been convinced that it is too late, because we've done so many things that would have been easy with closures in different ways. This means the benefits aren't as high as in a language like Scheme, or Self, or Smalltalk. The cost is non-trivial, to be sure.


Pick from the comments:

SUN never cared to implement Closures in Java.The reason why they are caring about now is Microsoft introduced them in C#.

So the funda is IF YOU WANT A NEW FEATURE IN JAVA DONT ASK SUN,(ITS TIME WASTE), BETTER ASK MICROSOFT, ONCE MS IMPLEMENTS THAT FEATURE IN THEIR LANGUAGE, THE NEXT YEAR SUN WILL CONSIDER THAT FEATURE. (This is also the quickest way of getting your favourite feature in JAVA).

(1st enums, support for dynamic languages, now closures...) :D

And a link to jaggregate examples.

Wednesday, July 26, 2006

Google Tech Talk: Cornelia Brunner - 'On Girls, Boys and IT Careers'

google video


Comments in code

from wiki: 'to need comments' and 'too much documentation'

Class comments - OK.
Method comments - NO
Comments in code - NO


If you need a comment to specify the behaviour of an object/method, specify that behaviour in some unit-tests. In that way you get runnable, automatic, one-click behaviour testing. If your test cases have good names, than you won't need to actually read the code in the tests, a brief look at the method names should say how an object/method reacts.

Tim Ottinger writes here:


A comment is an apology for not choosing a more clear name, or a more reasonable set of parameters, or for the failure to use explanatory variables and explanatory functions. Apologies for making the code unmaintainable, apologies for not using well-known algorithms, apologies for writing 'clever' code, apologies for not having a good version control system, apologies for not having finished the job of writing the code, or for leaving vulnerabilities or flaws in the code, apologies for hand-optimizing C code in ugly ways. And documentation comments are no better. In fact, I have my doubts about docstrings.

If something is hard to understand or inobvious, then someone *ought* to apologize for not fixing it. That's the worst kind of coding misstep. It's okay if I don't really get how something works so long as I know how to use it, and it really does work. But if it's too easy to misuse, you had better start writing. And if you write more comment than code, it serves you right. This stuff is supposed to be useful and maintainable, you know?

Is there any use of comments that are not apologies? I don't think so. I can't think of one. Is there any good reason to write a comment? Only if you've done something "wrong".




Podcast: Scott Ambler - Advanced Agile Techniques

mp3 here


Tuesday, July 25, 2006

Interview with Andy Hunt - Practices of an Agile Developer

on perlcast


no null

I've seen too many NullPointerExceptions.
Apparently I am not the only, see the post from Michael Feathers:


Passing null in production code is a very bad idea. It’s an example of what I call offensive programming – programming in way that encourages defensive programming. The better way to code is to deal with nulls as soon as they happen and translate them to null objects or exceptions. Unfortunately, this isn’t common knowledge.



Keith Ray explains how it is done in Objective-C:


In Cocoa / Objective-C programming, I still prefer an empty string over a null pointer, or an empty container-object over a null object, but the language does have a key difference: calling object methods on null-pointers does not normally crash! (But sometimes method parameters being null can cause a crash.)

Foo* aFoo = nil;
Bar* aResult = [aFoo someMethod: anArgument ];

calling someMethod (as above) on a nil object DOES NOTHING (it does not crash or throw an exception) and returns nil.

The Cocoa UI frameworks take advantage of this. For example, the objects that implements a Button or a Menu item would have two members variables: a pointer to an object, and a "selector" that identifies what method to call on the object. The method that handles a click (or whatever) would be written something like this:

[ targetObject performSelector: actionSelector withArgument: self ];

instead of like this:

if ( targetObject != nil ) {
[ targetObject performSelector: actionSelector withArgument: self ];
}

No need to check for a null targetObject. There would be a need to check for a null-selector (in the performSelector:withArgument: method), since the selector isn't actually an object.

People have objected that null acting like the "null object pattern" hides bugs, but too many times have I gotten web-apps sending me messages that a "null pointer exception has occurred" so I assert that null-pointer exceptions are not helping people find bugs as well as test-driven development, or thorough code-reviews and testing, would do. I expect that if null had the "null object" behavior, the web-app would have returned an partial or empty result rather than a crashing message, and that would be fine for a most users.

If the "null = null object pattern" behavior is an expected and documented part of the language, it can work quite well. Cocoa and NextStep programmers are, and have been, very productive using a language with this behavior.


Achileas Margaritis makes a very good point:

No, the problem with nulls is not their existence, but that there are not separate types.

This is the real problem: null is no object, you cannot send any message to it (you cannot call any method on it). So if I declare a function: doSomethingWith(Object somethingElse), than it is clear that I expect an object (and null is no object !!!) as argument for the method. (the same goes for the result of a function: object provideSomething()).

A colleague said that null is like a "joker" when playing cards. Nice metaphor, but null is an "evil" jocker.


Monday, July 24, 2006

Wednesday, July 12, 2006

Java "new" for non-static iinner classes

By (over) using non-static inner-classes, I came to the following code:

InnerClass created = outer_class_instance.new InnerClass(...);
The "new" operator is completely misleading: is no method(message) of the OuterClass.
It just couples the creation to the outer_class_instance scope.

strange...


Functional Programming

Peter Norvig's "Python for Lisp Programmers"
Another "comparison of Python and Lisp"
James Edward Gray  "Higher Order Ruby"

Lisp Scripting for .Net
F# ML/OCaml variant for .Net (nice sample here)

First feelings:
- Python is more functional than object oriented (watch-out for lambdas cannot contain statements)
- Ruby is more smalltalk-ish (I found it easier to use than Python)
- Lisp is more readble than ML/OCaml