0

I'm not so sure the title is a good match for this question I want to put on the table.

I'm planning to create a web MVC framework as my graduation dissertation and in a previous conversation with my advisor trying to define some achivements, he convinced me that I should choose a modular design in this project.

I already had some things developed by then and stopped for a while to analyze how much modular it would be and I couldn't really do it because I don't know the real meaning of "modular".

Some things are not very cleary for me, like for example, just referencing another module blows up the modularity of my system?

Let's say I have a Database Access module and it OPTIONALY can use a Cache module for storing results of complex queries. As anyone can see, I at least will have a naming dependency for the cache module.

In my conception of "modular design", I can distribute each component separately and make it interact with others developed by other people. In this case I showed, if someone wants to use my Database Access module, they will have to take the Cache as well, even if he will not use it, just for referencing/naming purposes.

And so, I was wondering if this is really a modular design yet.

I came up with an alternative that is something like creating each component singly, without don't even knowing about the existance of other components that are not absolutely required for its functioning. To extend functionalities, I could create some structure based on Decorators and Adapters.

To clarify things a little bit, here is an example (in PHP):

Before

interface Cache {
    public function isValid();
    public function setValue();
    public function getValue();
}

interface CacheManager {
    public function get($name);
    public function put($name, $value);
}

// Some concrete implementations...

interface DbAccessInterface {
    public doComplexOperation();
}

class DbAccess implements DbAccessInterface {
    private $cacheManager;

    public function __construct(..., CacheManager $cacheManager = null) {
        // ...
        $this->cacheManager = $cacheManager;
    }

    public function doComplexOperation() {
        if ($this->cacheManager !== null) {
            // return from cache if valid
        } 
        // complex operation
    }
}

After

interface Cache {
    public function isValid();
    public function setValue();
    public function getValue();
}

interface CacheManager {
    public function get($name);
    public function put($name, $value);
}

// Some concrete implementations...

interface DbAccessInterface {
    public function doComplexOperation();
}

class DbAccess implements DbAccessInterface {
    public function __construct(...) {
        // ...
    }

    public function doComplexQuery() {
        // complex operation
    }
}

// And now the integration module

class CachedDbAcess implements DbAccessInterface {
    private $dbAccess;
    private $cacheManager;

    public function __construct(DbAccessInterface $dbAccess, CacheManager $cacheManager) {
        $this->dbAccess = $dbAccess;
        $this->cacheManager = $cacheManager;
    }

    public function doComplexOperation() {
        $cache = $this->cacheManager->get("Foo")
        if($cache->isValid()) {
            return $cache->getValue();
        }
        // Do complex operation...
    }
}

Now my question is: Is this the best solution? I should do this for all the modules that do not have as a requirement work together, but can be more efficient doing so?

Anyone would do it in a different way?

I have some more further questions involving this, but I don't know if this is an acceptable question for stackoverflow.

P.S.: English is not my first language, maybe some parts can get a little bit confuse

Bart
  • 17,070
  • 5
  • 61
  • 80
Henrique Barcelos
  • 7,670
  • 1
  • 41
  • 66
  • mvc framework as graduation dissertation? sounds good. and to the design pattern: google for building up a plugin system, it's nearly the same (abstract class gets implemented with a factory). – ultima_rat0 May 19 '13 at 23:54
  • I thought about plugins, but not so sure if is the same thing. Plugins are made to extend the functionality of a system, in my case, it will the a PART of the system. – Henrique Barcelos May 19 '13 at 23:58
  • You can rate some plugins as necessary. I think of it as implementations of abstract classes, like a db-interface and a sqlite-plugin or a mysql-plugin with a standard-plugin as normal interface. – ultima_rat0 May 20 '13 at 00:16
  • Yes, but this you're saying is INTRAmodule, seem easier when is like this. What is twisting my mind is this INTERmodule thing... – Henrique Barcelos May 20 '13 at 00:22
  • You have some ModuleManager and you give to every Module a Reference to the ModuleManager so the Module can handle and work with other modules. – ultima_rat0 May 20 '13 at 00:23

3 Answers3

1

Some resources (not theoretical):

Community
  • 1
  • 1
ultima_rat0
  • 290
  • 2
  • 8
  • Nice... I'll look into it a little bit... Thank's... Any other suggestions are welcome too. I have like 2 months to decide for a line of work and go back to my adivsor with something more concrete, in this time, I'll dig int everything I can... – Henrique Barcelos May 20 '13 at 00:24
  • Good luck! it's hard to get a concrete starting point, I hope it helps a bit. – ultima_rat0 May 20 '13 at 00:28
