8

I was recently considering that sometimes several objects depend on each other (e.g. if they contain cyclic references) and therefore it would be useful to create them as part of one atomic operation that makes sure that, after construction, the new objects fulfil some collective constraint.

In order to do this one could have constructors that can create more than one object. The programmer would then put in a single constructor all the code ensuring that, once objects o1, ..., on have been created, they satisfy all required constraints (e.g. all links between the new objects are already in place). I have made up the term collective constructors myself because I have never heard of such a feature, but there might well exist an accepted name for this concept.

So, is there any programming language supporting this kind of constructors? If not, has the idea been tried out already?

  • 3
    I'm not sure, but the first thing that comes to my mind is the factory pattern. – JensG Jan 13 '14 at 21:57
  • 3
    Can the voter please explain the close vote? I am asking if there exists a programming language with a very specific feature. The question does not seem to be off-topic or poorly formulated to me but I am open for feedback. – Giorgio Jan 13 '14 at 21:58
  • @JensG: I thought about that, but a factory has some limitations. For example, if an object contains an immutable reference, you cannot set it in a factory: you can only set it in the constructor. I am considering the Java semantics here, but I think this can be a general problem. – Giorgio Jan 13 '14 at 22:00
  • This is interesting since I'm hacking something similar in C# using IoC containers currently. Also, how does this differ from languages that have traits and allow those traits to be mixed to fill abstract members? A toy language I worked on supported A with B style type composition, whose resultant constructor would essentially build the new type composed of the two traits. – Telastyn Jan 13 '14 at 22:03
  • 3
    This question is clearly not "asking us to recommend a tool, library or favorite off-site resource" and it is an embarrassment to the site that two people have voted to close it as doing so. I have rephrased the title slightly to make this even clearer. – Carson63000 Jan 14 '14 at 7:24
12

This sounds like the Builder Pattern to me, which is a more complex form of a Factory. One Java example is a StringBuilder, which you use to build up a String, then call builder.toString() when you want the immutable result. However, you can use the builder pattern to build more complex non-homogenous collections of objects. You could use friend semantics in a builder to get access to private variables that would be considered immutable after the result object is created.

Functional languages might provide some inspiration. Scala, for example, has a mutable ListBuffer that can be used for the building stage, then converted to an immutable List.

Another possibly relevant concept is Freezable Objects, by which an object is considered mutable until a Freeze() method is called on it. A builder could use the unfrozen objects, then freeze them before returning.

  • I find the idea of a builder pattern in combination with freezable object very good. It is not exactly what I had in mind but it solves my problem without introducing a new ad-hoc concept, which is IMO good. – Giorgio Jan 14 '14 at 20:55
  • +1: Eric Lippert had series of articles concerned immutable objects and called one of variations of "freezable" objects Popsicle immutability (convenient search term to find the articles :) ) - whole series may be useful to read if you are into constructing complex immutable objects in C#-like language. – Alexei Levenkov Jan 15 '14 at 2:16
4

Ruby, Smalltalk, Self, Newspeak etc. don't have constructors, they just have a naming convention for factory methods (e.g. new in Ruby). Since they are just bog standard methods like any other method, they can do anything they want, including allocating and initializing as many objects as they want. The main problem is that such factory methods return, by convention, a single object that is an instance of the class the factory method was called on. I.e. when calling Foo.new it is expected that you get back a single object which is an instance of Foo. But, with sufficient documentation, you could return some structure (e.g. an Array) of multiple new objects.

Example:

class Foo
  def self.new
    new_foo = super

    new_bar = Bar.new
    new_bar.foo = new_foo

    new_foo.bar = new_bar

    return new_foo, new_bar
  end

  attr_accessor :bar
end

class Bar
  attr_accessor :foo
end

foo, bar = Foo.new

In ECMAScript, constructors are just regular procedures, or rather, any procedure can be used as a constructor just by sticking the new keyword in front of it. Again, since they are just regular procedures, they can do anything they want.

1

(e.g. if they contain cyclic references) [...] In order to do this one could have constructors that can create more than one object. The programmer would then put in a single constructor all the code ensuring that, once objects o1, ..., on have been created,

Cyclic dependencies between the objects? Then the answer is "don't use (just) a constructor", because cyclic method calls don't make any sense. Instead, this is a classic scenario for some Factory methods.

Here's an example (in PHP) which is sort of silly but illustrates the general idea: You cannot create a Sprocket without an associated Widget, and vice-versa. Each object has a reference to the other when it becomes available.

class Widget {            
    protected $sprocket = null;
    public function getSprocket(){ return $this->sprocket; }

    protected function __construct(){ 
        // Constructor cannot be called from outside, not public
        // Initialize self, to a limited degree
    }
    public static function create(Sprocket $partner=null){
        $me = new Widget(); // Can call constructor from same class

        // Here we can make all sorts of changes and additions and other
        // objects, wiring them all together, before revealing the result
        // to the outside world.

        if($partner !== null){
            $me->sprocket = $partner;

        }else{
            $me->sprocket = Sprocket::create($me);
        }
        return $me;
    }

}

/* 
 * Practically identical to Widget, just with some renaming
 */
class Sprocket {
    protected $widget = null;
    public function getWidget(){ return $this->widget; }

    protected function __construct(){  }
    public static function create(Widget $partner=null){            
        $me = new Sprocket();            
        if($partner !== null){
            $me->widget = $partner;
        }else{
            $me->widget = Widget::create($me);
        }
        return $me;
    }        
}

/* 
$mw = new Widget(); // NOT ALLOWED! Constructor not public
*/

$w = Widget::create(); // OK to call
$s = $w->getSprocket();
$w2 = $s->getWidget();

assert($w == $w2);

If I had to do this in PHP 5.2 in real life, I'd simply just leave the constructors public, and tell people not to use them. Instead I'd have a makeWidgetWithSprocket() function. If the language was Java, I'd use its package-level visibility controls to further prevent mistakes.

Additional reading:

  • If you want to pass lots of options and settings to create(), consider the Builder pattern.
  • If you find yourself needing a lot of flexibility to rewire things in different ways, look at Inversion of Control frameworks, which commonly (but not always) use dependency injection to connect objects together "from the outside".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.