Atom Feed SITE FEED   ADD TO GOOGLE READER

Who holds the remote control?

I have a DVR built into the receiver for my Canadian satellite dish. It's fantastic. I love being able to record Canadian football games and to do my own instant-replays when I see something great.

Tonight I'm home alone - Jodie's out shopping in San Francisco. When I got home, I immediately collapsed on the couch to veg out in front of the TV. But when I turned it on, I discovered that one of Jodie's shows is being recorded. And since our set-top-box only has a single tuner, I can't really watch anything else.

It's like the TiVo* lets her hold the remote control, even when she's gone!

Don't do this: evading polymorphism

I've got two classes, Base and Sub. I can freely make changes to Base. But Sub is written by a third party and I don't have privileges to make changes to it. Here's what they look like:
public class Base {
public void prepareForMission() {
loadUpInfantry();
loadUpWeapons();
}
}

public class Sub extends Base {
public void prepareForMission() {
super.prepareForMission();
loadUpOxygen();
}
}
Suppose that I need to change the behaviour for instances of Base without changing the behaviour of Sub or other subclasses.

The horrible, ugly hack I came up with for this is to evade polymorphism like so:
public class Base {
public void prepareForMission() {
loadUpInfantry();
loadUpWeapons();
if (getClass() == Base.class) {
loadUpSecretPlans();
}
}
}

Doesn't it make ya cringe? I'm quite ashamed of it.

CorelDraw on Mac discussion forums

Long before I was writing code, I liked to play with the CorelDRAW graphics suite. Unfortunately, Corel abandoned the Mac market five years ago!

I've blogged some tips and tricks on getting CorelDRAW to run on new Macs. And a lot of people searched for them on Google and commented on them! Since I'm not the only one holding tight to this old software, I took a couple hours and setup a Google Group:


Welcome to CorelDRAWonMac.com,
a support group for fans of CorelDRAW and the Mac.


Stephan Schmidt on type inference

Stephan Schmidt writes,
Beside the fact that my IDE does the typing with auto completion - of course the compiler knows - DUH. But the developer does not know.
I couldn't agree more with his recent post on programming languages.

Simpler service interfaces with Guice

I'm using Guice throughout my code, and I've found a pattern that works rather nicely. Suppose I've got a service interface method for scheduling a delivery:
public interface DeliveryService {
/**
* Schedules {@link order} for delivery and returns a snapshot with
* the details of the scheduled delivery.
*
* @param loggedInUser the customer service rep who is making this request.
* @param selectedCustomer the customer to whom the order will be delivered
* @param order the order to schedule a delivery for
*/
Delivery scheduleDelivery(User loggedInUser,
Customer selectedCustomer, Order order);
}
The interface does exactly what it needs to do. But since it has so many parameters, calling it is a hassle for the caller. They need to inject the user and customer, only to pass it to the service:
public class ScheduleDeliveryAction implements Action {
private final DeliveryService deliveryService;
private final User loggedInUser;
private final Customer selectedCustomer;
private Delivery delivery;

@Inject
public ScheduleDeliveryAction(DeliveryService deliveryService,
User loggedInUser, Customer selectedCustomer) {
this.deliveryService = deliveryService;
this.loggedInUser = loggedInUser;
this.selectedCustomer = selectedCustomer;
}

public String execute() {
/* parse HTTP parameters etc. */
Order order = ...

this.delivery = deliveryService.scheduleDelivery(
loggedInUser, selectedCustomer, order);

return SUCCESS;
}

...
}

A better approach


A better approach is have the service know about the logged in user and customer implicitly. I change the real implementation of the service so that it gets the Customer and User injected into it. Now the interface is simpler:
public interface DeliveryService {
/**
* Schedules {@link order} for delivery and returns a snapshot with
* the details of the scheduled delivery.
*
* @param order the order to schedule a delivery for
*/
Delivery scheduleDelivery(Order order);
}
And so is the calling code:
public class ScheduleDeliveryAction implements Action {
private final DeliveryService deliveryService;
private Delivery delivery;

@Inject
public ScheduleDeliveryAction(DeliveryService deliveryService) {
this.deliveryService = deliveryService;
}

public String execute() {
/* parse HTTP parameters etc. */
Order order = ...

this.delivery = deliveryService.scheduleDelivery(order);

return SUCCESS;
}

...
}
The other great benefit of this approach is that if we need to add more fields to DeliveryService, we don't need to change the callers. With Guice, your code is simpler because you don't need to worry about indirect dependencies.