in trading_data.go, in the API package, we're getting values from the stats type for the API. This is fine, but the stats.Stats type is passed in raw, so the Inc*, Add* and Set* methods are all exposed. We ought to define an interface so only getters are exposed to the api package.
TODO:
Embed the stats types so stats.Stats has a single API (embedded getters can be accessed directly on the type etc...)
Declare the interface the API package needs/uses to serve up the stats
In case of name conflicts (embedded getters with the same name), create an overarching getter to be specific, or rename conflicting getters (whichever makes more sense given the name collision)
Tests:
The stats and monitoring objects are the only dependencies not yet changed to an interface. Once we have the stats dependency as an interface, we can easily write a unit test to cover the statistics endpoint.
Risks:
As previously indicated, name conflicts are possible, and resolving these incorrectly could result in bugs. For this reason, I'd recommend using an overarching getter unless we can be absolutely certain that renaming the getter will work as expected. Just an example to clarify what I mean:
type Stats struct {
*Blockchain // as opposed to the current Blockchain *Blockchain
*FutureStats // currently no other stats objects exist/are embedded
}
func (b Blockchain) GetFoo() int {
return b.foo
}
func (f FutureStats) GetFoo() int {
return f.foo
}
func (s Stats) GetBlockchainFoo() int {
return s.Blockchain.GetFoo()
}
func (s Stats) GetFutureFoo() int {
return s.foo.GetFoo()
}
// and not:
func (f FutureStat) GetFutureFoo() int {
return f.foo
}
// with expected use of:
stat.GetFoo() // equivalent to stat.Blockchain.GetFoo()
stat.GetFutureFoo() // equivalent to stat.FutureStat.GetFoo()
in
trading_data.go
, in the API package, we're getting values from thestats
type for the API. This is fine, but thestats.Stats
type is passed in raw, so theInc*
,Add*
andSet*
methods are all exposed. We ought to define an interface so only getters are exposed to the api package.TODO:
stats.Stats
has a single API (embedded getters can be accessed directly on the type etc...)Tests:
The stats and monitoring objects are the only dependencies not yet changed to an interface. Once we have the stats dependency as an interface, we can easily write a unit test to cover the statistics endpoint.
Risks:
As previously indicated, name conflicts are possible, and resolving these incorrectly could result in bugs. For this reason, I'd recommend using an overarching getter unless we can be absolutely certain that renaming the getter will work as expected. Just an example to clarify what I mean: