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!
# posted by Jesse Wilson
on Thursday, November 15, 2007
1 comments
post a comment
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.
# posted by Jesse Wilson
on Wednesday, November 14, 2007
5 comments
post a comment
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.
# posted by Jesse Wilson
on Sunday, November 11, 2007
1 comments
post a comment
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.
# posted by Jesse Wilson
on Monday, November 05, 2007
0 comments
post a comment
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.
# posted by Jesse Wilson
on Thursday, November 01, 2007
0 comments
post a comment