Sample - With Strategy
Code Sample with Strategy Pattern
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace PatternsExperiments.OrderWithStrategy
{
/// *** The below classes are new for Strategy *** ///
//Singleton class we call for global items
class ConfigData
{
//Simple Singleton class setup
private static ConfigData myInstance;
static Encrypter myEncrypter;
private ConfigData()
{
}
public static ConfigData GetInstance()
{
if (myInstance == null)
{ myInstance = new ConfigData();}
return myInstance;
}
//our public functions
public Encrypter Encrypter()
{
return new AES();
//return new TripleDES(); //alternate
}
public CreditCardProcesser CreditCardProcesser()
{
return new CCProcesser_AuthorizeNet();
//return new CCProcesser_BluePay;
}
public StateTaxCalulator StateTaxCalculator()
{
return new TaxCalator_AL();
//return new TaxCalculator_AK();
}
public RiskService RiskService()
{
return new RiskService_FraudSmack();
//return new RiskService_MaxFraud();
}
}
interface StateTaxCalulator
{
double ComputeTax(double Taxable);
}
class TaxCalculator_AK:StateTaxCalulator
{
internal StateTaxCalulator StateTaxCalulator
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public double ComputeTax(double Taxable)
{
return Taxable * .06;
}
}
class TaxCalator_AL : StateTaxCalulator
{
internal StateTaxCalulator StateTaxCalulator
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public double ComputeTax(double Taxable)
{
return Taxable * .07;
}
}
interface Encrypter
{
string Encrypt(string PlainText);
string Decrypt(string EncText);
}
class TripleDES : Encrypter
{
internal Encrypter Encrypter
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public string Encrypt(string PlainText)
{
//implement 3DES enc. algo.
return "";
}
public string Decrypt(string EncText)
{
//implement 3DES dec. algo.
return "";
}
}
class AES : Encrypter
{
internal Encrypter Encrypter
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public string Encrypt(string PlainText)
{
//implement AES enc. algo.
return "";
}
public string Decrypt(string EncText)
{
//implement AES dec. algo.
return "";
}
}
abstract class CreditCardProcesser //using class instead of interface
{
private bool _authorized;
private string _transID;
public abstract void Sale (CreditCard cc, double Amount);
public abstract void Authorize(CreditCard cc, double Amount);
public bool Authorized
{
get{return _authorized;}
set{this._authorized = value;}
}
public string TransactionID
{
get{return _transID;}
set{_transID = value;}
}
}
class CCProcesser_AuthorizeNet:CreditCardProcesser
{
public override void Sale (CreditCard card, double Amount)
{
//to be implemented
}
public override void Authorize(CreditCard card, double Amount)
{
//to be implemented
}
}
class CCProcesser_BluePay:CreditCardProcesser
{
public override void Sale (CreditCard card, double Amount)
{
//to be implemented
}
public override void Authorize(CreditCard card, double Amount)
{
//to be implemented
}
}
interface RiskService
{
RiskObject GetRiskObject(CreditCard card, Customer cust);
}
class RiskService_FraudSmack:RiskService
{
internal RiskService RiskService
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public RiskObject GetRiskObject(CreditCard card, Customer cust)
{
//implement Fraudsmack call
//create and return a RiskObject
return new RiskObject();
}
}
class RiskService_MaxFraud:RiskService
{
internal RiskService RiskService
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public RiskObject GetRiskObject(CreditCard card, Customer cust)
{
//implement MaxFraud call
//create and return a RiskObject
return new RiskObject();
}
}
/// *** The above classes are new for Strategy *** ///
class Customer
{
public string state;
}
class CreditCard
{
//implement the card object
}
class RiskObject
{
public enum ScoreValues{
Error,
Low,
Med,
Hi
};
ScoreValues _score;
public RiskObject()
{
_score = ScoreValues.Error;
}
public ScoreValues Score
{
get { return this._score; }
set { this._score = value; }
}
}
class ShoppingCart
{
ArrayList items = new ArrayList();
}
class Invoice
{
double subtotal;
double salesTax;
public double total;
}
class OrderProcesser
{
public void ProcessOrder(ShoppingCart cart,Customer cust)
{
// 1.) CreateInvoice
Invoice inv = CreateInvoice(cart, cust);
// 2.) Perform RiskCheck
CreditCard card = new CreditCard();
//TODO: assign the customer's input to the card
// card.number = "1111222233334444";
// etc.
RiskObject riskObj = ConfigData.GetInstance().RiskService().GetRiskObject(card,cust);
if (riskObj.Score == RiskObject.ScoreValues.Low)
{
//Complete the order
CreditCardProcesser ccp = ConfigData.GetInstance().CreditCardProcesser();
ccp.Sale(card,inv.total);
if (ccp.Authorized)
{
//The credit card processed
//Save Customer
//Save Invoice
SaveCreditCardTransaction();
//Activate account or Setup shipment of goods
}
else
{
//The credit card did not process (denied or error)
// Tell the customer to try later.
}
}
else if (riskObj.Score == RiskObject.ScoreValues.Med)
{
//Send to manual review process
//ReferForManualReview();
}
else if (riskObj.Score == RiskObject.ScoreValues.Hi)
{
//Reject the sale.
//RejectSale();
}
}
protected Invoice CreateInvoice(ShoppingCart cart, Customer cust)
{
Invoice i = new Invoice();
i.total = 100.00; //we would calc this
double tax;
//instead of switch, 1 line of code
//we can set the tax calculator in one place
//in the ConfigData singleton
//and now use 1 line when we need to calc tax
//1) CalcTax
tax = ConfigData.GetInstance().StateTaxCalculator().ComputeTax(i.total);
//2) Set invoice sales tax
return i;
}
//Got rid of real messy PerformRiskCheck() function
//Got rid of real messy ProcessCard() function
protected void SaveCreditCardTransaction()
{
EncryptTransactionData();
//now save the encrypted data
}
//get rid of messy switch statement in this function
protected void EncryptTransactionData()
{
Encrypter enc = ConfigData.GetInstance().Encrypter();
//enc.Encrypt(someString);
//enc.Encrypt(anotherString);
}
}
}