Skip to content

Instantly share code, notes, and snippets.

@thieux
Last active May 30, 2017 21:39
Show Gist options
  • Select an option

  • Save thieux/96a418732ec0bc22b7253f80fd634de3 to your computer and use it in GitHub Desktop.

Select an option

Save thieux/96a418732ec0bc22b7253f80fd634de3 to your computer and use it in GitHub Desktop.

Dynamic Composite

  1. Implement a DSL with many operation like concatenate, every, and, or, etc.

Here is some usages.

With the following object:

@FunctionalInterface
interface Article {
    String name();
}

We can apply name() to a single Article.

Article a = () -> "hello";
a.name(); // "hello"

We can also apply the same operation to a composite of Article (here a list of Articles).

Article a = () -> "hello";
Article b = () -> "world";
concat(Arrays.asList(a, b)).name() // "helloworld"

The way we compose the operation is selected by apply concat.

We can extend this style to many things.

For example for boolean we may have:

@FunctionalInterface
interface Article {
  boolean isPublished();
}
Article a = () -> true;
Article b = () -> false;

every(Arrays.asList(a, b)).isPublished(); // false
atLeastOne(Arrays.asList(a, b)).isPublished(); // true

Other styles

@interface Article {
  String name();
  boolean isPublished();
  Article concat(List<Article> articles);
  Article list(List<Article> articles);
  Article every(List<Article> articles);
  Article atLeastOne(List<Article> articles);
}

Or a more monoidal way:

@interface Article {
  String name();
  boolean isPublished();
  Article concat(Article b);
  Article list(Article b);
  Article every(Article b);
  Article atLeastOne(Article b);
}

Or (applying ISP) that gives the composite (GOF):

interface Article {
  String name();
  boolean isPublished();
}
interface Articles extends Article {
  Articles concat(Article b);
  Articles list(Article b);
  Articles every(Article b);
  Articles atLeastOne(Article b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment