using System.Linq.Expressions;
using System.Linq;
using System.Text;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace design_patterns.behavioral.strategy
{
///
/// Strategy is a behavioral design pattern that lets you
/// define a family of algorithms, put each of them into a separate class,
/// and make their objects interchangeable.
///
/// Use it when:
/// - you want to use different variants of an algorithm
/// within an object and be able to switch from one algorithm
/// to another during runtime.
/// - you have a lot of similar classes that only differ
/// in the way they execute some behavior.
/// - to isolate the business logic of a class from the
/// implementation details of algorithms that may not be as important
/// in the context of that logic.
/// - your class has a massive conditional operator that switches
/// between different variants of the same algorithm.
///
public class StrategySample
{
public static async Task Run()
{
Console.WriteLine("Behavioral - Strategy");
var processor = new SqlBuilderProcessor(new SqliteStrategy());
processor.Select.AddRange(new string[]{"fieldA", "fieldB" });
processor.From = "TableABC";
processor.Where = new LogicExpression {
First = new LogicExpression {
First = "fieldF",
Operator = LogicOperator.Equal,
Last = 1
},
Operator = LogicOperator.And,
Last = true
};
processor.Orderby.Add(("fieldA", OrderDirection.ASC));
processor.Orderby.Add(("fieldC", OrderDirection.DESC));
System.Console.WriteLine(processor);
// second strategy
processor.SetStrategy(new MsSqlStrategy());
System.Console.WriteLine(processor);
}
public interface ISqlStrategy {
string Select(IProcessor processor);
string From(IProcessor processor);
string Where(IProcessor processor);
string OrderBy(IProcessor processor);
string GetOperatorSymbol(LogicOperator op);
}
public enum OrderDirection {
ASC,
DESC
}
public enum LogicOperator {
And,
Or,
Not,
Like,
Greater,
Less,
Equal,
NotEqual
}
public class LogicExpression
{
public object First { get; set; }
public StrategySample.LogicOperator Operator { get; set; }
public object Last { get; set; }
private StringBuilder sb = new StringBuilder();
private Func operatorFunc;
private Func