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.