Shared Models in Different Modules

View: New views
7 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 | Next >

Re: Shared Models in Different Modules

by digitalus_media :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I also agree with the other posts that suggested setting up a users module.  

If the table is a real core table that many different models will both read and write to (like content in a cms) I would suggest setting up a core model, then extending this with your module's models.  this way your news model can write to the content model, but enforce news specific logic.



Let say we have a user table in the database used by the website that has different modules - blog, news, forums, etc. Where will you put the user class module in the application that is going to be used by all the modules?

Regards,

Maru
Ralph Schindler wrote:
I'll chime in here with some contextual background, perhaps that might
help you understand the ideas at play.

One important notion to keep in mind is the difference between library
layer code and application layer code.  Essentially, all Zend Framework
components are considered "library" code.  They are unit testable, live
in a very well defined pseudo-namespace and as such are named according
to the pseudo-namespace rule.  IE: Zend_Loader is Zend/Loader.php.  The
reason this works so well is b/c there is a requirement that ZF exists
inside PHP's include_path.

On the other side of the coin is the application layer code.  This
includes (But is not limited to current) View Scripts, Controller
Scripts and Models.  Typically, in ZF's MVC file structure, they can be
found in ./moduleName/views/, ./moduleName/controllers/, and
./moduleName/models/ respectively.  Bear in mind, these paths ARE NOT i
your php-inclue path.

Moving along, (this is a matter of personal taste), I prefer model
purism in my model classes and objects.  This means that I typcially
name my models (for example): Blog_User.  This means that the model
class User exists within the realm of the Blog module.  This naming
convention keeps the class names away from collisions as well as
provides the simplest cleanest name for my application to reference.

Another note (from my personal perspective), is that is A GOOD THING (r)
that the word controller is in the controller file name as that removes
itself from potential confusion between model file names and controller
files (its serves as a visual cue).  But that can be argued either way.

ALL OF THAT SAID: there is a solution for loading classes and files at
runtime that do not exist inside PHP's include_path.  If you look in the
incubator, you will see Zend/Loader/PluginLoader.php.  It will be
documented over the next week and half, and I think you will find it
immensely useful when it comes to loading application-layer code with
arbitrary (developer friendly) namings in arbitrary (again read:
developer friendly) file locations.

The future of ModelLoader btw, will be revisited once PluginLoader is
fully documented.

Hope that helps,
Ralph

AmirBehzad Eslami wrote:
> That's exactly what i am talking about it, and, yes, it requires a
> massive shift.
>
> Why should we use:
> $this->_helper->ModuleLoader('News_Story');
> instead of:
> Zend_Loader::loadClass('News_Story');
> ?
>
> To achieve this, we should follow a consistent naming scheme
> among controllers and models, and that scheme should be compatible
> with Zend_Loader.
>
> Forget the models for a moment, but the inconsistency still remains:
> *Currently, we name our controllers X_Y_Z,
> but we store them in X/controllers/ZY.php !*
>
> What's wrong with: X/Y/Z.php ? It's compatible with Zend_Loader.
>
> Zend_Loader and its scheme is created to facilitate loading classes in a
> Modular-MVC architecute, whereas it is currently unable to achieve this,
> because of inconsistent naming schemes.
>
> Zend_Loader::loadClass('Foo_Controller_Bar');
> // loads: foo/controllers/bar.php
>
> Zend_Loader::loadClass('Foo_Model_Bar');
> // loads: foo/models/bar.php
>
> Not only this naming scheme keeps the directory structure which is
> recommend in the manual, but also it allows the Zend_Loader to load
> every class in the MVC-architecture, and no patches is required.


Re: Shared Models in Different Modules

by Jens Ljungblad :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This is one of the things that has made me a sceptic of the whole concept of modules. Several people here has spoken about the copy & paste nature of modules, but I have yet to see this actually work.

If a module would be completely stand-alone, that's one thing, but if you start creating "shared" modules, such as a User module, things start to unravel. Once you introduce dependancies between modules you loose the point of having them in the first place: them being isolated, stand-alone packages.

For example:

You develop a User module, which in turn is used by a Blog module. You add functionality to display user profiles to your User module, and, what the heck, the ability to display the user's blog posts. Now you've ended up with two modules that each depend on each other. It's not possible to drop either one into a new project without also including the other. If you've introduced even more modules and dependancies, say a News module which also depends on the User module.. Yeah, you get the picture.

Modules seem to be an organisatory tool at best, or rather, that's my experience. They might work when each module is a separate "application" that never interacts with anything outside of itself, but I've yet to work on such a project. :)

I'd love to hear from other ZF developers on this topic.

Regards,
Jens Ljungblad



I also agree with the other posts that suggested setting up a users module.  

If the table is a real core table that many different models will both read and write to (like content in a cms) I would suggest setting up a core model, then extending this with your module's models.  this way your news model can write to the content model, but enforce news specific logic.


mmaru wrote:
Let say we have a user table in the database used by the website that has different modules - blog, news, forums, etc. Where will you put the user class module in the application that is going to be used by all the modules?

Regards,

Maru
Ralph Schindler wrote:
I'll chime in here with some contextual background, perhaps that might
help you understand the ideas at play.

One important notion to keep in mind is the difference between library
layer code and application layer code.  Essentially, all Zend Framework
components are considered "library" code.  They are unit testable, live
in a very well defined pseudo-namespace and as such are named according
to the pseudo-namespace rule.  IE: Zend_Loader is Zend/Loader.php.  The
reason this works so well is b/c there is a requirement that ZF exists
inside PHP's include_path.

On the other side of the coin is the application layer code.  This
includes (But is not limited to current) View Scripts, Controller
Scripts and Models.  Typically, in ZF's MVC file structure, they can be
found in ./moduleName/views/, ./moduleName/controllers/, and
./moduleName/models/ respectively.  Bear in mind, these paths ARE NOT i
your php-inclue path.

Moving along, (this is a matter of personal taste), I prefer model
purism in my model classes and objects.  This means that I typcially
name my models (for example): Blog_User.  This means that the model
class User exists within the realm of the Blog module.  This naming
convention keeps the class names away from collisions as well as
provides the simplest cleanest name for my application to reference.

Another note (from my personal perspective), is that is A GOOD THING (r)
that the word controller is in the controller file name as that removes
itself from potential confusion between model file names and controller
files (its serves as a visual cue).  But that can be argued either way.

ALL OF THAT SAID: there is a solution for loading classes and files at
runtime that do not exist inside PHP's include_path.  If you look in the
incubator, you will see Zend/Loader/PluginLoader.php.  It will be
documented over the next week and half, and I think you will find it
immensely useful when it comes to loading application-layer code with
arbitrary (developer friendly) namings in arbitrary (again read:
developer friendly) file locations.

The future of ModelLoader btw, will be revisited once PluginLoader is
fully documented.

Hope that helps,
Ralph

AmirBehzad Eslami wrote:
> That's exactly what i am talking about it, and, yes, it requires a
> massive shift.
>
> Why should we use:
> $this->_helper->ModuleLoader('News_Story');
> instead of:
> Zend_Loader::loadClass('News_Story');
> ?
>
> To achieve this, we should follow a consistent naming scheme
> among controllers and models, and that scheme should be compatible
> with Zend_Loader.
>
> Forget the models for a moment, but the inconsistency still remains:
> *Currently, we name our controllers X_Y_Z,
> but we store them in X/controllers/ZY.php !*
>
> What's wrong with: X/Y/Z.php ? It's compatible with Zend_Loader.
>
> Zend_Loader and its scheme is created to facilitate loading classes in a
> Modular-MVC architecute, whereas it is currently unable to achieve this,
> because of inconsistent naming schemes.
>
> Zend_Loader::loadClass('Foo_Controller_Bar');
> // loads: foo/controllers/bar.php
>
> Zend_Loader::loadClass('Foo_Model_Bar');
> // loads: foo/models/bar.php
>
> Not only this naming scheme keeps the directory structure which is
> recommend in the manual, but also it allows the Zend_Loader to load
> every class in the MVC-architecture, and no patches is required.

Re: Shared Models in Different Modules

by bradley.holt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This is an interesting question that I happen to have given some thought too. First thing I would suggest is to be aware of when you're introducing dependencies between modules and if there might be another way to solve the problem you're trying to solve without introducing cross-module dependencies. Assuming you do, in fact, need to add a cross-module dependency you can always use the design principle of programming to an interface (or an abstract class, this doesn't have to be applied literally). This way you can have a dependency on a User module instead of the specific User module (for example) you happen to be using at the moment. Of course, this leaves open the question as to where the interfaces (or abstract classes) for the module should live because they can't live in the module itself as this would defeat the purpose. Anyone want to take a crack at this problem? I have a few ideas but I'm interested to hear if anyone else has found a solution to this problem.

Another related point, Zend Framework provides two primary ways (that I'm aware of - please correct me if I get this wrong) in which it can be extended: either through components or modules. Components are library items either in your own namespace or in the Zend namespace. Since components are library items, there's a fair bit of "glue" needed to get them working. Modules are ready-to-run code that can be dropped into your application that you can have up-and-running with minimal setup. If you find yourself introducing a lot of cross-module dependencies then perhaps you would be better of creating components instead and then using these components from within your modules.

I would like to have some more guidance from Zend here on best practices for writing MVC modules. If lots of people started following the same practices, we could end up with a situation where there a lot of well-written, modular applications out there that can be wired up to quickly build your application. For example, grab a wiki module and a blog module and throw them into a custom Zend Framework application and quickly have a website with all of these features integrated. Maybe I'm dreaming here :-)

On Wed, Apr 16, 2008 at 6:28 PM, pakmannen <jens.ljungblad@...> wrote:

This is one of the things that has made me a sceptic of the whole concept of
modules. Several people here has spoken about the copy & paste nature of
modules, but I have yet to see this actually work.

If a module would be completely stand-alone, that's one thing, but if you
start creating "shared" modules, such as a User module, things start to
unravel. Once you introduce dependancies between modules you loose the point
of having them in the first place: them being isolated, stand-alone
packages.

For example:

You develop a User module, which in turn is used by a Blog module. You add
functionality to display user profiles to your User module, and, what the
heck, the ability to display the user's blog posts. Now you've ended up with
two modules that each depend on each other. It's not possible to drop either
one into a new project without also including the other. If you've
introduced even more modules and dependancies, say a News module which also
depends on the User module.. Yeah, you get the picture.

Modules seem to be an organisatory tool at best, or rather, that's my
experience. They might work when each module is a separate "application"
that never interacts with anything outside of itself, but I've yet to work
on such a project. :)

I'd love to hear from other ZF developers on this topic.

Regards,
Jens Ljungblad



digitalus_media wrote:
>
> I also agree with the other posts that suggested setting up a users
> module.
>
> If the table is a real core table that many different models will both
> read and write to (like content in a cms) I would suggest setting up a
> core model, then extending this with your module's models.  this way your
> news model can write to the content model, but enforce news specific
> logic.
>
>
>
> mmaru wrote:
>>
>> Let say we have a user table in the database used by the website that has
>> different modules - blog, news, forums, etc. Where will you put the user
>> class module in the application that is going to be used by all the
>> modules?
>>
>> Regards,
>>
>> Maru
>>
>> Ralph Schindler wrote:
>>>
>>> I'll chime in here with some contextual background, perhaps that might
>>> help you understand the ideas at play.
>>>
>>> One important notion to keep in mind is the difference between library
>>> layer code and application layer code.  Essentially, all Zend Framework
>>> components are considered "library" code.  They are unit testable, live
>>> in a very well defined pseudo-namespace and as such are named according
>>> to the pseudo-namespace rule.  IE: Zend_Loader is Zend/Loader.php.  The
>>> reason this works so well is b/c there is a requirement that ZF exists
>>> inside PHP's include_path.
>>>
>>> On the other side of the coin is the application layer code.  This
>>> includes (But is not limited to current) View Scripts, Controller
>>> Scripts and Models.  Typically, in ZF's MVC file structure, they can be
>>> found in ./moduleName/views/, ./moduleName/controllers/, and
>>> ./moduleName/models/ respectively.  Bear in mind, these paths ARE NOT i
>>> your php-inclue path.
>>>
>>> Moving along, (this is a matter of personal taste), I prefer model
>>> purism in my model classes and objects.  This means that I typcially
>>> name my models (for example): Blog_User.  This means that the model
>>> class User exists within the realm of the Blog module.  This naming
>>> convention keeps the class names away from collisions as well as
>>> provides the simplest cleanest name for my application to reference.
>>>
>>> Another note (from my personal perspective), is that is A GOOD THING (r)
>>> that the word controller is in the controller file name as that removes
>>> itself from potential confusion between model file names and controller
>>> files (its serves as a visual cue).  But that can be argued either way.
>>>
>>> ALL OF THAT SAID: there is a solution for loading classes and files at
>>> runtime that do not exist inside PHP's include_path.  If you look in the
>>> incubator, you will see Zend/Loader/PluginLoader.php.  It will be
>>> documented over the next week and half, and I think you will find it
>>> immensely useful when it comes to loading application-layer code with
>>> arbitrary (developer friendly) namings in arbitrary (again read:
>>> developer friendly) file locations.
>>>
>>> The future of ModelLoader btw, will be revisited once PluginLoader is
>>> fully documented.
>>>
>>> Hope that helps,
>>> Ralph
>>>
>>> AmirBehzad Eslami wrote:
>>>> That's exactly what i am talking about it, and, yes, it requires a
>>>> massive shift.
>>>>
>>>> Why should we use:
>>>> $this->_helper->ModuleLoader('News_Story');
>>>> instead of:
>>>> Zend_Loader::loadClass('News_Story');
>>>> ?
>>>>
>>>> To achieve this, we should follow a consistent naming scheme
>>>> among controllers and models, and that scheme should be compatible
>>>> with Zend_Loader.
>>>>
>>>> Forget the models for a moment, but the inconsistency still remains:
>>>> *Currently, we name our controllers X_Y_Z,
>>>> but we store them in X/controllers/ZY.php !*
>>>>
>>>> What's wrong with: X/Y/Z.php ? It's compatible with Zend_Loader.
>>>>
>>>> Zend_Loader and its scheme is created to facilitate loading classes in
>>>> a
>>>> Modular-MVC architecute, whereas it is currently unable to achieve
>>>> this,
>>>> because of inconsistent naming schemes.
>>>>
>>>> Zend_Loader::loadClass('Foo_Controller_Bar');
>>>> // loads: foo/controllers/bar.php
>>>>
>>>> Zend_Loader::loadClass('Foo_Model_Bar');
>>>> // loads: foo/models/bar.php
>>>>
>>>> Not only this naming scheme keeps the directory structure which is
>>>> recommend in the manual, but also it allows the Zend_Loader to load
>>>> every class in the MVC-architecture, and no patches is required.
>>>
>>>
>>>
>>
>>
>
>

--
View this message in context: http://www.nabble.com/Shared-Models-in-Different-Modules-tp14117646p16734950.html
Sent from the Zend MVC mailing list archive at Nabble.com.




--
Bradley Holt
bradley.holt@...


Re: Shared Models in Different Modules

by Jens Ljungblad :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I put off replying to this mail and then forgot all about it, sorry. :-)

