Martin Fowler's Blog, page 31

November 30, 2015

Role of an Enterprise Architect in a Lean Enterprise



Many software projects that use agile and lean approaches have difficulties with
enterprise architects, whose role changes significantly in this context. Kevin
Hickey has been working with enterprise architecture groups with our clients and
shares his observations on how enterprise architects can engage successfully in this
context by building a vision and building bridges between groups to help realize
that vision.

 •  0 comments  •  flag
Share on Twitter
Published on November 30, 2015 06:14

November 21, 2015

photostream 92





Brattleboro, VT

 •  0 comments  •  flag
Share on Twitter
Published on November 21, 2015 10:18

Lightroom Lua script to select a repeating annual date range

I need to find all the photos that I've taken in November over the last few
years. I can't express this query easily in Lightroom, so I figured out how to write
a Lua script that would make this query. These notes describe what I did, as someone
who had never before programmed with Lua, nor used the scripting environment in
Lightroom.

 •  0 comments  •  flag
Share on Twitter
Published on November 21, 2015 09:08

November 19, 2015

Second installment of refactoring code into data



I now move onto the second, more awkward, section of the
imperative code to refactor to an adaptive model. This shows how
I need to massage both the imperative code to make it fit the
model's structure better, and the model to support more
capabilities. I then finish by comparing the imperative and
active model approaches.

 •  0 comments  •  flag
Share on Twitter
Published on November 19, 2015 07:38

November 11, 2015

Refactoring Code into Data



Our regular programming languages are where we usually like
to keep our logic, but there are times when it's useful to embed
logic into a data structure. Logic in a JSON file can remove
duplication when that same logic has to run on multiple
platforms that use different languages. This essay looks at how
to refactor logic from imperative code into such a data structure.

 •  0 comments  •  flag
Share on Twitter
Published on November 11, 2015 07:55

October 31, 2015

photostream 91





Bristol, VT

 •  0 comments  •  flag
Share on Twitter
Published on October 31, 2015 02:34

October 19, 2015

Remote versus Co-located Work



In the software industry we hear a lot of discussion about
the pros and cons of remote work, and a recent outbreak of that
finally got me to write my thoughts down. I point out that
there's distinct patterns of remoteness, which yield different
trade-offs and varied techniques to make them work. I recognize
that we lack any conclusive evidence on effectiveness, but sense
that most people are more productive when co-located, but even
so organizations can build more productive teams with a remote
working structure.

 •  0 comments  •  flag
Share on Twitter
Published on October 19, 2015 06:37

October 17, 2015

photostream 90





Istanbul, Turkey

 •  0 comments  •  flag
Share on Twitter
Published on October 17, 2015 08:17

October 13, 2015

Refactoring Module Dependencies



As a program grows in size it's important to split it into
modules, so that you don't need to understand all of it to make a
small modification. Often these modules can be supplied by
different teams and combined dynamically. In this refactoring
essay I split a small program using Presentation-Domain-Data
layering. I then refactor the dependencies between these modules
to introduce the Service Locator and Dependency Injection
patterns. These apply in different languages, yet look different,
so I show these refactorings in both Java and a classless
JavaScript style.

 •  0 comments  •  flag
Share on Twitter
Published on October 13, 2015 06:46

October 12, 2015

Bliki: RequiredInterface

A required interface is an interface that is defined by the
client of an interaction that specifies what a supplier component needs to do so
that it can be used in that interaction.



A good example of required interface is an interface commonly
referred to as “comparable”. Such an interface is usually required
by a sort function. Imagine I have a set of albums, and I want to
sort them by title, but ignoring articles such as "The", "A", and
"An". I can arrange them to be sorted in this way by implementing
the required interface for any sort functions.





In Java it would look
something like this.



class Album...



public class Album implements Comparable<Album> {
private String title;

public Album(String title) {
this.title = title;
}
public String getTitle() {
return title;
}

@Override
public int compareTo(Album o) {
return this.sortKey().compareTo(o.sortKey());
}
private String sortKey() {
return ignoreSortPrefixes(title).toLowerCase();
}
private static String ignoreSortPrefixes(String arg) {
final String[] prefixes = {"an", "a", "the"};
return Arrays.stream(prefixes)
.map(s -> s + " ")
.filter(s -> arg.toLowerCase().startsWith(s))
.findFirst()
.map(s -> arg.substring(s.length(), arg.length()))
.orElse(arg)
;
}

In this case Comparable is the required interface of
the various Java sort functions. More complicated examples can have
a richer interface with several methods defined on it.



Often people think about interfaces as a decision by the supplier
about what to expose to clients. But required interfaces are
specified (and often defined) by the client. You often get more
useful interfaces by thinking about what clients require - leading
towards thinking about RoleInterfaces.





Using an Adapter

A common problem comes up if I want to plug together two modules
that have been defined independently. Here we can run into
difficulties even if we get names that match.



Consider a task list with a required interface of tasks.



class TaskList...



private List<Task> tasks;
private LocalDate deadline;
public LocalDate latestStart() {
return deadline.minusDays(tasks.stream().mapToInt(t -> t.shortestLength()).sum());
}
}


interface Task…



int shortestLength();


Let's imagine I want to integrate it with an Activity
class I got from a different supplier.



class Activity…



public int shortestLength() {



Even though the activity has a method whose signature happens to match the
required interface's, I (rightly) can't create a
task list of activities because the type definitions don't match. If
I can't modify the activity class I need to use an adapter.



public class ActivityAdapter implements Task {
private Activity activity;

public ActivityAdapter(Activity activity) {
this.activity = activity;
}
@Override
public int shortestLength() {
return activity.shortestLength();
}
}


In the software world we use the term adapter pretty freely, but
here I'm using strictly in the sense of the Gang of
Four book
. In this usage an adapter is an object that maps one
object to the required interface of another.





In this case, I don't need an adapter if I'm using a dynamic
language, but I do if the activity class used a method with a
different signature.





Acknowledgements

Alexander Zagniotov and Bruno Trecenti commented on
drafts of this post.




Share:


if you found this article useful, please share it. I appreciate the feedback and encouragement
 •  0 comments  •  flag
Share on Twitter
Published on October 12, 2015 06:16

Martin Fowler's Blog

Martin Fowler
Martin Fowler isn't a Goodreads Author (yet), but they do have a blog, so here are some recent posts imported from their feed.
Follow Martin Fowler's blog with rss.