Skip to content

Instantly share code, notes, and snippets.

@Porges
Last active January 17, 2017 08:25
Show Gist options
  • Save Porges/bceb52ff49d059f7a687085498ea774d to your computer and use it in GitHub Desktop.
Save Porges/bceb52ff49d059f7a687085498ea774d to your computer and use it in GitHub Desktop.
Code for the post "Managing Multiplicity": https://porg.es/managing-multiplicity-monoidally/
interface IStrategy
{
Result DoTheThing(Input input);
}
class Consumer
{
readonly ICollection<IStrategy> _strategies;
public void PerformDuties()
{
foreach (var strategy in _strategies)
{
var result = strategy.DoTheThing(/*...*/);
// do something with result
}
}
}
interface IPolicy
{
bool ShouldPerformAction(Item item);
}
class UsesPolicy
{
readonly ICollection<IPolicy> _policies;
public void PerformDuties(Item item)
{
foreach (var policy in _policies)
{
if (!policy.ShouldPerformAction(item))
{
return;
}
}
// we got here, so perform the action
}
}
interface ICollectInformation
{
IEnumerable<Datum> CollectInformation();
}
class AggregateCollector : ICollectInformation
{
[NotNull]
readonly IReadOnlyCollection<ICollectInformation> _collectors;
public AggregateCollector(IEnumerable<ICollectInformation> collectors)
{
_collectors = collectors.ToList();
}
public IEnumerable<Datum> CollectInformation()
=> from collector in _collectors
from datum in collector.CollectInformation()
select datum;
}
class CollectsInformationRevised
{
readonly ICollectInformation _collecter;
public void Collect()
{
var data = _collecter.CollectInformation().ToList();
// do something with data
}
}
abstract class PolicyType
{
public abstract bool ShouldPerformAction(Item item);
public static PolicyType operator&(PolicyType first, PolicyType second)
=> new CombinedPolicy(first, second);
// this could be much cleaner if C# ever gets F#-style object expressions:
// https://github.com/dotnet/roslyn/issues/13#issuecomment-195161037
private class CombinedPolicy : PolicyType
{
readonly PolicyType _first;
readonly PolicyType _second;
public CombinedPolicy(PolicyType first, PolicyType second)
{
_first = first;
_second = second;
}
public override bool ShouldPerformAction(Item item)
=> _first.ShouldPerformAction(item) && _second.ShouldPerformAction(item);
}
}
class CombinedPolicy : IPolicy
{
[NotNull]
readonly IReadOnlyCollection<IPolicy> _policies;
public CombinedPolicy(IEnumerable<IPolicy> policies)
{
_policies = policies.ToList();
}
public bool ShouldPerformAction(Item item)
=> _policies.All(p => p.ShouldPerformAction(item));
}
class UsesPolicyRevised
{
readonly IPolicy _policy;
public void PerformDuties(Item item)
{
if (_policy.ShouldPerformAction(item))
{
// perform the action
}
}
}
interface IDoStuff
{
void DoStuff(Item item);
}
class InvokesActions
{
readonly ICollection<IDoStuff> _actions;
public void PerformDuties(Item item)
{
foreach (var action in _actions)
{
action.DoStuff(item);
}
}
}
class CombinedAction : IDoStuff
{
[NotNull]
readonly IReadOnlyCollection<IDoStuff> _actions;
public CombinedAction(IEnumerable<IDoStuff> actions)
{
_actions = actions.ToList();
}
public void DoStuff(Item item)
{
foreach (var action in _actions)
{
action.DoStuff(item);
}
}
}
class InvokesActionsRevised
{
readonly IDoStuff _action;
public void PerformDuties(Item item)
{
_action.DoStuff(item);
}
}
interface IDoStuffAsync
{
Task DoStuff(Item item, CancellationToken ct);
}
class InParallelActions : IDoStuffAsync
{
[NotNull]
readonly IReadOnlyCollection<IDoStuffAsync> _actions;
public InParallelActions(IEnumerable<IDoStuffAsync> actions)
{
_actions = actions.ToList();
}
public Task DoStuff(Item item, CancellationToken ct)
=> Task.WhenAll(_actions.Select(action => action.DoStuff(item, ct)));
}
struct Datum
{
public string Key { get; }
public double Value { get; }
}
interface ICollectInformation
{
Datum CollectInformation();
}
class CollectsInformation
{
readonly ICollection<ICollectInformation> _collecters;
public void DoCollection()
{
var data = new List<Datum>();
foreach (var collector in _collecters)
{
data.Add(collector.CollectInformation());
}
// do something with data
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment