Code Sample without Strategy
This code does not use the Strategy pattern. This would be an example of a scenario that can be improved with the Strategy pattern.
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace PatternsExperiments.OrderNoStrategy
{
class Customer
{
public string state;
}
class CreditCard
{
//implement the card object
}
class RiskObject
{
public enum ScoreValues{
Error,
Low,
Med,
Hi
};
ScoreValues _score;
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 = PerformRiskCheck(card, cust);
if (riskObj.Score == RiskObject.ScoreValues.Low)
{
//Complete the order
if (ProcessCard(card,inv.total))
{
//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();
//add sales tax to invoice
switch (cust.state)
{
case "AL":
//1) Calculate the AL tax.
break;
case "AK":
//1) Calculate the AK tax.
break;
// do this 48 more times for each state for US sales
// ...
}
//2) Set invoice sales tax
return i;
}
protected RiskObject PerformRiskCheck(CreditCard card, Customer cust)
{
string riskProcessor = "FraudSmack"; //setting a default
//Get a string from config file to tell us which type of
// risk processing function to call
//riskProcessor = GetFromConfig("FraudProcessor");
RiskObject ro = null;
if(riskProcessor != "")
{
switch (riskProcessor)
{
case "FraudSmack":
//Perform riks check using FraudSmack.com
break;
case "MaxFraud":
//Perform risk check using MaxFraud :)
break;
//continue for each possible risk check software or service
}
}
return ro;
}
protected bool ProcessCard(CreditCard card,double Amount)
{
string CCProcessor = "APlusProcessor"; //not a real cc processor
//you would get the string from config
bool retVal = false;
switch (CCProcessor)
{
case "APlusProcessor":
// 1)call the "APlusProcessor" credit card process
// 2)Set vars to save cc trans to database
// 3)retVal = APlusProcessor.PerformSale(card,Amount);
break;
case "BMinusProcessor":
// 1)call the "APlusProcessor" credit card process
// 2)Set vars to save cc trans to database
// 3)retVal = APlusProcessor.PerformSale(card,Amount);
break;
//implement a case for each card processor
// ...(goes on and on)
}
return retVal;
}
protected void SaveCreditCardTransaction()
{
EncryptTransactionData();
//now save the encrypted data
}
protected void EncryptTransactionData()
{
string EncryptType = "3DES";
//You would really pull this from a config file or global variable
switch (EncryptType)
{
case "3DES":
//Call 3DESEncrypt
break;
case "AES":
//Call AESEncrypt
break;
// this goes on for each type of possible encryption you use
// ... (this goes on and on)
}
}
}
}