Modules in Yii

There are two problems Yii modules could solve:

  1. Grouping alike functionality.

  2. Isolating functionality for future reuse within different projects.

When Yii core team developed modules the purpose was always about both. When it went into the wild, community started using modules for grouping only more often than for isolation which is understandable since proper isolation is hard to achieve. If the module is isolated it never uses anything from outside of it. If it needs something, it provides an interface to be implemented by the one using the module. Same applies the other way around i.e. external usage of the module internals is strictly prohibited except what’s provided by module’s interfaces.

the way to go for modular approach is to always go right of the forward slash "/" always


//../../../

and never


../../../..//

right?

But i do have some question about the best approaches.

Assume i have 2 module:

  • User

  • Article

Both can live on their own. That is User does not have anything to do with Article and vice versa.

But now i want to couple these 2, i.e. implement some sort of liking and commenting system. What is the best way to do it?

I didn’t get that about slashes…

About coupling of modules, use contract via interface instead. For example, in article module each post has author and we’re displaying author name after the article. Since we don’t want to couple to particular user implementation, we’re introducing interfaces which are provided by article module:




interface ArticleInterace

{

    public function getAuthorName();


    // ...

}


inteface ArticleRepositoryInterface

{

    public function getById($id);

    public function getPage($page);

}



Then in the module itself we’re using interfaces only and providing a way to set ArticleRepositoryInterface implementation in the module config. When module is to be used, developer has to implement these interfaces. It is typically simple, straightforward and, if interface is designed well, provides excellent flexibility.

well from the root of the module… we can use all files that comes right of the root:


module_root/folder_x/file.y

and we shoul avoid going to any file which comes left of the root


file.a/folder_b/module_root

Because of these little needs, i tend to add coupling to some of my modules which results in a mess and confusion amond developers. Is this a repository design pattern?

I do get an idea about what you mentioned but i feel still kind of lost.

Designing the interfaces and implementing them seems easy enough but what do you mean about “Then in the module itself we’re using interfaces only and providing a way to set ArticleRepositoryInterface implementation in the module config.”

I think an example would really be helpful in this case.

Ah, yes. Directly accessing files not within the module isn’t good.

No. The repository was just an example. That’s about SOLID principles in general and proper encapsulation within the module.

Designing interfaces is hard. I’ll write a cookbook tutorial about that but a bit later.

Ahh great, looking forward to it. Thanks

IAC (Interactive Application Communication). This requirement was solved in the original HMVC and PAC architectures using event/listener schemes. There should be plenty of docs on the web to outline the details as well as source code PHP source code on SourceForge. My mind might be regressing, but I think this was solved at least on the component level with the original PRADO framework. Ask Qiang Xue.

Say a module’s config file listed mandatory dependencies and optional dependencies. Based on the configuration, a Article module would broadcast events and other modules could listen for those events. If the existance of a User module was an absolute requirement for initialization, the module would be in a position to fully initialize if the User module broadcast an acknowledgement event. If not, it would fail to initialize. If SEO, Comments, and Taxonomy modules were listed as optional dependencies in the config file, The Article module could use those services or any subset of those services if they broadcast an acknowledgement event. This pretty much applies to any service-like module using pivot tables.

One could probably mimic the same process using RPCs or SOAP or another IAC protocol. Not sure, but I think someone tried to do this for 1.1.