Hello everyone)) I am working on the react application, where mobx is being used for the state management. Some time ago I have added such class:
class EventLogStore {
private _eventLogRecord: IEventLogRecord[];
get eventLogRecords(): IEventLogRecord {
return this._eventLogRecords;
}
add(eventLogRecord, options): void;
removeEventLogRecord(eventLogRecord): void;
}
I like that class, as it is easy to understand how to use it. However, later other developers has started to add some functionality that need access _eventLogRecords
, and class start to grow:
class EventLogStore {
private _eventLogRecord: IEventLogRecord[];
get eventLogRecords(): IEventLogRecord {
return this._eventLogRecords;
}
getSomeCustomFilter1(params): IEventLogRecords() {
}
getMsPassedFromEventAdded(): number {
return this.getMsPassedFromSomeEventAdded(DEFAULT_EVENT);
}
getMsPassedFromSomeEventAdded(event): number {
}
getSomeCustomFilter1(params): IEventLogRecords() {
}
add(eventLogRecord, options): void;
removeEventLogRecord(eventLogRecord): void;
}
From one point of view it is really seems like boilerplate job, to write functions, like
getMsPassedFromEventAdded(eventLogStore: EventLogStore): IEventLogRecords[] {
return eventLogStore.eventLogRecords ...;
},
as we can locate that function under the EventLogStore
itself to reduce amount of parameters to pass,
From another point, I really dislike that previously it was easy to understand the responsibility of the eventLogStore
, but now you scroll up/down and still miss the main responsibility of the class, and it continue growing)).
I'd like to suggest to split the functionality, e.g.
class EventLogStore {
private _eventLogRecords: IEventLogRecords = [];
private _feature1FiltersStore = new Feature1FiltersStore(this);
private _feature2FiltersStore = new Feature2FiltersStore(this);
get feature1FiltersStore(): Feature1FiltersStore;
get feature2FiltersStore(): Feature2FiltersStore;
add(eventLogRecord, options): void;
removeEventLogRecord(eventLogRecord): void;
}
// we have some kind of DI (hooks :D) that can allow to do the next
export function useFeature1Filters() {
return useEventLogStore().feature1FiltersStore;
}
I like that functionality would be grouped and the eventLogStore would cleaned up and other developers still can pass less parameters, but I'd like to discuss some questions on that solution:
- should
feature1Filters
be aprivate
field of theEventLogStore
or it should be out ofEventLogStore
- I have left it there, because it seems would be easier to navigate over the code, e.g. you openEventLogStore
and see it's business feature stores, where it is being used, however thing can become harder if any featureStore would need more dependencies. So, I'd like to extract it out fromEventLogStore
, e.g.
class EventLogStore {
private _eventLogRecords: IEventLogRecords = [];
add(eventLogRecord, options): void;
removeEventLogRecord(eventLogRecord): void;
}
class Feature1FiltersStore {
constructor(private eventLogStore: EventLogStore) {
}
}
useFeature1EventLogStore() {
}
// we have some kind of DI (hooks :D) that can allow to do the next
export function useFeature1Filters() {
return useEventLogStore().feature1FiltersStore;
}
- Does it become much harder to understand then flat functions in the
EventLogStore
? For me it seems easier, as it is easier to understand the responsibilities. - Any other alternatives?