简体   繁体   中英

is this a design pattern?

i have to build some financial data report, and for making the calculation, there are a lot of 'if then' situations: if it's a large client, subtract 10%, if it's postal code equals '10101', add 10%, if the day is on a saturday, make a difficult calculation etc.

so i once read about this kind of example, and what they did was (hope i remember well) create a class with some base info and make it possible to add all kinds of calculationobjects to it.

So to put what i remembered in pseudo code

Basecalc bc = new baseCalc();
//put the info in the bc so other objects can do their if
bc.Add(new Largecustomercalc());
bc.Add(new PostalcodeCalc());
bc.add(new WeekdayCalc());

the the bc would run the Calc() methods of all of the added Calc objects. As i type this i think all the Calc objects must be able to see the Basecalc properties to correctly perform their calculation logic.

So all the if's are in the different Calc objects and not ALL in the Basecalc.

does this make sense?

I was wondering if this is some kind of design pattern?

As dtb suggested, Chain of Responsibility seems most applicable here, with a slight variation: Typically, Chain of Responsibility finds exactly one handler , then exits. If a large customer ordered on Saturday, you'd need to execute two handlers. Note that doing so is a non-trivial extension, because your object might have changed in the mean time and the ordering of handlers becomes relevant. This can be very tricky. Eg what if there is a $10 discount and a 10% discount? Now the order of operations makes a difference, unless both work on the original price. You get the idea I guess.

It is important to realize that design patterns aren't clear-cut, so there is typically not the one correct answer. Still I believe this is very close to Chain of Responsibility and further from the other patterns that have been mentioned.

First, it is desirable to have concrete implementations perform the check whether they are actually applicable to the item at hand, which is typical for Chain of Responsibility.

Secondly, what you need will behave differently depending on the actual data in your object. The Strategy pattern simply encapsulates different algorithms that essentially achieve the same thing (ie you could have different strategies to calculate a 10% discount, but they should all yield the same value).

The Command pattern is a decoupling pattern for the actual request to perform an operation, eg if you wanted to have somebody else calculate the discount, you'd spawn a Command object for that. In fact, the handlers of (multicast) events are often Chains of Responsibility .

The Composite pattern is made for tree-like structures where you can compose objects much like you would in the real world. This is related to the issue mentioned before: If you represent your Chain of Responsibility as a degenerate subtree (without branches), you'll have an ordered list and you can represent the difference between subtract $10 first, then 10% or the other way around. In this sense, it could be understood as a highly degenerate Composite. The Composite could be used to describe a specific discounting scheme. Still, selecting and applying the scheme would be Chain of Responsibilities' job.

Like I said, these are not clear-cut terminologies, they are strongly related to each other, often found in variations (and in abuse) and, most importantly, every pattern needs some alterations for your specific problem. Still, I'd prefer to stick to the terminology of Chain of Responsibility with a few variations, because I believe it's closest to the situation you describe.

Seems like the Strategy pattern for me. Mixed with the Composite pattern perhaps, as you can add the Calculation implementations to your object.

There seem to be two patterns at work there, depending on what you're looking at. If you're talking about the work delegation to a list of items via a standard "calculate" method, then that's an example of Command pattern . If you're talking about the implementation of the calculator classes, that's Decorator pattern .

It is not chain of responsibility, chain of responsibility has a complete different purpose. It is a combination of command pattern (without undo/redo) and composite (composing commands). As others pointed out you can also consider it being part in a Strategy, but again it is to degenerated for being a good example for a Strategy. Some people would perhaps call it an "internal DSL". As most people pointed out: you can not really define what it is, as it depends on your point of view. If your calculations had more than one method and the traversal algorithm would call all of them - or a subset depending on the operants eg - it would be Strategy, the only thing that is certain is the "Composite".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM