admin管理员组文章数量:1302406
I have a system where multiple consumers (e.g., pricing calculators) process requests based on specific constraints. Each consumer has different requirements, meaning they only need a subset of the available data. For example:
- Consumer A relies heavily on one particular field.
- Consumer B has constraints related to the same field as Consumer A plus an other one.
- Consumer C ignores most fields but considers another aspect important.
- Consumer D rejects certain requests outright based on a condition.
Eg:
public interface IRequestProcessor
{
double ComputeResult(RequestData request);
}
class ConsumerA : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> 10 * request.SomeValue + request.BaseCost;
}
class ConsumerB : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> (request.SomeCondition ? 10 : 0) * request.SomeValue + request.BaseCost;
}
class ConsumerC : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> request.HasDetail ? 1.5 * request.BaseCost : request.BaseCost;
}
class ConsumerD : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> request.DueDate < DateTime.Now.AddMonths(6)
? -1
: request.HasDetail ? 1.5 * request.BaseCost : request.BaseCost;
}
And the RequestData
class:
class RequestData
{
public double BaseCost { get; } // Used by all Consumers
public double SomeValue { get; } // Used by Consumer A & B
public bool SomeCondition { get; } // Used by Consumer B
public bool HasDetail { get; } // Used by Consumer C & D
public DateTime DueDate { get; } // Used by Consumer D
}
Each time that I add a new consumer, I need to modify RequestData
to introduce new fields. This leads to:
- Growing complexity : The
RequestData
class keeps expanding. - Unused data : Most consumers only require a subset of the fields, making it inefficient.
==> How can I modelize this system so that it fill a better design ?
Although my current implementation is in C#, I welcome any general design pattern or architectural approach to solve this issue.
I have a system where multiple consumers (e.g., pricing calculators) process requests based on specific constraints. Each consumer has different requirements, meaning they only need a subset of the available data. For example:
- Consumer A relies heavily on one particular field.
- Consumer B has constraints related to the same field as Consumer A plus an other one.
- Consumer C ignores most fields but considers another aspect important.
- Consumer D rejects certain requests outright based on a condition.
Eg:
public interface IRequestProcessor
{
double ComputeResult(RequestData request);
}
class ConsumerA : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> 10 * request.SomeValue + request.BaseCost;
}
class ConsumerB : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> (request.SomeCondition ? 10 : 0) * request.SomeValue + request.BaseCost;
}
class ConsumerC : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> request.HasDetail ? 1.5 * request.BaseCost : request.BaseCost;
}
class ConsumerD : IRequestProcessor
{
public double ComputeResult(RequestData request)
=> request.DueDate < DateTime.Now.AddMonths(6)
? -1
: request.HasDetail ? 1.5 * request.BaseCost : request.BaseCost;
}
And the RequestData
class:
class RequestData
{
public double BaseCost { get; } // Used by all Consumers
public double SomeValue { get; } // Used by Consumer A & B
public bool SomeCondition { get; } // Used by Consumer B
public bool HasDetail { get; } // Used by Consumer C & D
public DateTime DueDate { get; } // Used by Consumer D
}
Each time that I add a new consumer, I need to modify RequestData
to introduce new fields. This leads to:
- Growing complexity : The
RequestData
class keeps expanding. - Unused data : Most consumers only require a subset of the fields, making it inefficient.
==> How can I modelize this system so that it fill a better design ?
Although my current implementation is in C#, I welcome any general design pattern or architectural approach to solve this issue.
Share Improve this question asked Feb 10 at 19:43 TotoToto 7,71919 gold badges51 silver badges72 bronze badges 8 | Show 3 more comments1 Answer
Reset to default 0I like Jeremey Lakeman's suggestion of generics.
You could also try consumer-specific derivatives:
abstract class RequestData {
public double BaseCost { get; } // Used by all Consumers
}
class ConsumerARequestData : RequestData{
public double SomeValue { get; } // Used by Consumer A & B
}
class ConsumerBRequestData : ConsumerARequest {
public bool SomeCondition { get; } // Used by Consumer B
}
class ConsumerCRequestData : RequestData {
public bool HasDetail { get; } // Used by Consumer C & D
}
class ConsumerDRequestData : ConsumerCRequestData {
public DateTime DueDate { get; } // Used by Consumer D
}
However, the cost of this approach is that you have to cast to the specific type in each implementation:
class ConsumerD : IRequestProcessor
{
public double ComputeResult(RequestData request) {
var requestData = (ConsumerDRequestData) request;
// ...
}
}
本文标签: cHow to avoid expanding a Request class when adding new consumersStack Overflow
版权声明:本文标题:c# - How to avoid expanding a Request class when adding new consumers? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741694024a2392899.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
IRequestProcessor<T>{ double ComputeResult(T request); }
but even that smells. – Jeremy Lakeman Commented Feb 11 at 0:36RequestData
with a need property. As result : 1/ every consumer now sees this property that is useless for them 2/ this leads to confusion 3/ there is potential unwanted side effect 4/ what if a data needs to be hidden to others consumer ? 5/ what if a consumer need to change an int property into double ? – Toto Commented Feb 12 at 1:03RequestData
class? What is the problem to define a request data class per request processor? – Peter Csala Commented Feb 17 at 15:08void HandleIncomingRequest(Request request){ var minPrice = this.processor.Min(p=>p.ComputeResult(request));)}
– Toto Commented Feb 17 at 19:16