Honestly I think the issue you're having here is that due to the waterbed
theory of complexity the fact you have an object trying to really do two
things causes ugly to burst out in unseemly places.

When I say do two things what I mean is not only are you trying to include
all of the business logic for your behavior, but you're trying to turn it
into a serialization and (potentially) storage engine too. Is it any wonder
that any of the solutions you come up with involve short cuts, or
"useless appendices of code" to deal with the extra burden of complexity
you're putting onto the object?

The better solution here is to make your serialization and storage
framework orthogonal to the business logic objects. This is the approach
that KiokuDB attempts to make, how I use DBIx::Class, and how I would
integrate in other storage solutions. At the most MX::Storage should
provide the serialization hooks for a home-grown object persistance layer.
The fact MX::Storage does File IO is at best a useful rookie mistake.

I'd love to claim that MooseX::Storage wasn't intended for doing the kind
of serialization you're talking about, but I'd be lying. The reason
MX::Storage has File IO is because I wanted to re-use the trust
serialization that Bender already did. However in the intervening 6 years
I've grown to have the opinion that except in a limited set of
circumstances persistance is best done as a third party service, and likely
that's where serialization should happen too. Otherwise you end up
overloading your objects and adding back in complexity that simply doesn't
belong there.

-Chris


On Fri, Jul 5, 2013 at 2:53 PM, Buddy Burden <barefootco...@gmail.com>wrote:

> Jesse,
>
>
>  There's nothing stopping you from using delegation in this case either.
>> All you have to do is make the object you delegate to consume both your
>> API role and MooseX::Storage, and then have the rest of your code just
>> use the API role. Using excludes is basically always the wrong answer.
>>
>> For instance:
>>
>>    package MyStorage;
>>    use Moose::Role;
>>
>>    requires 'load', 'store';
>>
>>    package MyPersistentThing;
>>    use Moose;
>>
>>    # MooseX::Storage implements 'load' and 'store'
>>    with 'MyStorage', 'MooseX::Storage';
>>
>>    # ...
>>
>>    package MyClass;
>>    use Moose;
>>
>>    has persistent_thing => (
>>        is      => 'ro',
>>        does    => 'MyStorage',
>>        handles => 'MyStorage', # this delegates only 'load' and 'store'
>>    );
>>
>
> Hmmmm ... so, invent a whole new class whose sole purpose is to make it so
> I don't have to use `excludes`?  Respectfully, I'm not sure I can see that
> as better.  It appears to be multiplying entities beyond necessity, first
> of all, and it adds a layer in my modeling that's bound to be confusing to
> whoever comes after.  One of the things I absolutely love about roles is
> that they effectively increase the expressiveness of your modeling by
> adding adjectives to your nouns and verbs.  This solution turns turns my
> adjective into a noun, making my sentence a lot more awkward.
>
> I think that _if_ I were going to do something like this, I'd rather move
> the useless noun down a layer (or up a layer, depending on your POV).  I
> could create a class which consumes MooseX::Storage, and then have an
> attribute of that class in MyStorage.  At least that way the ugliness would
> be hidden from the client.  The modeling would still be rough, but you
> could try to think of it like implementing "Feathery" in terms of
> "Bird-Like" and needing to have a "Bird" in there somewhere. Sort of.
>
> I'm still not convinced that's a better solution than using `excludes`
> though.
>
> So I guess I'm saying that I'm perfectly willing to accept your assertion
> that "Using excludes is basically always the wrong answer" ... but only if
> you can give me a better one. ;->
>
>
>                 -- Buddy
>

Reply via email to