Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's this java pattern called?

I'm wondering what the following pattern is called, if it has a name at all.

Purpose

Store data that is associated with an object (MyObject), but that is private to an implementation of an interface that deals with that object. Clients of the object have no business looking at this data.

Alternatives

Some alternatives are

  1. a WeakHashMap<MyObject, FooApiMyObjectAttachment> maintained in the implementation of the interface,
  2. using subclassing and factories everywhere the value is created, so that the extra data can be stored in the subclass or
  3. using subclassing and accepting both MyObject and subclasses in the API.

Code example

public interface MyApi {
  void doSomething(MyObject x);
}

public class MyObject {
  public interface Attachment {} // empty interface, type bound only
  private Attachment attachment;
  public void setAttachment(Attachment attachment) {
    this.attachment = attachment;
  }
  public <T extends Attachment> T getAttachment(Class<T> type) {
    return type.cast(attachment);
  }
}

class FooApiMyObjectAttachment implements MyObject.Attachment {
  Foo foo; // some data that one MyApi implementer `foo' wants to persist between calls, but that is neither needed nor desired on MyObject 
}

class BarApiMyObjectAttachment implements MyObject.Attachment {
  Bar bar; // some data that another MyApi implementer `bar' wants to persist between calls, but that is neither needed nor desired on MyObject
}

class FooApi implements MyApi {
  // associates FooApiMyObjectAttachment with any MyObjects passed to it or created by it
}

class BarApi implements MyApi {
  // associates BarApiMyObjectAttachment with any MyObjects passed to it or created by it
}

Compared to subclassing, the advantage is that no factories are needed for MyObject, just so that implementers of MyApi can associate extra data with the objects.

Compared to a WeakHashMap in the implementers, a disadvantage is two methods on MyObject that aren't useful to clients, but an advantage is the simplicity.

A nice property of this pattern is that you can generalize it to store any number of attachments of different types with each node by changing the field to Map<Class<?>, Attachment> attachments, which cannot be done with subclassing at all.

I've seen the generalized form used successfully to annotate tree nodes in a tree rewriting system with various data used by various modules that processed the nodes. (c.f. pointers to parent nodes, origin information)

Question

Does this pattern have a name? If so, what is it? Any references?

like image 580
Tobi Avatar asked Nov 02 '22 11:11

Tobi


2 Answers

It looks like a structural pattern, very close derivation from Whole-part, or composite.

Looking for a reference online, an overview of Whole-Part:

Sometimes called Composite

Helps with the aggregation of components (parts) that together form a semantic unit (whole).

Direct access to the Parts is not possible

Compose objects into tree structures to represent part-whole hierarchies. Whole-Part lets clients treat individual objects and compositions of object uniformly

Composite Pattern

Really the difference between what you are doing and the composite is that you are storing non-composites, so you don't get the tree structure that composites would allow, but a UML would look similar just without the pigs ear.

like image 54
kmchugh12 Avatar answered Nov 15 '22 05:11

kmchugh12


Found it!

The form where multiple attachments are possible (Map<Class<?>, Attachment> attachments) is described by Erich Gamma as the Extension Objects Pattern.

like image 22
Tobi Avatar answered Nov 15 '22 04:11

Tobi