bradley.holt wrote:
Assuming you do, in fact, need to add a cross-module
dependency you can always use the design principle of programming to an
interface (or an abstract class, this doesn't have to be applied literally). This way you
can have a dependency on *a* User module instead of *the* specific User
module (for example) you happen to be using at the moment. Of course, this
leaves open the question as to where the interfaces (or abstract classes)
for the module should live because they can't live in the module itself as
this would defeat the purpose. Anyone want to take a crack at this problem?
I have a few ideas but I'm interested to hear if anyone else has found a
solution to this problem.
That's an interesting approach. No idea if it would actually work, but it's always fun to speculate about these things. :-P I'd be interested to hear your ideas on placement. I suppose a module could have a configuration file or similar where those things could be set.

bradley.holt wrote:
If you find yourself introducing a lot of cross-module dependencies then perhaps you would be
better of creating components instead and then using these components from within your modules.
I agree. I tend to favour compontents as often as it makes sense.

bradley.holt wrote:
I would like to have some more guidance from Zend here on best practices for
writing MVC modules. If lots of people started following the same practices,
we could end up with a situation where there a lot of well-written, modular
applications out there that can be wired up to quickly build your
application. For example, grab a wiki module and a blog module and throw
them into a custom Zend Framework application and quickly have a website
with all of these features integrated. Maybe I'm dreaming here :-)
I think you are ;-) But seriously, other frameworks do this with various success. Symfony for instance. It's a tricky area.

