Strategy and Flyweight patterns
I've read that "Strategy objects often make good flyweights" (from Design Patterns Elements of Reusable Object-Oriented Software), and I'm wondering how can this be implemented. I didn't find any example in the Internet.
Is the code (C#) below right, following this idea?
Thanks!
using System;
using System.Collections.Generic;
namespace StrategyFlyweight
{
class Program
{
static void Main(string[] args)
{
Client client = new Client();
for(int i = 1; i <= 10;i++)
{
client.Execute(i);
}
Console.ReadKey();
}
}
public interface IStrategy
{
开发者_运维问答 void Check(int number);
}
public class ConcreteStrategyEven : IStrategy
{
public void Check(int number)
{
Console.WriteLine("{0} is an even number...", number);
}
}
public class ConcreteStrategyOdd : IStrategy
{
public void Check(int number)
{
Console.WriteLine("{0} is an odd number...", number);
}
}
public class FlyweightFactory
{
private Dictionary<string, IStrategy> _sharedObjects = new Dictionary<string, IStrategy>();
public IStrategy GetObject(int param)
{
string key = (param % 2 == 0) ? "even" : "odd";
if (_sharedObjects.ContainsKey(key))
return _sharedObjects[key];
else
{
IStrategy strategy = null;
switch (key)
{
case "even":
strategy = new ConcreteStrategyEven();
break;
case "odd":
strategy = new ConcreteStrategyOdd();
break;
}
_sharedObjects.Add(key, strategy);
return strategy;
}
}
}
public class Client
{
private IStrategy _strategy;
private FlyweightFactory _flyweightFactory = new FlyweightFactory();
public void Execute(int param)
{
ChangeStrategy(param);
_strategy.Check(param);
}
private void ChangeStrategy(int param)
{
_strategy = _flyweightFactory.GetObject(param);
}
}
}
I think that to properly implement the flyweight pattern here, your factory method should always return the same instance of a particular strategy (like ConcreteStrategyEven
) rather than constructing a new instance each time.
If I'm not mistaken, the point of saying that Strategy objects make good Flyweights is that they often encapsulate no state (since they represent algorithms rather than entities) and can be reused.
Here is a link to an example of a Flyweight factory: http://www.java2s.com/Code/Java/Design-Pattern/FlyweightFactory.htm. Note this part, in particular:
public synchronized FlyweightIntr getFlyweight(String divisionName) {
if (lstFlyweight.get(divisionName) == null) {
FlyweightIntr fw = new Flyweight(divisionName);
lstFlyweight.put(divisionName, fw);
return fw;
} else {
return (FlyweightIntr) lstFlyweight.get(divisionName);
}
}
Here in the factory method, a new FlyweightIntr
is only initialized if the correct one is not available; otherwise it is retrieved from lstFlyweight
.
精彩评论