.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

public class PerspectiveSelectionDialog extends Dialog<Perspective> {

    private static final Image iconSmall;
    private static final Image iconBig;
    static {
	try {
	    iconSmall = ResourceUtils.getImage(Perspective.class, "icons/FatCow_Icons16x16/switch_windows.png");
	    iconBig = ResourceUtils.getImage(Perspective.class, "icons/FatCow_Icons32x32/switch_windows.png");
	} catch (IOException e) {
	    throw new RuntimeException(e);
	}
    }

    public PerspectiveSelectionDialog() {
	super();
	setTitle("Perspectives");
	setHeaderText("Choose a perspective to be opened.");
	setGraphic(new ImageView(iconBig));
	Stage stage = (Stage) getDialogPane().getScene().getWindow();
	stage.getIcons().addAll(iconSmall, iconBig);
	setResizable(true);

	ListView<Perspective> listView = new ListView<>();
	listView.setEditable(false);

	fillListView(listView);

	getDialogPane().setContent(listView);

	ButtonType buttonTypeOk = new ButtonType("OK", ButtonData.OK_DONE);
	ButtonType buttonTypeCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
	ObservableList<ButtonType> buttonTypes = getDialogPane().getButtonTypes();
	buttonTypes.addAll(buttonTypeOk, buttonTypeCancel);

	setResultConverter(b -> {
	    if (b == buttonTypeOk) {
		return listView.getSelectionModel().getSelectedItem();
	    }
	    return null;
	});

    }

    private void fillListView(ListView<Perspective> listView) {
	ServiceLoader<Perspective> perspectives = ServiceLoader.load(Perspective.class);
	List<Perspective> items = new ArrayList<>();
	perspectives.forEach(p -> items.add(p));
	Collections.sort(items, (l, r) -> l.getName().compareTo(r.getName()));
	listView.setItems(FXCollections.observableArrayList(items));
	listView.setCellFactory(p -> {
	    ListCell<Perspective> cell = new ListCell<>() {
		@Override
		protected void updateItem(Perspective t, boolean bln) {
		    super.updateItem(t, bln);
		    if (t!= null) {
			setText(t.getName());
			Optional<Image> image = t.getImage();
			if (image.isPresent()) {
			    setGraphic(new ImageView(image.get()));
			}
		    }
		}
	    };
	    cell.setOnMouseClicked(event -> {
		if ((event.getClickCount() == 2) && (!cell.isEmpty())) {
		    Perspective perspesctive = cell.getItem();
		    setResult(perspesctive);
		    close();
		}
	    });
	    return cell;
	});
    }

}
The NoEstimates Movement
I started out my career as a programmer and consultant to build e-commerce sites. Effort estimates have always been around me while developing software. I have made effort estimates myself, and I have also asked other people to do it, then used them in all sorts of plans.
At the beginning of my career, I was absolutely crappy at making effort estimates. I once estimated a project that, in the end, took ten times longer than first expected. Later on, I gathered some knowledge and became better at it, but I have never liked to do effort estimates, and I think I share that sentiment with many others within the software development industry.
When doing effort estimates, there is a certain feeling of unease; you can’t predict the future, and you will be held accountable when more time is spent than was originally estimated. Is there another method we can use besides making effort estimates?
History
Through Twitter, the three initiators of the NoEstimates movement met for the first time in October 2012. They were Woody Zuill (an American software veteran), Vasco Duarte (a European author and agile practitioner), and Neil Killick (an Australian agile practitioner). By reading each other’s blog posts and continuing the discussion using the hashtag #NoEstimates on Twitter, they soon spread the word to others and the movement got started.
All of them were questioning the ”de facto” use of estimates in managing software development, but they had different ideas about the core problems of using estimates, and therefore different approaches to the solution. If you watch the ongoing #NoEstimates debate today, it can be quite vivid. In later days, Ron Jeffries and Kent Beck (two of the authors behind the Agile Manifesto) joined the discussion and shared their thoughts.
Three groups
Even if exploring still takes place regarding NoEstimates, I have tried to sort the positions into three groups:
- Continuous delivery
- Forecast/projection driven
- Estimation improvement
The first position, continuous delivery, takes on a highly agile path by finding the thing that delivers the most customer value. When the most valuable function/feature/story is found, that, and only that, is implemented and delivered to the customer. The claim is that only when you have done and delivered the most important thing can you go on and find out what the second most important thing is, deliver that, and so on. If waterfall is on one side of the spectrum, where everything is planned upfront, this is the most agile approach at the other end.
By regularly measuring the throughput of the team, like completed tasks per week, you can use that data to forecast and make projections for the future. As W. Edward Deming stated, your process needs to be in statistical control (stable), i.e., only common causes of variations can be present. This, for example, is achievable for teams that stay together over a longer period of time and are working on the same product.
The last group I simply call estimation improvement. Those people want to find ways to make estimates more accurate, and therefore more useful, for upfront planning. I see this as an attempt to stick with the waterfall method, and represents the least agile approach.
My experience is that project forecasts are needed, so I sympathize with the second group.
Planning a project before it starts
If you are continuously measuring the capacity of your team, you can do project planning without effort estimation. You can use the following steps:
- Measure capacity – Count completed tasks per week for the team.
- Analyze collected data – Analyze your collected data to be able to use it.
- Calculate metrics – Calculate the metrics to be used for forecasting.
- Time plan – Check the times from the time plan, since time is usually a delimiting factor in a project (when the project shall be finished).
- Forecast – Make a forecast using the calculated metrics and the given time constraint.
- Assumptions – Fulfill assumptions so you’ll be able to plan using this method.
- Similarities – Use the forecast and compare with other known references.
- Think – Given the gathered knowledge, think and judge if the project is feasible; if not, take proper actions.
With these eight steps, you don’t need to spend valuable time doing effort estimates.
How It’s Done
1. Measure capacity (completed tasks per week)
To measure the capacity, every Friday the team leader counts all the stickies that are in the ”Done” column on the Scrum/Kanban board (representing completed tasks) and writes the total sum on the board. This is repeated every Friday. Each sticky corresponds in our board to a sub-task of a story/feature or a bug fix. Hence, the measuring is done on the lowest level of work that we track. The data is also plotted in a graph.
2. Analyze
To be able to use the collected data for further planning, it has to be analyzed. In other words, we must understand and be able to explain the “peaks and valleys”. Likely, the capacity (throughput of completed tasks) is oscillating around an average/median value, with a few tops and bottoms. If the data represents a stable system, we can make predictions for the future.
3. Calculate metrics
To be able to forecast, the following calculations must be made on the collected data using a spreadsheet program:
- AVERAGE – The average capacity value considering all weeks.
- MEDIAN – The median capacity value considering all weeks.
- AVG DEVIATION – The average deviation in the capacity value from the AVERAGE.
- MAX (DEVIATION) – Is AVERAGE + AVG DEVIATION, to give a capacity MAX value with deviation considered.
- MIN (DEVIATION) – Is AVERAGE – AVG DEVIATION, to give a capacity MIN value with deviation considered.
4. Time plan
Usually the finish date is set in advance for a project in the time plan. Experience tells us that the capacity of the team will vary during the course of a project. Therefore, I separate the project into