Skip to content

Instantly share code, notes, and snippets.

@OriginUnknown
Created June 17, 2015 10:08
Show Gist options
  • Save OriginUnknown/db057fddcd542083f6b2 to your computer and use it in GitHub Desktop.
Save OriginUnknown/db057fddcd542083f6b2 to your computer and use it in GitHub Desktop.
JavaScript OOP Design Pattern Adapter Pattern {Object}
<!doctype html>
<html lang="en">
<head>
<title>Adapter pattern - object composition</title>
</head>
<body>
<script type="text/javascript">
//Adaptees -> the classes to be adapted
function WesternUnion () {
var wire = function ( amount ) {
return amount;
};
return {
"wire" : wire
}
}
function PayPal () {
var payAPerson = function ( amount ) {
var fee = 20, totalAmt = parseInt( amount ) + fee;
return totalAmt;
};
return {
"payRecepient" : payAPerson
}
}
function Amex () {
var transferMoney = function ( amt ) {
var amount = amt,
amexFeePercentage = 2.5,
feeAmount = (amexFeePercentage / 100) * amount,
totalAmount = amount + feeAmount;
return totalAmount;
};
return {
"transferFunds" : transferMoney
}
}
/*
** Adapter -> mediates between the client and the adaptee, using an interface the clients expects ->(ITarget), the Adapter takes the client's
** request and delegates it to the Adaptee either by composition -> object adapter pattern: (including an instance object of the Adaptee class
** inside the Adapter) or via multiple inheritance (class adapter pattern aka polymorphic interfaces). The code below adopts object adapter pattern
**
** Normally, you'd have an interface that has a signature method[s] for Adapter classes to implement AND that the client understands.
** and expects to use. This would look something like
** var PaymentAdapter = function(){
** this.pay(amount);
** this.getTotalAmount();
** ...
** }
** As JavaScript doesn't acknowledge interfaces, all Adapter classes will be implemented with identical method names to mimic an interface
**
** Known as "composition": an instance of the Adaptee class which has the method we want pay() to wrap is newed up inside the Adapter class hence,
** the "object adapter pattern"
*/
function WesternUnionAdapter () {
var westernUnionObj = WesternUnion(), //composition in action: the object adapter pattern
logger = PaymentStatusLogger();
var ipay = function ( amount ) {
westernUnionObj.wire( amount );
logger.add( "Wiring $" + amount + " using Western Union's services" );
};
var logMsg = function () {
return logger.showLogs();
};
return {
"pay" : ipay,
"log" : logMsg
}
}
function PayPalPaymentAdapter () {
var paypalObj = PayPal(),
logger = PaymentStatusLogger();
var ipay = function ( amount ) {
var totalAmount = paypalObj.payRecepient.call( this, amount );
logger.add( "Total amount sent incl $20 handling fee is $" + totalAmount + " using PayPal services" );
};
var logMsg = function () {
return logger.showLogs();
};
return {
"pay" : ipay,
"log" : logMsg
}
}
function AmexPaymentAdapter () {
var amexObj = Amex(),
logger = PaymentStatusLogger();
var ipay = function ( amnt ) {
var amount = amnt, totalAmount = amexObj.transferFunds.call( this, amount );
logger.add( "Total amount sent incl 2% processing fee for $" + amount + " is $" + totalAmount + " using American Express services" );
};
var logMsg = function () {
return logger.showLogs();
};
return {
"pay" : ipay,
"log" : logMsg
}
}
//helper function to print out the outcome of the pay() method
function PaymentStatusLogger () {
var msg = "";
var addMsg = function ( m ) {
msg += m + "\n";
};
var show = function () {
return msg;
};
return {
"add" : addMsg,
"showLogs" : show
}
}
/*
** Client code
** The client is unaware that it is talking to an Adapter class. It just calls the methods it knows about and they return the results it wants -> decoupling between client and Adaptee!!!
*/
var westernUnion = WesternUnionAdapter(), paypal = PayPalPaymentAdapter(), amex = AmexPaymentAdapter();
//object adapter pattern in action. Note how the
westernUnion.pay( 2000 );
paypal.pay( 3000 );
amex.pay( 4000 );
//log out payment status report
console.log( westernUnion.log() );
console.log( paypal.log() );
console.log( amex.log() );
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment