3

I am developing a solution which is similar to railway ticketing.

Context : 18 Railway Stations from Tamil Nadu are given. A passenger needs a ticket. For upto 5 stations journey, the fare is Rs.10. After the 5 stations, for every 5 stations, 5 Rs extra will be charged. For the full stretch journey i.e. From 1st to the last station, fare is Rs. 20.

e.g.

Input 1 : StationFrom - Guindy, StationTo - Kadambakkam
Output 1 : Print ticket. i.e. StationFrom : Guindy, StationTo : Kadambakkam, Total Stops : 3, Total Fare : 10

Input 2 : StationFrom - Guindy , StationTo - Chennai Fort
Output 2 : Print ticket. i.e. StationFrom : Guindy, StationTo : Chennai Fort, Total Stops : 8, Total Fare :15

In future, more business rules on fare calculation can be added.

The question is, which design patterns would be correct choice in the fare calculation?

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
Free Coder
  • 459
  • 4
  • 19

3 Answers3

6

Strategy pattern also suits your requirement. You can define multiple strategy classes for 5, 10, 20 station fares. Depending on count of stations, you can load corresponding strategy. You can have factory method to create fare objects first. Strategy + Factory method + Builder combo works for you.

  1. BaseFareRule, AgeRule, StationsRule, DistanceRule, FestivalRule are core Strategies(interfaces)

  2. And each of these strategies will have concrete implementations. Getting a particular strategy like FiveStation or TenStation strategy uses FactoryMethod pattern. Even you can have multiple FiveStation strategies and can change the implementation dynamically through rule configuration. Strategy is best fit for this type of requirement.

  3. FareRuleBuilder is a builder class, with many set of configured rules using Composition pattern.

Irrespective of Decorator Or Strategy, Rules will be interfaces. Builder & FactoryMethod are required in both solutions.

You can use either Decorator Or Stretegy in your solution ( A problem can have multiple solutions) but I prefer Strategy, which is core component for of Fare Calculation

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
  • refer this question for strategy vs decorator : http://stackoverflow.com/questions/4354611/when-and-how-strategy-pattern-can-be-applied-instead-of-decorator-pattern – Ravindra babu Aug 12 '15 at 10:45
1

I recommend you Decorator Pattern

You have the default Price class and its Price interface, then you create the decorator interface that inherits from Price interface. All combinations would be subclasses of the decorator interface.

blashser
  • 921
  • 6
  • 13
  • With strategy you must create a class for each trip combination. However with decorator, you create classes when new feature/discount is needed. This mean few classes and the different combination are done by composition. – blashser Aug 12 '15 at 10:21
  • Even Decorator needs new class & Strategy needs new class if you add a new fare. One problem can have multiple solutions. – Ravindra babu Aug 12 '15 at 10:44
  • In future, if the business requirement comes as, Apply applicable business rules for Fare, and also check Age i.e. For Age < 5Yrs OR senior citizens, Fare would be half. If another Business Rule comes e.g. 20% Fare cut in the summer season, along with other applicable Business Rules. Then in that case, would the Strategy Pattern be correct or Decorator pattern? – Free Coder Aug 12 '15 at 11:01
  • You can do it the way you think that it will be simpler. But if you start mixing businesses rules, I still think decorator would be a bit better. – blashser Aug 12 '15 at 13:08
  • @blashser Why do you think Decorator will be bit better than Strategy? – Free Coder Aug 12 '15 at 18:09
  • If you want to mix some of the business rules, you would have to create a new strategy for each combination that you imagine. However, any kind of imaginable combination is done dynamically in runtime with decorator pattern. I see strategy more appropriate when you are thinking in algorithms predetermined. But again, both are possible but I see more flexible for this issue the decorator. – blashser Aug 12 '15 at 18:29
1

Strategy Pattern will work in this situation. So, You have one strategy like based on stop count you decide, how much fare should be.If later your strategy change like we need to calculate fare based on distance, easily you can change strategy.

Decorate it if you want to add service tax on top of fare calculated.

So, I would suggest to use Strategy and Decorator pattern for it.

