Created
October 27, 2016 05:31
-
-
Save patterns/dc8cb67ebf03fdc7c5c7ac503526c7ff to your computer and use it in GitHub Desktop.
Practice adapter pattern on SHA1 / SHA256 / .....
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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