Real World Example of the Strategy Pattern
I've been reading about the OCP principal and how to use the strategy pattern to accomplish this.
I was going to try and explain this to a couple of people, but the only example I can think of is using different validation classes based on what status an "order" is.
I've read a couple of articles online, but these don't usually describe a real like reason to use the strategy, like generating reports/bills/validation etc...
Are there any real world examples where you think a strategy pattern is common?
What about this:
You have to encrypt a file.
For small files, you can use "in memory" strategy, where the complete file is read and kept in memory ( let's say for files < 1 gb )
For large files, you can use another strategy, where parts of the file are read in memory and partial encrypted results are stored in tmp files.
These may be two different strategies for the same task.
The client code would look the same:
File file = getFile();
Cipher c = CipherFactory.getCipher( file.size() );
c.performAction();
// implementations:
interface Cipher {
public void performAction();
}
class InMemoryCipherStrategy implements Cipher {
public void performAction() {
// load in byte[] ....
}
}
class SwaptToDiskCipher implements Cipher {
public void performAction() {
// swapt partial results to file.
}
}
The
Cipher c = CipherFactory.getCipher( file.size() );
Would return the correct strategy instance for the cipher.
I hope this helps.
( I don't even know if Cipher is the right word :P )
Again, an old post but still turns up on searches so I'll add two more examples (Code is in C#). I absolutly love the Strategy pattern since it has saved my butt a lot of times when the project managers say: "We want the application to do , but is not yet clear and it can change in the near future". I'm pretty sure this video explains everything that is so great about the strategy pattern, using StarCraft as an example: http://www.youtube.com/watch?v=MOEsKHqLiBM
Stuff that falls in this category:
Sorting (We want to sort these numbers, but we don't know if we are gonna use BrickSort, BubbleSort or some other sorting)
Validation (We need to check items according to "Some rule", but it's not yet clear what that rule will be, and we may think of new ones.)
Games (We want player to either walk or run when he moves, but maybe in the future, he should also be able to swim, fly, teleport, burrow underground, etc.)
Storing information (We want the application to store information to the Database, but later it may need to be able to save a file, or make a webcall)
Outputting (We need to output X as a plain string, but later may be a CSV, XML, Json, etc.)
Examples
I have a project where the users can assign products to people in a database. This assignment of a product to a person has a status which is either "Approved" or "Declined", which isdependant on some businessrules. (For example, is a user assigns a product to a person with a certain age, it's status should be declined, if the difference between two fields in the item is larger than 50, it's status is declined, etc.)
Now, at the moment of development these businessrules are not yet all completely clear, and new rules could come up at any time. The power of the stragety-pattern is that I made a RuleAgent, which is given a list of IRules.
public interface IRule {
bool IsApproved(Assignment assignment);
}
At the moment of assigning a product to a person, I create a RuleAgent, give it a list of rules (which all implement IRule), and ask it to validate an assignment. It'll run through all it's rules (Which because they all implement the same interface, all have the IsApproved
method) and return false if any of them returns false.
Now when for instance the manager suddenly comes up and says, we also need to decline all assignments to women, or all assignments to people with the last name "Johnsson" or whatever... You make new classes like this:
public LastNameRule : IRule
{
public bool IsApproved(Assignment assignment) //Interface method
{
if (assignment.Person.Lastname == "Johnsson")
{
return false;
}
return true;
}
}
public GenderRule : IRule
{
public bool IsApproved(Assignment assignment) //Interface method
{
if (assignment.Person.Gender== Gender.Female)
{
return false;
}
return true;
}
}
You see that you don't have to keep adding or removing if-statements or code, just make a new rule-class that implements the IRUle interface and switch those out when needed.
Another great example (by Scott Allen's video serie at http://www.asp.net/mvc/pluralsight The part where he uses the strategy pattern in in the UNit-test part of the application)
He builds a website which has a page that displays items based on popularity. However "Popular" can be many things (most views, most subscribers, creation date, most activity, least amount of comments, whatever), and in case management doesn't yet know exacly how to order, and may want to experiment with different orderings at a later date. You make an interface (IOrderAlgorithm or somethng) with an order method, and let an Orderer-object delegate the ordering to a concrete implementation of the IOrderAlgorithm interface. You can make a "CommentOrderer", "ActivityOrderer", etc... And just switch these out when new requirements come up.
I can think of several fairly simple examples:
Data compression. You might have an ICompressor interface whose sole method looks something like this:
byte[] compress(byte[] input);
Your concrete compression classes might be things like RunLengthCompression, DeflateCompression, etc.
上一篇: 如何从日期查找月份的最后一天?
下一篇: 战略模式的实例