Skip to content

Commit a2011a2

Browse files
committed
decoupling with interface and concrete data
1 parent 0f92501 commit a2011a2

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module decoupling
2+
3+
go 1.21.1
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"io"
7+
"math/rand"
8+
"time"
9+
)
10+
11+
func init() {
12+
rand.Seed(time.Now().UnixNano())
13+
}
14+
15+
// =============================================================================
16+
17+
// Data is the structure of the data we are copying.
18+
type Data struct {
19+
Line string
20+
}
21+
22+
// =============================================================================
23+
24+
// Puller declares behavior for pulling data.
25+
type Puller interface {
26+
Pull(d *Data) error
27+
}
28+
29+
// Storer declares behavior for storing data.
30+
type Storer interface {
31+
Store(d *Data) error
32+
}
33+
34+
// PullStorer declares behavior for both pulling and storing.
35+
type PullStorer interface {
36+
Puller
37+
Storer
38+
}
39+
40+
// =============================================================================
41+
42+
// Xenia is a system we need to pull data from.
43+
type Xenia struct {
44+
Host string
45+
Timeout time.Duration
46+
}
47+
48+
// Pull knows how to pull data out of Xenia.
49+
func (*Xenia) Pull(d *Data) error {
50+
switch rand.Intn(10) {
51+
case 1, 9:
52+
return io.EOF
53+
54+
case 5:
55+
return errors.New("error reading data from Xenia")
56+
57+
default:
58+
d.Line = "Data"
59+
fmt.Println("In:", d.Line)
60+
return nil
61+
}
62+
}
63+
64+
// Pillar is a system we need to store data into.
65+
type Pillar struct {
66+
Host string
67+
Timeout time.Duration
68+
}
69+
70+
// Store knows how to store data into Pillar.
71+
func (*Pillar) Store(d *Data) error {
72+
fmt.Println("Out:", d.Line)
73+
return nil
74+
}
75+
76+
// =============================================================================
77+
78+
// System wraps Pullers and Stores together into a single system.
79+
type System struct {
80+
Puller
81+
Storer
82+
}
83+
84+
// =============================================================================
85+
86+
// pull knows how to pull bulks of data from any Puller.
87+
func pull(p Puller, data []Data) (int, error) {
88+
for i := range data {
89+
if err := p.Pull(&data[i]); err != nil {
90+
return i, err
91+
}
92+
}
93+
94+
return len(data), nil
95+
}
96+
97+
// store knows how to store bulks of data from any Storer.
98+
func store(s Storer, data []Data) (int, error) {
99+
for i := range data {
100+
if err := s.Store(&data[i]); err != nil {
101+
return i, err
102+
}
103+
}
104+
105+
return len(data), nil
106+
}
107+
108+
// Copy knows how to pull and store data
109+
func Copy(p Puller, s Storer, batch int) error {
110+
data := make([]Data, batch)
111+
112+
for {
113+
i, err := pull(p, data)
114+
if i > 0 {
115+
if _, err := store(s, data[:i]); err != nil {
116+
return err
117+
}
118+
}
119+
120+
if err != nil {
121+
return err
122+
}
123+
}
124+
}
125+
126+
// =============================================================================
127+
128+
func main() {
129+
x := &Xenia{
130+
Host: "localhost:8000",
131+
Timeout: time.Second}
132+
p := &Pillar{
133+
Host: "localhost:9000",
134+
Timeout: time.Second,
135+
}
136+
137+
if err := Copy(x, p, 3); err != io.EOF {
138+
fmt.Println(err)
139+
}
140+
}

0 commit comments

Comments
 (0)