Skip to content

Instantly share code, notes, and snippets.

@patterns
Created October 27, 2016 05:31
Show Gist options
  • Save patterns/dc8cb67ebf03fdc7c5c7ac503526c7ff to your computer and use it in GitHub Desktop.
Save patterns/dc8cb67ebf03fdc7c5c7ac503526c7ff to your computer and use it in GitHub Desktop.
Practice adapter pattern on SHA1 / SHA256 / .....
Reference https://msdn.microsoft.com/en-us/library/orm-9780596527730-01-04.aspx
Attempt of the pluggable adapter according to this excerpt:
// Existing way requests are implemented
class Adaptee {
public double Precise (double a, double b) {
return a/b;
}
}
// New standard for requests
class Target {
public string Estimate (int i) {
return "Estimate is " + (int) Math.Round(i/3.0);
}
}
// Implementing new requests via old
class Adapter : Adaptee {
public Func <int,string> Request;
// Different constructors for the expected targets/adaptees
// Adapter-Adaptee
public Adapter (Adaptee adaptee) {
// Set the delegate to the new standard
Request = delegate(int i) {
return "Estimate based on precision is " +
(int) Math.Round(Precise (i,3));
};
}
// Adapter-Target
public Adapter (Target target) {
// Set the delegate to the existing standard
Request = target.Estimate;
}
}
class Client {
static void Main ( ) {
Adapter adapter1 = new Adapter (new Adaptee( ));
Console.WriteLine(adapter1.Request(5));
Adapter adapter2 = new Adapter (new Target( ));
Console.WriteLine(adapter2.Request(5));
}
}
package main
import (
"bufio"
"crypto/sha1"
"crypto/sha256"
"fmt"
"os"
)
// Adaptee is the existing functionality.
type Adaptee struct {
Salt []byte
}
// Hash is calculated with Salt prefixed
func (a Adaptee) Hash(data []byte) []byte {
sz := len(data) + len(a.Salt)
t := make([]byte, sz)
copy(t, a.Salt)
copy(t[len(a.Salt):], data)
h := sha1.New()
h.Write(t)
digest := h.Sum(nil)
return digest
}
// Target is the *new* contract
type Target struct {
Salt []byte
Algo string
}
func (t Target) GetDigest(data string) string {
sz := len(data) + len(t.Salt)
d := make([]byte, sz)
copy(d, t.Salt)
copy(d[len(t.Salt):], []byte(data))
h := sha256.New()
h.Write(d)
digest := h.Sum(nil)
return string(digest)
}
// Adapter is the part that sits in between the Client and Target/Adaptee
type Adapter struct {
Salt []byte
Algo string
Calc func(string) string
}
// New is a ctor to handle Target approach
func (Adapter) New2(target Target) Adapter {
a := Adapter{target.Salt, target.Algo, target.GetDigest}
return a
}
// New is a ctor to bridge the original Adaptee
func (Adapter) New(target Adaptee) Adapter {
a := Adapter{
target.Salt,
"SHA1",
func(data string) string {
d := target.Hash([]byte(data))
return string(d)
},
}
return a
}
// Client makes calls according to the contract defined by Target
func main() {
var salt, payload string
scanner := bufio.NewReader(os.Stdin)
_, err := fmt.Fscanf(scanner, "%s %s\n", &salt, &payload)
if err != nil {
panic(err)
}
s := []byte(salt)
// Adapter1 configured to original SHA1
adapter1 := Adapter{}.New(Adaptee{s})
d1 := adapter1.Calc(payload)
fmt.Printf("%x\n", d1)
// Adapter2 configured to SHA256
adapter2 := Adapter{}.New2(Target{s, "SHA256"})
d2 := adapter2.Calc(payload)
fmt.Printf("%x\n", d2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment