>Collapse all three. This works but I really don't like having Fake code in 
the same package as real code.

This is the answer, in my opinion. Don't split code across packages unless 
there's a reason to do so. A fake implementation is a feature. If it hurts 
that much, just call it something more general, like InMemoryClient, and 
note in the doc that it's only for testing. Keep it simple.
On Monday, June 19, 2023 at 6:18:02 PM UTC-7 Salvatore Domenick Desiano 
wrote:

> Interesting point. Two questions:
>
>    - Is there a standard library example of a client library that 
>    provides a fake?
>    - I've always been taught that Go packages stand alone so names like 
>    "api" and "model" are verboten. Am I wrong?
>
>
>
> On Monday, June 19, 2023 at 1:22:03 AM UTC-4 TheDiveO wrote:
>
>> Maybe not the best way either, but the POD part might benefit from slight 
>> refactoring and you already in part hinted at it.
>>
>>    - gopher/api -- some PODs here
>>    - gopher/model -- don't repeat gopher as in gophermodel; some PODs 
>>    here
>>
>> It won't ever perfect, so YMMV. But at the same time it allows your 
>> module to grow.
>>
>> On Monday, June 19, 2023 at 7:04:24 AM UTC+2 Salvatore Domenick Desiano 
>> wrote:
>>
>>> I've been using Go for almost a decade and I still don't have a library 
>>> package structure I like. I'm hoping I can post what I want here and 
>>> someone can tell me either (a) what the idiomatic way of doing this is, or 
>>> (a) how to break the dependency cycle.
>>>
>>> Let's imagine we're building the fancy Gopher Client library. What I 
>>> want is:
>>>
>>>    - *gopher*: public POD (plain old data) types, public interfaces, 
>>>    func NewClient(), struct clientImpl
>>>    - *gopher/testing*: func NewFakeClient(), struct fakeClientImpl, all 
>>>    testing-specific code (*not* gopher _test files... just code for 
>>>    *other* libraries that want a fake of this one)
>>>    - *gopher/internal*: internal types, implementation details shared 
>>>    between gopher and gopher/testing.
>>>
>>> This doesn't work. Having POD types in gopher means that everything else 
>>> has to depend on it. This means that NewClient() can't be in gopher because 
>>> it would depend on gopher/internal (shared implementation details) and 
>>> gopher/internal depends on gopher (PODs).
>>>
>>> At various points I've tried:
>>>
>>>    - Collapse gopher and gopher/internal. This works, but requires 
>>>    private types to be available to gopher/testing.
>>>    - Collapse all three. This works but I really don't like having Fake 
>>>    code in the same package as real code.
>>>    - Create gopher/gophermodel for the PODs and interfaces. This works, 
>>>    but it's really ugly to have to refer to the PODS as (for example) 
>>>    gophermodel.Response.
>>>    - Create gopher/gopherclient for NewClient() and clientImpl. This is 
>>>    probably the least ugly but it still feel strange to call 
>>>    gopherclient.New() and have the PODs in gopher.
>>>
>>> What am I missing?
>>>
>>> Thank you!
>>>
>>> -- Salvatore
>>> smile.
>>>
>>>

-- 
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/6354aa27-06ff-4fee-bc9a-7afd2ed81e09n%40googlegroups.com.

Reply via email to