Jens Ljungblad

Re: Shared Models in Different Modules

by bradley.holt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jens,

On Mon, May 5, 2008 at 9:06 AM, pakmannen <jens.ljungblad@...> wrote:

I put off replying to this mail and then forgot all about it, sorry. :-)


bradley.holt wrote:
>
> Assuming you do, in fact, need to add a cross-module
> dependency you can always use the design principle of programming to an
> interface (or an abstract class, this doesn't have to be applied
> literally). This way you
> can have a dependency on *a* User module instead of *the* specific User
> module (for example) you happen to be using at the moment. Of course, this
> leaves open the question as to where the interfaces (or abstract classes)
> for the module should live because they can't live in the module itself as
> this would defeat the purpose. Anyone want to take a crack at this
> problem?
> I have a few ideas but I'm interested to hear if anyone else has found a
> solution to this problem.
>
That's an interesting approach. No idea if it would actually work, but it's
always fun to speculate about these things. :-P I'd be interested to hear
your ideas on placement. I suppose a module could have a configuration file
or similar where those things could be set.

In my other (non-PHP) job I am currently working with a .NET dependency injection framework called the Composite UI Application Block (CAB). The CAB has an interesting approach to cross-module dependencies. For every module you create, you also create an "interface" version of the module where your interfaces and/or abstract classes live (from now on I'll just say "interfaces" but I mean both interfaces and/or abstract classes). Any other modules that have dependencies on your module actual depend on the interfaces in the "Interface" version of the module. For example, ModuleA has all your implementation code and ModuleA.Interface has all of your interfaces. ModuleB references the interfaces in ModuleA.Interface, *not* in ModuleA itself. This setup strictly enforces the concept of programming to an interface. In other words, your contracts are defined in ModuleA.Interface and this leaves you free to change the implementation code in ModuleA as long as you don't break the contract (or you can renegotiate the contract through refactoring). Of course, this setup works best with dependency injection which we don't currently have in ZF. You can still do this manually without dependency injection (using Zend_Registry or manually instantiating dependencies but declaring the type as the interface type), but you need to be a little more careful about not introducing implementation dependencies.

Applying this concept to ZF, there are a few options as to where the equivalent ModuleA.Interface could live. You could literally create two different modules, one for your implementation code and one for your interfaces. However, this probably doesn't make a lot of sense within the context of ZF as these are MVC modules and since the "Interface" module wouldn't have any implementation code it also wouldn't have any action controllers which would be somewhat odd.

A simple option would be for all of your interfaces to simply live in your module. This is a generally a good idea anyways if you want to follow the design principle of programming to an interface. However, it doesn't solve the initial goal of being able to swap out implementation modules since your interfaces live in your module. But, this is probably "good enough" for most situations.

Probably the best option would be to define the interfaces in a component in your library directory. Then, you can write your implementation code in your module. Assuming you write all of your cross-module dependencies based on the interfaces in your component, you can now easily swap out different implementation modules. For example, define a "Blog" component that has all of the interfaces that define blog-like functionality (or at least the interfaces that other modules would need access to). Next, create a "blog" module that implements the interfaces in your "Blog" component. You now have relatively clean cross-module dependencies. You also have the added-benefit if being able to create a better "blog" module in the future (let's call it "blogreloaded") and replace your old "blog" module with a small amount of work (assuming you were good about basing your dependencies on the interfaces in the "Blog" component and not the "blog" module itself).
   
 



bradley.holt wrote:
>
> If you find yourself introducing a lot of cross-module dependencies then
> perhaps you would be
> better of creating components instead and then using these components from
> within your modules.
>
I agree. I tend to favour compontents as often as it makes sense.


bradley.holt wrote:
>
> I would like to have some more guidance from Zend here on best practices
> for
> writing MVC modules. If lots of people started following the same
> practices,
> we could end up with a situation where there a lot of well-written,
> modular
> applications out there that can be wired up to quickly build your
> application. For example, grab a wiki module and a blog module and throw
> them into a custom Zend Framework application and quickly have a website
> with all of these features integrated. Maybe I'm dreaming here :-)
>
I think you are ;-) But seriously, other frameworks do this with various
success. Symfony for instance. It's a tricky area.

Yes, it's definitely a tricky area. I think the design principle of programming to an interface could help with this. Using the suggestion I just made about defining interfaces in a component and implementation in a module, people could work together to define what parts of , say, a blog or wiki application need to be exposed for cross-module dependencies. The interfaces for this could be defined in commonly distributed components (perhaps even provided as part of ZF). Then, individuals can decide exactly how they want to implement a blog or wiki (again, these are just examples, you can apply this to any type of application) and write their own modules based on these components. Basically, the idea is by separating out interface definitions from implementation definitions it is more likely you can get a bunch of people on the same page while still leaving implementation details up to individual programmers. Perhaps I'm still dreaming here :-)
 