Sumit Gupta
  • 286
  • 1
  • 15
  • Decorator should be used when you want additional functionality wrapped on base functionality. So, how are u going to wrap within classes? if you are using decorator pattern, you would still be writing code to decide decorator classes. And one more thing, how you will incorporate if business rules changed later? – Sumit Gupta Aug 12 '15 at 10:36
  • I believe, Strategy is used when a client wants to select a strategy at runtime. eg When user purchase a product online, the user can choose any of the strategy amongst different payment strategies eg internet banking, cash on delivery, Bank ATM Pin etc. eg 2. A user wants to sort array. User can select any of the strategy i.e. Quick Sort, Merge Sort etc. I.e. Selecting a strategy at runtime which will give the same outcome. Different strategies at runtime which results in the same goal. Isn't it? I am not able relate the same analogy for the given problem statement with Strategy pattern. – Free Coder Aug 12 '15 at 13:19
  • In future, if the business requirement comes as, Apply applicable business rules for Fare, and also check Age i.e. For Age < 5Yrs OR senior citizens, Fare would be half. If another Business Rule comes e.g. 20% Fare cut in the summer season, along with other applicable Business Rules. Then in that case, would the Strategy Pattern be correct or Decorator pattern? – Free Coder Aug 12 '15 at 13:32
  • 1
    Now you can add "Chain of Responsibility" to handle discounts based on age/distance/festival dates etc to take care of this scenario – Ravindra babu Aug 12 '15 at 16:01
  • Chain Of Responsibility can be added for the Decorator as well. Intent of Strategy : https://en.wikipedia.org/wiki/Strategy_pattern. Intent of Decorator : https://en.wikipedia.org/wiki/Decorator_pattern. What would make sense A) BaseFare, AgeDecorator, DistanceDecorator, StationsDecorator, FestivalDecorator + Chain Of Responsibility OR B) BaseFareStrategy OR BaseAgeStrategy OR BaseAgeFestivalStrategy OR BaseAgeDistanceStationsStrategy etc OR C) BaseFareStrategy, AgeStrategy, StationsStrategy, DistanceStrategy, FestivalStrategy + Chain Of Responsibility. – Free Coder Aug 12 '15 at 17:53
  • If you meant option (C) then it's breaking the intent of Strategy, and how it is different than (A) in that case? If you meant option (B), then creating such complex strategies is too complex. Isn't it? – Free Coder Aug 12 '15 at 17:56
  • Decorator adds additional responsibility. Strategy implements a rule. Generally strategy is good pattern to implement Rule engine. – Ravindra babu Aug 13 '15 at 02:23
  • I want to replace Chain of Responsibility with Builder pattern, Strategy + Builder pattern will build a require rule engine. – Ravindra babu Aug 13 '15 at 02:43
  • interesting article about comparison between these two :http://synvistech.com/blogs/decorator-vs-strategy-design-pattern/ – Ravindra babu Aug 13 '15 at 02:55
  • @sunrise76 Please refer the same link you provided. Check the example of Payment Strategy. A user can/should choose any one of the payment strategies, but not all. Using the same analogy of the link you provided, could you tell, out of the options (A) , (B), (C) stated earlier, which option is in you mind? – Free Coder Aug 13 '15 at 03:47
  • In your example, you cannot get fare in one shot. You have to apply different rule strategies. – Ravindra babu Aug 13 '15 at 04:03
  • @sunrise76 How is it different than Option (A) in that case, and isn't it breaking the intent of Strategy as per the example in the link referenced by you? – Free Coder Aug 13 '15 at 06:00
  • I still think Fare calculation is "Gut" rather thank "Skin". Once you have strategy, you can substitute multiple rule implementations. I have implemented 40+ rule based state machine with strategies+ builder, which includes financial transactions. – Ravindra babu Aug 13 '15 at 06:21
  • That's the point, I am interested in, and need to understand. We are not substituting the strategies one for another, instead combining them, i.e. based on applicability. The analogy is similar to adding one decorator over the other. Isn't it? – Free Coder Aug 13 '15 at 07:00