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.