Jens Ljungblad
--
View this message in context: http://www.nabble.com/Shared-Models-in-Different-Modules-tp14117646p17061249.html
Sent from the Zend MVC mailing list archive at Nabble.com.




--
Bradley Holt
bradley.holt@...


Re: Shared Models in Different Modules

by lcrouch :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

while I agree with the idea of coding to an interface to enhance modularity, I think it's dangerous business to start down that path too heavily at the outset of a project.

I think the most sensible and practical thing to do is, when you're writing module-dependent code, ask yourself how likely it will be that you will re-use the module later. only if you are likely to re-use it should you worry about abstracting everything up into interfaces.

-L

On Mon, May 5, 2008 at 10:25 AM, Bradley Holt <bradley.holt@...> wrote:
Jens,

On Mon, May 5, 2008 at 9:06 AM, pakmannen <jens.ljungblad@...> wrote:

I put off replying to this mail and then forgot all about it, sorry. :-)


bradley.holt wrote:
>
> Assuming you do, in fact, need to add a cross-module
> dependency you can always use the design principle of programming to an
> interface (or an abstract class, this doesn't have to be applied
> literally). This way you
> can have a dependency on *a* User module instead of *the* specific User
> module (for example) you happen to be using at the moment. Of course, this
> leaves open the question as to where the interfaces (or abstract classes)
> for the module should live because they can't live in the module itself as
> this would defeat the purpose. Anyone want to take a crack at this
> problem?
> I have a few ideas but I'm interested to hear if anyone else has found a
> solution to this problem.
>
That's an interesting approach. No idea if it would actually work, but it's
always fun to speculate about these things. :-P I'd be interested to hear
your ideas on placement. I suppose a module could have a configuration file
or similar where those things could be set.

In my other (non-PHP) job I am currently working with a .NET dependency injection framework called the Composite UI Application Block (CAB). The CAB has an interesting approach to cross-module dependencies. For every module you create, you also create an "interface" version of the module where your interfaces and/or abstract classes live (from now on I'll just say "interfaces" but I mean both interfaces and/or abstract classes). Any other modules that have dependencies on your module actual depend on the interfaces in the "Interface" version of the module. For example, ModuleA has all your implementation code and ModuleA.Interface has all of your interfaces. ModuleB references the interfaces in ModuleA.Interface, *not* in ModuleA itself. This setup strictly enforces the concept of programming to an interface. In other words, your contracts are defined in ModuleA.Interface and this leaves you free to change the implementation code in ModuleA as long as you don't break the contract (or you can renegotiate the contract through refactoring). Of course, this setup works best with dependency injection which we don't currently have in ZF. You can still do this manually without dependency injection (using Zend_Registry or manually instantiating dependencies but declaring the type as the interface type), but you need to be a little more careful about not introducing implementation dependencies.

Applying this concept to ZF, there are a few options as to where the equivalent ModuleA.Interface could live. You could literally create two different modules, one for your implementation code and one for your interfaces. However, this probably doesn't make a lot of sense within the context of ZF as these are MVC modules and since the "Interface" module wouldn't have any implementation code it also wouldn't have any action controllers which would be somewhat odd.

A simple option would be for all of your interfaces to simply live in your module. This is a generally a good idea anyways if you want to follow the design principle of programming to an interface. However, it doesn't solve the initial goal of being able to swap out implementation modules since your interfaces live in your module. But, this is probably "good enough" for most situations.

Probably the best option would be to define the interfaces in a component in your library directory. Then, you can write your implementation code in your module. Assuming you write all of your cross-module dependencies based on the interfaces in your component, you can now easily swap out different implementation modules. For example, define a "Blog" component that has all of the interfaces that define blog-like functionality (or at least the interfaces that other modules would need access to). Next, create a "blog" module that implements the interfaces in your "Blog" component. You now have relatively clean cross-module dependencies. You also have the added-benefit if being able to create a better "blog" module in the future (let's call it "blogreloaded") and replace your old "blog" module with a small amount of work (assuming you were good about basing your dependencies on the interfaces in the "Blog" component and not the "blog" module itself).
   
 



bradley.holt wrote:
>
> If you find yourself introducing a lot of cross-module dependencies then
> perhaps you would be
> better of creating components instead and then using these components from
> within your modules.
>
I agree. I tend to favour compontents as often as it makes sense.


bradley.holt wrote:
>
> I would like to have some more guidance from Zend here on best practices
> for
> writing MVC modules. If lots of people started following the same
> practices,
> we could end up with a situation where there a lot of well-written,
> modular
> applications out there that can be wired up to quickly build your
> application. For example, grab a wiki module and a blog module and throw
> them into a custom Zend Framework application and quickly have a website
> with all of these features integrated. Maybe I'm dreaming here :-)
>
I think you are ;-) But seriously, other frameworks do this with various
success. Symfony for instance. It's a tricky area.

Yes, it's definitely a tricky area. I think the design principle of programming to an interface could help with this. Using the suggestion I just made about defining interfaces in a component and implementation in a module, people could work together to define what parts of , say, a blog or wiki application need to be exposed for cross-module dependencies. The interfaces for this could be defined in commonly distributed components (perhaps even provided as part of ZF). Then, individuals can decide exactly how they want to implement a blog or wiki (again, these are just examples, you can apply this to any type of application) and write their own modules based on these components. Basically, the idea is by separating out interface definitions from implementation definitions it is more likely you can get a bunch of people on the same page while still leaving implementation details up to individual programmers. Perhaps I'm still dreaming here :-)
 


Jens Ljungblad
--
View this message in context: http://www.nabble.com/Shared-Models-in-Different-Modules-tp14117646p17061249.html
Sent from the Zend MVC mailing list archive at Nabble.com.




--
Bradley Holt
bradley.holt@...



Re: Shared Models in Different Modules

by bradley.holt :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Luke,

On Mon, May 5, 2008 at 2:16 PM, Luke Crouch <luke.crouch@...> wrote:
while I agree with the idea of coding to an interface to enhance modularity, I think it's dangerous business to start down that path too heavily at the outset of a project.

Agreed. Unless you already have a very clear picture of what your API will look like (most likely through detailed specs) then programming to an interface from the beginning is probably just busy-work. One exception is if you're doing test-driven development and want to be able to use mock objects (thus you need interfaces).

I think the most sensible and practical thing to do is, when you're writing module-dependent code, ask yourself how likely it will be that you will re-use the module later. only if you are likely to re-use it should you worry about abstracting everything up into interfaces.

I think there is a benefit to using interfaces for module code that will be depended on by other modules (for everything else, see above). These interfaces give you a place to clearly define the contracts your module is making with other modules. I'm not saying there aren't other ways to define contracts, just that interfaces are one nice way to have your modules loosely coupled. For most cases, simply placing these interfaces within the module's code is probably fine - just as long as it's clear what is "contract" code and what is "implementation" code.
 


-L


On Mon, May 5, 2008 at 10:25 AM, Bradley Holt <bradley.holt@...> wrote:
Jens,

On Mon, May 5, 2008 at 9:06 AM, pakmannen <jens.ljungblad@...> wrote:

I put off replying to this mail and then forgot all about it, sorry. :-)


bradley.holt wrote:
>
> Assuming you do, in fact, need to add a cross-module
> dependency you can always use the design principle of programming to an
> interface (or an abstract class, this doesn't have to be applied
> literally). This way you
> can have a dependency on *a* User module instead of *the* specific User
> module (for example) you happen to be using at the moment. Of course, this
> leaves open the question as to where the interfaces (or abstract classes)
> for the module should live because they can't live in the module itself as
> this would defeat the purpose. Anyone want to take a crack at this
> problem?
> I have a few ideas but I'm interested to hear if anyone else has found a
> solution to this problem.
>
That's an interesting approach. No idea if it would actually work, but it's
always fun to speculate about these things. :-P I'd be interested to hear
your ideas on placement. I suppose a module could have a configuration file
or similar where those things could be set.

