First - I have a Node struct, which represents a network connection to a node.
type Node struct { *apiclient.Node } func (c *Node) GetStatus() (status *models.Status, err error) func (c *Node) PostTransaction(signedEncodedTx, signedEncodedTxHash string) (err error) func (c *Node) GetTopBlock() (kb *models.KeyBlockOrMicroBlockHeader, err error) func (c *Node) GetHeight() (height uint64, err error) func (c *Node) GetCurrentKeyBlock() (kb *models.KeyBlock, err error) func (c *Node) GetAccount(accountID string) (account *models.Account, err error) func (c *Node) GetNameEntryByName(name string) (nameEntry *models.NameEntry, err error) func (c *Node) GetGenerationByHeight(height uint64) (g *models.Generation, err error) func (c *Node) GetMicroBlockTransactionsByHash(microBlockID string) (txs * models.GenericTxs, err error) func (c *Node) GetMicroBlockHeaderByHash(microBlockID string) (txs *models. MicroBlockHeader, err error) func (c *Node) GetKeyBlockByHash(keyBlockID string) (txs *models.KeyBlock, err error) func (c *Node) GetTransactionByHash(txHash string) (tx *models. GenericSignedTx, err error) func (c *Node) GetOracleByPubkey(pubkey string) (oracle *models. RegisteredOracle, err error) func (c *Node) GetOracleQueriesByPubkey(pubkey string) (oracleQueries * models.OracleQueries, err error) func (c *Node) GetContractByID(ctID string) (contract *models.ContractObject , err error) I want to be able to mock out the node's methods, so for every Node method, I make an interface. type GetStatuser interface type PostTransactioner interface type GetTopBlocker interface type GetHeighter interface type GetAccounter interface type GetNameEntryByNamer interface type GetGenerationByHeighter interface type GetMicroBlockTransactionsByHasher interface type GetMicroBlockHeaderByHasher interface type GetKeyBlockByHasher interface type GetTransactionByHasher interface type GetOracleByPubkeyer interface Sometimes, I just need to return a Node instance. However, to make that code testable without an actual Node connection, I have to introduce this large interface, which is only used once. type NodeInterface interface { GetAccounter GetTopBlocker GetStatuser GetHeighter GetKeyBlockByHasher GetOracleByPubkeyer GetGenerationByHeighter GetTransactionByHasher GetNameEntryByNamer GetMicroBlockHeaderByHasher GetMicroBlockTransactionsByHasher PostTransactioner } Some functions that build upon Node methods are used quite often, so I put them in a Helper struct to avoid having to specify the Node instance every time. Again, to make code above independent from Helpers or an actual Node connection, I have to introduce a large interface. type Helpers struct { Node GetHeightAccountNamer } func (h Helpers) GetTTL(offset uint64) (ttl uint64, err error) func (h Helpers) GetNextNonce(accountID string) (nextNonce uint64, err error ) func (h Helpers) GetTTLNonce(accountID string, offset uint64) (height uint64 , nonce uint64, err error) func (h Helpers) getAnythingByName(name string, key string) (results [] string, err error) func (h Helpers) GetAccountsByName(name string) (addresses []string, err error) func (h Helpers) GetOraclesByName(name string) (oracleIDs []string, err error) func (h Helpers) GetContractsByName(name string) (contracts []string, err error) func (h Helpers) GetChannelsByName(name string) (channels []string, err error) type HelpersInterface interface { GetTTL(offset uint64) (ttl uint64, err error) GetNextNonce(accountID string) (nextNonce uint64, err error) GetTTLNonce(accountID string, offset uint64) (height uint64, nonce uint64, err error) GetAccountsByName(name string) (addresses []string, err error) GetOraclesByName(name string) (oracleIDs []string, err error) GetContractsByName(name string) (contracts []string, err error) GetChannelsByName(name string) (channels []string, err error) } The functions that use the Helper struct are always executed in the context of a particular address and node, so I make a Context struct that combines Helpers and an Address. // Context stores relevant context (node connection, account address) that one might not want to spell out each time one creates a transaction type Context struct { Address string Helpers HelpersInterface } func (c *Context) SpendTx(senderID string, recipientID string, amount, fee big.Int, payload []byte) (tx SpendTx, err error) func (c *Context) NamePreclaimTx(name string, fee big.Int) (tx NamePreclaimTx, nameSalt *big.Int, err error) func (c *Context) NameClaimTx(name string, nameSalt big.Int, fee big.Int) (tx NameClaimTx, err error) func (c *Context) NameUpdateTx(name string, targetAddress string) (tx NameUpdateTx, err error) ... Problems: 1. After using the `Context` methods to create a Transaction, it is necessary to `node.BroadcastTransaction()`. However, because of `HelpersInterface`, the code above cannot access the underlying Node instance. So I either create a new Node above, or return one from `Context`'s constructor func NewContextFromURL(url string, address string, debug bool) (ctx *Context , node *Node) which seems inelegant. Of course I could add Helpers.BroadcastTransaction() but unlike the other helper methods, BroadcastTransaction() does not need any extra code around it. 2. After writing the question it seems like eliminating the Helpers struct will solve the problem. But I don't know if it is really THE solution, because I used the same pattern with NodeInterface, and sometimes I really do need to say that I will pass in a full-featured Node, so I have to have this large interface. 3. Somehow I feel like the whole idea of making code easier to write by putting frequently used variables into a class/struct (yes I know Go has no classes) and calling the methods of that struct is not how Go is supposed to be used, but I am not sure. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/3ee266e3-ccb4-401c-a754-addbda544349%40googlegroups.com.