Search code examples
javafactorynaming

When a class or interface acts as its own factory, are there conventions / best practices for choosing the name of the factory method?


My question might be a special case of this more general one, but the answers there don't apply to my case (and say that it's context dependent).

Consider the case, where an interface or a class act as their own factory. Examples would be in Java 8 the interface Stream with the static method of(...) and the class Optional with the static method of(...). Although I don't yet use Java 9, I've seen that there also the interfaces List, Set, and Map have obtained static factory methods of(...) or ofEntries(...) for the latter. They all seem to create immutable objects from all the entries passed as arguments.

For my own classes, I'm using frequently the name from(otherObject) to create a new object out of a similar object, but I haven't seen this naming used elsewhere. Originally I was tempted to use of(otherObject), if the other object will become a member of the new object, and changes to the otherObject will affect the new one, and from(otherObject), if I only take information out of the other object at construction time and changes to the other object won't affect the new object. But according to my examples in the beginning, it seems, that the name "of(...)" is reserved for the creation of immutable objects.
So my concrete questions would be:

  1. has anyone seen from(...) being used in JDK packages as a creator method/factory method, and if so, with what precise meaning?
  2. how could I best express with the name of the creator method/factory method the distinction between the case where the new object will depend on changes of the related object used for construction and the case where it doesn't depend on such changes?

BTW, my idea about using from() and of() stems from the fact, that in the other direction (the class or object being a factory for another class, using an instance of this class as information for the creation) some objects have methods containing "to" (e.g. List#toArray()) to create a new object, not depending on changes of the old, and "as" (e.g. Arrays.asList(...)), when the new object will depend on changes of the old.

Edit: after writing this question, I realized that my intended use of "of" does not contradict the immutability usage I referred to. E.g. in the example of the List, the argument(s) of the creator method of(E... elements) is not another List (which would correspond to my intended use case), but the entries of the List. And the immutability means that all these references to the entries cannot be changed. But changes to every entry-object (not their reference) will clearly affect the new List (see here in the java-docs). If List had another creator method ofList(List anotherList), then it would only be logical, that the reference to anotherList is kept and changes in the old list are seen in the new one. So I think I'm settled with using "of" in this case. If people agree, the remaining question would thus be, if "from" is appropriate for the case, where no reference to the original object is kept.


Solution

  • There is heavy use of "from" for Datetime API, like Instant#from(TemporalAccessor), LocalDate#from(TemporalAccessor). It is quite interesting that, those class also use "of" like LocalDate#of(int, int, int).


    By observing and comparing difference cases, IMO, different between from and of is:

    Is all data in the parameter used to construct the object?

    "from" is used when the created object is extracting data from the parameter, where "of" use all data from the parameter.

    So when we have A a = A.of(b), it usually means b can be deduced from a, which is not possible for the case A a = A.from(b).