String foo = Request.QueryString["foo"];
if (!String.IsNullOrEmpty(foo))
{
DoFooWork(foo);
}
else
{
String bar = Request.QueryString["bar"];
if (!String.IsNullOrEmpty(bar))
{
DoBarWork(bar);
}
else
{
String baz = Request.QueryString["baz"];
if (!String.IsNullOrEmpty(baz))
{
DoBazWork(baz);
}
else
{
String beer = Request.QueryString["beer"];
if (!String.IsNullOrEmpty(beer))
{
DoBeerWork(beer);
// ...
Refactorings
No refactoring yet !
slf
March 24, 2009, March 24, 2009 14:49, permalink
Maybe a psuedo-registry pattern? Also, it's probably worth mentioning this is .NET 3.5 so any Linq / Lambda / Functional programming answers are valid too.
AG
March 24, 2009, March 24, 2009 15:55, permalink
Need more context. What is the intent of this code? You could probably roll this into a map using the querystring value as a key into it...
(Keep in mind that the PoEAA book is intended for higher "Enterprise" patterns.)
uvw
March 24, 2009, March 24, 2009 17:13, permalink
May be something like this.
internal interface IQueryStringProcessor : IEnumerable<KeyValuePair<string, Action<string>>>
{
void Add(string key, Action<string> action);
void Process(IDictionary<string, string> queryString);
Action Fallback { get; set; }
};
internal class FooBarBazQueryStringProcessor : IQueryStringProcessor
{
private readonly List<KeyValuePair<string, Action<string>>> plan;
public FooBarBazQueryStringProcessor(Action fallback)
{
plan = new List<KeyValuePair<string, Action<string>>>();
Fallback = fallback;
}
public void Add(string key, Action<string> action)
{
plan.Add(new KeyValuePair<string, Action<string>>(key, action));
}
public void Process(IDictionary<string, string> queryString)
{
foreach (var pair in plan) {
string value;
if (!queryString.TryGetValue(pair.Key, out value) ||
string.IsNullOrEmpty(value)) {
continue;
}
pair.Value(value);
return;
}
if (Fallback != null) {
Fallback();
}
}
public Action Fallback { get; set; }
public IEnumerator<KeyValuePair<string, Action<string>>> GetEnumerator()
{
return plan.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Sample usage
/// </summary>
public static void Main()
{
Action fallback = () => {
throw new ArgumentException("The query string does not contain any known parameters.");
};
var processor = new FooBarBazQueryStringProcessor(fallback) {
{"foo", foo => DoFooWork(foo) },
{"bar", bar => DoBarWork(bar)},
{"baz", baz => DoBazWork(baz)}
};
// ...
var request = new Dictionary<string, string> {
{"foo", "some foo data"}
};
// ...
processor.Process(request);
}
}
slf
March 24, 2009, March 24, 2009 18:43, permalink
@uvw, I like it. Kind of reminds me of Perl.
@AG comments made me remember to pull out the GoF book. I think this is the solution:
http://www.dofactory.com/patterns/PatternStrategy.aspx
What do you guys think?
Moonshield
March 27, 2009, March 27, 2009 01:39, permalink
I've already posted something similar, you can take a look at http://refactormycode.com/codes/493-twitter-esque-relative-dates
The code below is probably what I would do, it is very similar to the code above but without the overhead
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication4
{
class Program
{
private static Dictionary<string, Action<string>> _QueryPriority;
static void Main(string[] args)
{
if (_QueryPriority == null)
{
_QueryPriority = new Dictionary<string, Action<string>>();
_QueryPriority.Add("Foo", DoFooWork);
_QueryPriority.Add("Bar", DoBarWork);
_QueryPriority.Add("Beer", DoBeerWork);
_QueryPriority.Add("Coffee", DoCoffeeWork);
}
var action = Program._QueryPriority.FirstOrDefault(x => !string.IsNullOrEmpty(Request.QueryString[x]));
if (action.Key != null)
action.Value.Invoke(action.Key);
}
private static void DoFooWork(string pParam) { Console.WriteLine(pParam); }
private static void DoBarWork(string pParam) { Console.WriteLine(pParam); }
private static void DoBeerWork(string pParam) { Console.WriteLine(pParam); }
private static void DoCoffeeWork(string pParam) { Console.WriteLine(pParam); }
}
}
slf
March 27, 2009, March 27, 2009 19:48, permalink
Very nice, clean and concise Moonshield. I love it. Going back to the original intent, is there an established pattern for this? If not we should come up with a name. This is basically a "Action Registry" to me.
uvw
March 27, 2009, March 27, 2009 22:25, permalink
In general this is the "Pattern Matching" [http://en.wikipedia.org/wiki/Pattern_matching] pattern (oops ;))
Jean
April 3, 2009, April 03, 2009 21:01, permalink
Hello. That's very nice site but I've seen this before here <a href="http://href.inguaro.com/f183d07eb9ff97f92a80d3965dce9974">http://text.inguaro.com/f183d07eb9ff97f92a80d3965dce9974</a>
f183d07eb9ff97f92a80d3965dce9974
Hello. That's very nice site but I've seen this before here <a href="http://href.inguaro.com/f183d07eb9ff97f92a80d3965dce9974">http://text.inguaro.com/f183d07eb9ff97f92a80d3965dce9974</a> f183d07eb9ff97f92a80d3965dce9974
Lewis
April 3, 2009, April 03, 2009 21:01, permalink
The night of the fight, you may feel a slight sting. That's pride f*cking with you. F*ck pride. Pride only hurts, it never helps.
f183d07eb9ff97f92a80d3965dce9974
The night of the fight, you may feel a slight sting. That's pride f*cking with you. F*ck pride. Pride only hurts, it never helps. f183d07eb9ff97f92a80d3965dce9974
There is a page in a C# web site that has a requirement to do something like the below. To me this is basically the same problem as a command line application that takes multiple parameters that must override each other. This is ugly to me, and I'm looking for an established pattern that solves this problem. After poking around http://martinfowler.com/eaaCatalog/ I didn't see anything that immediately jumped out at me as the solution.