2

Say I have a TypeScript class:

export class TypeCreator {

  entities: Set<Whatever>

  registerEntities(e: Set<Whatever>): Set<Whatever>{
    return this.entities = e;
  }
}

if registerEntities() should only be called once, should I throw an error if they call it twice, or just overwrite the value, or is this a code smell that can be handled a different way, perhaps with a less stateful pattern?

  • 1
    Sharing your research helps everyone. Tell us what you've tried and why it didn't meet your needs. This demonstrates that you've taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer. Also see How to Ask – gnat Nov 27 '18 at 21:18
  • Should only be called once per object instance or per program execution? – Tomas Zubiri Nov 29 '18 at 6:42
  • Please use names for real word things instead of abstract names ( Type, entity, whatever) where you can. If possible, use the names of things you are working on, if this is not possible or is too complex for us, try to create a metaphor with similar examples (cars, seats,wheels,vehicle) . This is important because you don't yet know what the right level of abstraction is, we will help you figure out. – Tomas Zubiri Nov 29 '18 at 6:44
  • Why should it be write once? If its in the global scope, you already have sharing issues. If its in a local function, just don't write it twice. – Kain0_0 Nov 29 '18 at 7:56
  • @Kain0_0 it's for a library, users don't always know, jfc – MrCholo Nov 29 '18 at 8:36
10

In cases like this, I try to be more precise on naming the methods.

  • setFoo() sets, but can be called many times.
  • addFoo() adds to the existing data. (To me, your "register" fits in here.)
  • putFoo() is a Java convention, meaning "add but do not duplicate if it is already there".
  • initFoo() sets but should only be called once. If called twice it can return an error status or throw an Exception.
8

Disclaimer: this recommendation comes from a Java background, so I don't know if it fits into the TypeScript world as well:

You can make the TypeCreator immutable, by eliminating the registerEntities() method and introducing only one constructor that accepts the entities at object creation time.

This not only makes it impossible to set the entities multiple times, but also avoids the useless object state between being created and being populated with entities: as soon as you have a TypeCreator object, it's completely initialised and ready for use.

  • 3
    I was going to add this to my answer but also wasn't sure if it fit into TypeScript. But excellent point. The best way to make it clear that something needs to be done exactly once is to put it in the constructor. – user949300 Nov 28 '18 at 20:17
  • In this case I have a specific desire to return the value from the method tho, unfortunately constructor can't do that. – MrCholo Nov 29 '18 at 2:25
0

One way to solve this would be to use a map:

export class TypeCreator {

  entitiesMap: Map<string,Set<Whatever>>

  registerEntities(namespace: string, e: Set<Whatever>): Set<Whatever>{
    this.entitiesMap.set(namespace,e);
    return e;
  }
}

but then that requires someone to provide a key/namespace to retrieve that value.

0

You may be looking for a Singleton. It's a very common design pattern. I've never used TypeScript, so I found a link that shows how to create a Singleton in TS.

https://fullstack-developer.academy/singleton-pattern-in-typescript/

A Singleton ensures that there is only one instance.

0

Is this a method that also must be called? If so then I suggest the code and params belong in the constructor. Init methods are a code smell. (Different from factory methods that are static and return a configured instance). Constructors are perhaps exactly what you are seeking—a section of code that is execute once and results in a configured instance ready for use.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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