开发者

Is there a design pattern for properties coming from different, conflicting, prioritized sources?

开发者 https://www.devze.com 2023-04-03 10:55 出处:网络
I have a bunch of properties of an object, which values are mostly boolean, but they come from different sources, different sources overriding each other.

I have a bunch of properties of an object, which values are mostly boolean, but they come from different sources, different sources overriding each other.

For example, to decide if feature X is available to a user, I have following information sources:

  • Default value for the feature, like, "Feature X is available per default"
  • User account type, like, "Feature X is available for users with account type 'Business'"
  • Country, like, "Feature X is not available in your country"
  • Per-user override, like, "Feature X is available for this user because he's cool"

For different features, the list of sources, their order and their effect on default differ, for example, feature Y cannot be overridden for an individual user, country source has priority.

Maybe I'm too bound to the current implementation, which is following:

  • Each feature is identified by a constant in the class Feature.
  • There is an array with defaults (feature X -> not available per default).
  • There are arrays for each account type (business account:feature X -> available, feature Y -> ...)
  • There is a long, long function for all the other sources, with lots of if-nesting
  • There is (or there can be) an unconditional per-user override at the end

    (select available from user_feature where user_id=1 and feature_id=X).

The question is, how do I do it right, and is there a design pattern for this? Or maybe I'm trying to be too generic and YAGNI is the answer?

What I imagine could work out:

  • A DSL to describe the effect of a source on a property, to express things like "available for this account type" and "not available in this country"
  • An ordered list of sources for each defined property
    • Default could be just another source

EDIT

Maybe my problem is the number of different properties and sources. Maybe I need an efficient data structure to hold infor开发者_如何学编程mation about properties, data sources, priorities/source order/overriding to compute every property.


"Importance, then permissive"

First, assign each source an importance. Default is the LEAST important, since it should always be overwritten.

Now, when trying to determine a permission, start with the most important source and see what it has to say. Continue until you find a source that tells you whether or not the action is allowed and use that.

You may want to have some sources be of equal importance. In this case, use the most premissive setting. If two sources of equal importance differ, where one says you can and another says you can't, then you can. (Obviously this assumes no more important sources have said you can or can't, or you would have stopped there.)

I don't know if this is a pattern so much as an algorithm.


You might want to look at the Specification Pattern for a clean way of handling a complex system of rules.

Your idea of defining a DSL for the rules may also be a good one, with the structure built by the DSL being a composite specification as described in the pattern.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号