0

I am using typescript and angular.

I have 2 service that are very similar, but the property are different :

  synchronizedMaps: Map<string, Map<string, MapSynchSettings>> = new Map<string, Map<string, MapSynchSettings>>();
  groupDispatchers: Map<string, Subject<SynchMapGroupSubject>> = new Map<string, Subject<SynchMapGroupSubject>> ();
  mapDispatchers: Map<string, Subject<SynchMapSubject>> = new Map<string, Subject<SynchMapSubject>> ();

  public createNewSynchGroup(id?: string): Observable<SynchMapGroupSubject> {

    this.synchronizedMaps.set(id, new Map<string, MapSynchSettings>());
    this.groupDispatchers.set(id, new Subject<SynchMapGroupSubject>());
    this.mapDispatchers.set(id, new Subject<SynchMapSubject>());

    return this.groupDispatchers.get(id).asObservable();
}

and

  synchronizedDrawer: Map<string, Map<string, SynchWaypointDrawerSettings>> = new Map<string, Map<string, SynchWaypointDrawerSettings>>();
  groupDispatchers: Map<string, Subject<SynchWaypointDrawerGroupSubject>> = new Map<string, Subject<SynchWaypointDrawerGroupSubject>> ();
  waypointDispatchers: Map<string, Subject<SynchWaypointSubject>> = new Map<string, Subject<SynchWaypointSubject>> ();

  constructor() { }

  public createNewSynchGroup(id?: string): Observable<SynchWaypointDrawerGroupSubject> {
    this.synchronizedDrawer.set(id, new Map<string, SynchWaypointDrawerSettings>());
    this.groupDispatchers.set(id, new Subject<SynchWaypointDrawerGroupSubject>());
    this.waypointDispatchers.set(id, new Subject<SynchWaypointSubject>());

    return this.groupDispatchers.get(id).asObservable();
}

The property type, and the method returned value change, but the method implementation and logic of those 2 service are exactly the same.

I wanted to know if there is a method to merge those 2 service into a single one, or make a parent class that I can extend with just the variable types but all the name and logic will be kept the same.

thanks

1 Answer 1

2

One way to do this is with a generic class, where you use a type parameter for each type you want to specify later:

class GeneralThing<S, G, T> {
    synchronized: Map<string, Map<string, S>> = new Map();
    groupDispatchers: Map<string, Subject<G>> = new Map();
    subjectDispatchers: Map<string, Subject<T>> = new Map();

    public createNewSynchGroup(id?: string): Observable<G> {
        if (!id) throw new Error("What?!");

        this.synchronized.set(id, new Map());
        this.groupDispatchers.set(id, new Subject<G>());
        this.subjectDispatchers.set(id, new Subject<T>());

        return this.groupDispatchers.get(id)!.asObservable();
    }
}

In the above, I've changed the property names to something general (so just synchronized and subjectDispatchers) and used the type parameters S, G, and T.

Then you can specify the two services as

GeneralThing<MapSynchSettings, SynchMapGroupSubject, SynchMapSubject>

and

GeneralThing<SynchWaypointDrawerSettings, SynchWaypointDrawerGroupSubject, SynchWaypointSubject>

Or you could give them concrete names like

class MapThing extends GeneralThing<
  MapSynchSettings, 
  SynchMapGroupSubject, 
  SynchMapSubject
> {}

class WaypointDrawerThing extends GeneralThing<
  SynchWaypointDrawerSettings, 
  SynchWaypointDrawerGroupSubject, 
  SynchWaypointSubject
> {}

Hope that helps; good luck!

Sign up to request clarification or add additional context in comments.

1 Comment

I was thinking something like that, I didn't know I could do it on many different types, definitely the solution thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.