1

I came up with an alternative that is something like creating each component singly, without don't even knowing about the existance of other components that are not absolutely required for its functioning

It is great if you came up with this idea by yourself. The statement itself, is a key to modular programming.

Plugin architecture is the best in terms of extensibility, but imho it is hard to maintenance especially in intra application. And depending the complexity of plugin architecture, it can make your code more complex by adding plugin logics, etc.

Thus, for intra modular design, I choose the N-Tier, interface based architecture. Basically, the architecture relays on those tiers:

  1. Domain / Entity
  2. Interface [Depend on 1]
  3. Services [Depend on 1 and 2]
  4. Repository / DAL [Depend on 1 and 2]
  5. Presentation Layer [Depend on 1,2,3,4]

Unfortunately, I don't think this is achieveable neatly in php projects as it need separated project / dll references in each tier. However, following the architecture can help to modularize the application.

For each modules, we need to do interface-based design. It can help to enhance the modularity of your code, because you can change the implementation later, but still keep the consumer the same.

I have provided an answer similiar to this interface-based design, at this stackoverflow question.

Lastly but not least, if you want to make your application modular to the UI, you can do Service Oriented Architecture. This is simply make your application as bunch of services, and then make the UI to consume the service. This design can help to separate your UI with your logic. You can later use different UI such as desktop app, but still use the same logic. Unfortunately, I don't have any reliable source for SOA.

EDIT:

I misunderstood the question. This is my point of view about modular framework. Unfortunately, I don't know much about Zend so I will give examples in C#:

  • It consist of modules, from the smallest to larger modules. Example in C# is you can using the Windows Form (larger) at your application, and also the Graphic (smaller) class to draw custom shapes in the screen.
  • It is extensible, or replaceable without making change to base class. In C# you can assign FormLoad event (extensible) to the Form class, inherit the Form or List class (extensible) or overridding form draw method to create a custom window graphic (replaceable).
  • (optional) it is easy to use. In normal DI interface design, we usually inject smaller modules into a larger (high level) module. This will require an IOC container. Refer to my question for detail.
  • Easy to configure, and does not involve any magical logic such as Service Locator Pattern. Search Service Locator is an Anti Pattern in google.

I don't know much about Zend, however I guess that the modularity in Zend can means that it can be extended without changing the core (replacing the code) inside framework.

If you said that:

if someone wants to use my Database Access module, they will have to take the Cache as well, even if he will not use it, just for referencing/naming purposes.

Then it is not modular. It is integrated, means that your Database Access module will not work without Cache. In reference of C# components, it choose to provide List<T> and BindingList<T> to provide different functionality. In your case, imho it is better to provide CachedDataAccess and DataAccess.

Community
  • 1
  • 1
Fendy
  • 4,565
  • 1
  • 20
  • 25
  • Thank's for your feedback. Yes, I also answered the very same question you pointed =). I have no problems with **design for an interface**, at application level I have some real cases implemented, but what is catching me is doing this at a lower level (the framework itself). I don't really understand why ZF2 or Symfony2 can call themselves **modular** frameworks. I never used neither of them seriously, but just reading the docs you can see that are lots of intermodule references. – Henrique Barcelos May 20 '13 at 09:56
  • So you're saying you'd follow something like the "solution" I proposed? – Henrique Barcelos May 20 '13 at 14:16
  • @HenriqueBarcelos is it about the CachedDbAcess? If yes then it is, only if you also provided the DbAccess, and can handle most of possible use case with the cache. – Fendy May 21 '13 at 01:18
1

Just referencing another module blows up the modularity of my system?

Not necessarily. It's a dependency. Having a dependencies is perfectly normal. Without dependencies modules can't interact with each other (unless you're doing such interaction indirectly which in general is a bad practice since it hides dependencies and complicates the code). Modular desing implies managing of dependencies, not removing them.

One tool - is using interfaces. Referencing module via interface makes a so called soft dependency. Such module can accept any implementation of an interface as a dependency so it is more independant and as a result - more maintainable.

The other tool - designing modules (and their interfaces) that have only single responcibility. This also makes them more granular, independant and maintainable.

But there is a line which you should not cross - blindly applying these tools may leed to a too modular and too generic desing. Making things too granular makes the whole system more complex. You should not solve universe problems, making generic modules, that all developers can use (unless it is your goal). First of all your system should solve your domain tasks and make things generic enough, but not more than that.

OpenMinded
  • 496
  • 3
  • 10