-2

I have a scenario where user has multiple filters in a web application and a displayed list of items. In the gui it has multiple FilterGUI that he/she can tune interacting in the browser (these are React web components). Every specific implementation of the FilterGUI do the same: tune parameters and according to parameters create at runtime an arrow function that will filter (according to some algorithm/criteria) the dataset items.

Example:

i have data like this:

user {
    name: "bob",
    age: 25
    }
FilterGUI1 {
    createFilterFunction() {
         return (userSelectedInterval) => {
                      I filter user by age based on an interval selected by the user
                      }

    }
}
FilterGUI2 {
     createFilterFunction() {
          return (criteria1, criteria2 ...) => {
          i filter user item based on nested if else criteria  
          }
     }
}

It seems to me that createFilterFunction() may be replaced by a FilterFunctionFactory such that:

FilterGUI {
    this.filterFunctionFactory = new FilterFunctionFactory()

    makeFilter(someParams) {
        return this.filterFunctionFactory.makeFilter(someParams)
    }
}

I read also something about Strategy pattern. In particular that it allows selection of an algorithm’s behaviour during runtime. Can this pattern be used somehow here to modify the filterFunction produced by the factory at runtime? How would you do that ? I'm not an expert on software design patterns by i would like to write this code in a much elegant way.

UPDATE

After @BartvanIngenSchenau pointing to great article on how choosing design pattern I try to reformulate the question. Possibly avoiding to make it appear less "how to combine design patterns to write code".

I have different web components all implementing FilterGUI interface. For example FilterByAgeGUI, FilterByPriceGUI ...

interface FilterGUI {
    makeFilter(someFilterCrieria) : IFilter
}
interface IFilter {
    someFilterCriteria
    filter(someFilterCriteria, datasetNode) : boolean
}

filter method should accept someCriteria provided at runtime by FilterGUI and a datasetNode, and decide based on criteria if keeping node or not.

My question is: is there a way to have a general Filter implementing IFilter interface and change it's filter method at runtime ?

Would be bad coding something like:

interface IFilter {
    filter(FilteringFunction): boolean
}

Or i need to create a specific FilterByPrice, FilterByAge class for every IFilter implementation i would like to have in my GUI?

I cited Strategy pattern because I read it can be useful to change algorithm at runtime. Can it be used to tackle this problem? What i wouldn't like is to create dozens of FilterInSomeWay class for every GUI filtering component. Thank you.

5
  • 2
    please don't cross-post: stackoverflow.com/questions/66262419/… "Cross-posting is frowned upon as it leads to fragmented answers splattered all over the network..."
    – gnat
    Feb 18, 2021 at 15:44
  • ok, i deleted duplicate
    – c0l1n
    Feb 18, 2021 at 16:14
  • Does this answer your question? Choosing the right Design Pattern Feb 19, 2021 at 8:46
  • @BartvanIngenSchenau thank you. It partially answers my question in the sense that I asked something like: "How to fit factory or strategy into this code". The real answer has to do with dirty code and a way to clean it through those patterns. Now i try to reformulate.
    – c0l1n
    Feb 19, 2021 at 14:18
  • @BartvanIngenSchenau please check update
    – c0l1n
    Feb 19, 2021 at 14:53

1 Answer 1

0

After better introspection this was easily solved with Strategy pattern.

IFilterGui {
    makeFilter(someParams) : IFilteringStrategy
Filter {
    constructor(filterStrategy : IFilteringStrategy)
    filter(node) { 
         this.filterStrategy.filter(node)
    }
}

Concrete example:

TimeFilterGUI implements IFilterGUI {
    setStartTime()
    setEndTime()
    makeFilter() {
        return new FilterByTimeStrategy(this.startTime, this.endTime)
    }

}

FilterByTimeStrategy implements IFilteringStrategy {
    constructor(startTime, endTime)
    filter(node) {
        if (node.startTime >= startTime && node.endTime <= endTime) keep else discard
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.