Qual è lo schema appropriato per un framework applicativo estendibile?

1

Ho creato un framework applicativo di base specifico per un dominio per una GUI basata sul web. Il framework fornisce Annulla / Ripristina di 'Operazioni', persistenza e altre funzionalità specifiche del dominio. Ora sto cercando di impacchettare la funzionalità principale non specifica del dominio per riutilizzarla in altri progetti.

Ho una classe ApplicationFramework simile a questa (Typescript):

export class ApplicationFramework {

  constructor() { }

  private transactionWrapper(fn) {
    // ...
  }

  operation(operation: IOperationConstructor, params: any): IOperation {

    // ...

    const me = this;
    let op;
    this.transactionWrapper(function (data) {
      op = new operation(me, data, params);
      if (!op.apply()) {
        op.cancel();
      }
    });

    // ...

    return op;
  }

}

E ho alcune interfacce e una classe astratta per Operations che assomiglia a questo:

export type Map = Immutable.Map<any, any>;

export interface IOperation {
  resultMessage: string;
  apply(): boolean;
  cancel(): void;
}

export interface IOperationConstructor {
  new(doc: ApplicationFramework, map: Map, params: any): IOperation;
}

export abstract class Operation implements IOperation {

  protected doc: ApplicationFramework;
  protected map: Map;
  protected params: any;

  abstract resultMessage: string;

  constructor(doc: ApplicationFramework, map: Map, params: any) { }

  abstract apply(): boolean;

  abstract cancel(): void;

}

Come nota a margine, all'interno di una singola implementazione, ci dovrebbe essere 1 definizione di ApplicationFramework e 1 o più definizioni per Operation . Ad esempio, potrebbero esserci operazioni come "MoveObject", "RenameEntity", "ModifyShape", ecc. Ciascuna estraendo Operation .

La mia intenzione è di rendere l'intero framework estendibile ad altri domini. A questo proposito, il mio approccio attuale è che sia le classi ApplicationFramework che Operation siano estese per supportare casi d'uso specifici per dominio.

Sono preoccupato che io stia usando un anti-pattern. Come puoi vedere, la classe astratta Operation dipende da ApplicationFramework . Questo non è corretto, dato che ApplicationFramework e Operation dovrebbero essere entrambi estesi e quindi le classi derivate di Operation richiedono una classe derivata di ApplicationFramework , non ApplicationFramework stessa. Ho preso in considerazione la creazione di un'interfaccia IApplicationFramework da utilizzare in questo caso, ma ciò non sembra ancora corretto.

Ho 2 domande:
1) Pensi che sia una cattiva idea generalizzare la mia struttura in questo modo?
2) In caso contrario, puoi consigliare un particolare schema / approccio a questo problema?

Apprezzo qualsiasi considerazione.

- Modifica -

Ho deciso di procedere con questo approccio. Ho creato il membro doc dell'estratto di classe Operation , pertanto le classi derivate devono definire la propria implementazione di doc :

export abstract class Operation implements IOperation {

  protected abstract doc: ApplicationFramework;
  protected map: Map;
  protected params: IOperationParameters;

  abstract resultMessage: string;

  constructor(doc: ApplicationFramework, map: Map, params: IOperationParameters) { }

  abstract apply(): boolean;

  abstract cancel(): void;

}

Implementazione:

class AFImpl extends ApplicationFramework {
  constructor() {
    super();
  }
  AddEntity(map: Map, entity: any) {
    // do stuff
  }
}

class OpImpl extends Operation {
  resultMessage = 'the result';
  doc: AFImpl;
  constructor(doc: AFImpl, map: Map, params: IOperationParameters) {
    super(doc, map, params);
    this.doc = doc;
  }
  apply(): boolean {
    this.doc.AddEntity(this.map, {});
    return true;
  }
}

Sono ancora curioso di sentire qualsiasi opinione su questo se sei incline a condividere.

    
posta eric sherouse 25.01.2018 - 22:21
fonte

0 risposte