In my other (non-PHP) job I am currently working with a .NET dependency injection framework called the Composite UI Application Block (CAB). The CAB has an interesting approach to cross-module dependencies. For every module you create, you also create an "interface" version of the module where your interfaces and/or abstract classes live (from now on I'll just say "interfaces" but I mean both interfaces and/or abstract classes). Any other modules that have dependencies on your module actual depend on the interfaces in the "Interface" version of the module. For example, ModuleA has all your implementation code and ModuleA.Interface has all of your interfaces. ModuleB references the interfaces in ModuleA.Interface, *not* in ModuleA itself. This setup strictly enforces the concept of programming to an interface. In other words, your contracts are defined in ModuleA.Interface and this leaves you free to change the implementation code in ModuleA as long as you don't break the contract (or you can renegotiate the contract through refactoring). Of course, this setup works best with dependency injection which we don't currently have in ZF. You can still do this manually without dependency injection (using Zend_Registry or manually instantiating dependencies but declaring the type as the interface type), but you need to be a little more careful about not introducing implementation dependencies.

Applying this concept to ZF, there are a few options as to where the equivalent ModuleA.Interface could live. You could literally create two different modules, one for your implementation code and one for your interfaces. However, this probably doesn't make a lot of sense within the context of ZF as these are MVC modules and since the "Interface" module wouldn't have any implementation code it also wouldn't have any action controllers which would be somewhat odd.

A simple option would be for all of your interfaces to simply live in your module. This is a generally a good idea anyways if you want to follow the design principle of programming to an interface. However, it doesn't solve the initial goal of being able to swap out implementation modules since your interfaces live in your module. But, this is probably "good enough" for most situations.

Probably the best option would be to define the interfaces in a component in your library directory. Then, you can write your implementation code in your module. Assuming you write all of your cross-module dependencies based on the interfaces in your component, you can now easily swap out different implementation modules. For example, define a "Blog" component that has all of the interfaces that define blog-like functionality (or at least the interfaces that other modules would need access to). Next, create a "blog" module that implements the interfaces in your "Blog" component. You now have relatively clean cross-module dependencies. You also have the added-benefit if being able to create a better "blog" module in the future (let's call it "blogreloaded") and replace your old "blog" module with a small amount of work (assuming you were good about basing your dependencies on the interfaces in the "Blog" component and not the "blog" module itself).
   
 



bradley.holt wrote:
>
> If you find yourself introducing a lot of cross-module dependencies then
> perhaps you would be
> better of creating components instead and then using these components from
> within your modules.
>
I agree. I tend to favour compontents as often as it makes sense.


bradley.holt wrote:
>
> I would like to have some more guidance from Zend here on best practices
> for
> writing MVC modules. If lots of people started following the same
> practices,
> we could end up with a situation where there a lot of well-written,
> modular
> applications out there that can be wired up to quickly build your
> application. For example, grab a wiki module and a blog module and throw
> them into a custom Zend Framework application and quickly have a website
> with all of these features integrated. Maybe I'm dreaming here :-)
>
I think you are ;-) But seriously, other frameworks do this with various
success. Symfony for instance. It's a tricky area.

Yes, it's definitely a tricky area. I think the design principle of programming to an interface could help with this. Using the suggestion I just made about defining interfaces in a component and implementation in a module, people could work together to define what parts of , say, a blog or wiki application need to be exposed for cross-module dependencies. The interfaces for this could be defined in commonly distributed components (perhaps even provided as part of ZF). Then, individuals can decide exactly how they want to implement a blog or wiki (again, these are just examples, you can apply this to any type of application) and write their own modules based on these components. Basically, the idea is by separating out interface definitions from implementation definitions it is more likely you can get a bunch of people on the same page while still leaving implementation details up to individual programmers. Perhaps I'm still dreaming here :-)
 


Jens Ljungblad
--
View this message in context: http://www.nabble.com/Shared-Models-in-Different-Modules-tp14117646p17061249.html
Sent from the Zend MVC mailing list archive at Nabble.com.




--
Bradley Holt
bradley.holt@...





--
Bradley Holt
bradley.holt@...

< Prev | 1 - 2 - 3 | Next >