Page 1 of 2

Application component dependencies

Posted: Fri Apr 21, 2006 7:54 pm
by Chris Corbyn
In relation to: viewtopic.php?t=47443

When I write apps they usually tie into some sort of framework. The framework at a bare minimum will handle the inclusion of the needed files, the template system and the database gibberish :P Along with that come a bunch of classes that make up each module in the app.

Now... take a module out of the application. There's a pretty good chance it wiont work at all without the core framework around which it was built. There's a possibility (30-50% ?) that it won't work if you remove another class that's not part of the framework, but part of a module that ties in with the module in question.

Would you consider this acceptable in application design or should app comonents/modules be non-dependant upon each other?

Anyone got any damn useful tips in ways to reduce dependancies without massively repeating code? This is something I've been striving towards for a good while now :(

Posted: Fri Apr 21, 2006 8:19 pm
by Christopher
Yikes, can we get a bunch of pizzas and a keg of beer, and all hang out with Larry Constantine for a weekend. :)

This is the whole topic of Low Coupling / High Cohesion. The goal is to make changes and maintenance easier by keeping each object focused and clean/clear. But the trade-off is always between now and later. There is nothing wrong with High(er) Coupling, it's just that Low Coupling has proven to make things easier down the road.

The GRASP Patterns are probably a good starting place for "damn useful tips."

Posted: Sat Apr 22, 2006 10:24 pm
by Christopher
I am suprised that people didn't jump on d11wtq's question. This is an area I certainly would like to know more about. I found a write-up on the GRASP patterns here and copied them below. It is an interesting list because it condenses the basics of how to turn a design into a group of classes -- which for me is the hardest part. Can we find examples, in PHP, of how each of these very general concepts improve a piece of code? Maybe go through them one by one and try to make sense of them? Design a simple problem based on them?

Expert
Who, in the general case is responsible?
Assign a responsibility to the information expert -- the class that has the information necessary to fulfill the responsibility.

Creator
Who creates?
Assign class B the responsibility to create an instance of class A if one of the following is true:
1. B contains A
2. B aggregates A
3. B has the initializing data for A
4. B records A
5. B closely uses A

Controller
Who handles a system event?
Assign the responsibility for handling a system event message to a class representing one of these choices:
1. The business or overall organization (a façade controller).
2. The overall "system" (a façade controller).
3. An animate thing in the domain that would perform the work (a role controller).
4. An artificial class (Pure Fabrication) representing the use (a use case controller).

Low Coupling
(evaluative)
How to support low dependency and increased reuse?
Assign responsibilities so that coupling remains low.

High Cohesion
(evaluative)
How to keep complexity manageable?
Assign responsibilities so that cohesion remains high.

Polymorphism
Who, when behavior varies by type?
When related alternatives or behaviors vary by type (class), assign responsibility for the behavior—using polymorphic operations—to the types for which the behavior varies.

Pure Fabrication
Who, when you are desperate, and do not want to violate High Cohesion and Low Coupling?
Assign a highly cohesive set of responsibilities to an artificial class that does not represent anything in the problem domain, in order to support high cohesion, low coupling, and reuse.

Indirection
Who, to avoid direct coupling?
Assign the responsibility to an intermediate object to mediate between other components or services, so that they are not directly coupled.

Don't Talk to Strangers (Law of Demeter)
Who, to avoid knowing about the structure of indirect objects?
Assign the responsibility to a client's direct object to collaborate with an indirect object, so that the client does not need to know about the indirect object. Within a method, messages can only be sent to the following objects:
* The this object (or self).
* A parameter of the method
* A attribute of self.
* An element of a collection which is an attribute of self.
* An object created within a method

Posted: Sat Apr 22, 2006 10:27 pm
by John Cartwright
Heh, just as soon as I find the topic you pretty much wen't over what I was going to say :roll: Well put aborint.

In terms on putting a percentage on the number of classes that work straight out of the box from framework to framework, I probably hit about 5% around. I don't know if thats a bad thing or a good thing, although I can tell you that as long as the depencies make sense, are kept to as little as possible, and are made clear then I think you shouldn't be worried about the fact that there are many classes that don't work out of the box.

Now my question to you is -- what do you consider a module? Personally a module to me is an enhancement, for example my Application_SmartStripTags class, which serves a very small yet very focuses purpose. On the other hand, if you consider each page to be a module, like many people do, then your probably best ignoring me. Using a controller out of the box doesn't make much sense to be unless I am packaging all these classes together, such as the framework core, application controller, model controller, view controller, shall I go on?

Hope this helps.

Posted: Sun Apr 23, 2006 7:22 am
by Chris Corbyn
Wow I'm overwhelmed with things to read up on :) Thanks for this :)
Jcart wrote:Now my question to you is -- what do you consider a module? Personally a module to me is an enhancement, for example my Application_SmartStripTags class, which serves a very small yet very focuses purpose. On the other hand, if you consider each page to be a module, like many people do, then your probably best ignoring me.
I've always found this to be a question that everyone has their own view on too. A module for me isn't a page as such, nor is it an enhancement as you put it :? A module is any given part of an application that serves a common purpose. Usually a handful of pages each with their own view and controller but they all hook up to a main parent class (I call it a module class but I've got no idea of the correct term) which works with the model. So the only place I'd ever get dependencies would be within the model itself... Hmm... I guess that makes sense in any case.

/goes off to read up on GRASP.

Posted: Sun Apr 23, 2006 11:02 am
by alex.barylski
jcart: In terms on putting a percentage on the number of classes that work straight out of the box from framework to framework, I probably hit about 5% around
This suggests, 95% of your classes are written specifically for your applications purpose...??? :?

Being an OOP zealot...I don't like the sounds of that...my number one golden rule of OOP:

Reusability...if you can't drop it into any application (phpMailer, Smarty, etc) there is little purpose in writting it as a class...

It's likely you don't have any data members associated with that class and any given instantiation will likely only use a single method call...if this is true you've worked against OOP principles in general...

So what you've done is basically wrapped a group of functions with a class name (preventing namespace collisions) but incured the overhead of object instantiation/parsing, etc...

For what? Am I missing something here? :?

Also, just to add to the thread, in my experience... :)

1) A framework, is a foundation of interconnected modules, which work togather (tight binding) to simply application development. Consider an framework much like a generic application skeleton.

2) An application skeleton, is a industry specific framework, derived from a generic framework, which provides a highly specialized interface. For example using a generic framework, you build off that, say for example in your industry, your user registertation pages are always using the same fields, then those FORMS, database schema, users model, etc never change and therefore can be part of an application skeleton. Application skeletons can be less specialized, for example your skeleton might only include first name and last name, and you might need to add email address. This functionality is easily added.

3) A module, is an interface to a group of functions or classes which serve a certain purpose and are part of a core library, therefore they are likely statically bound to your application - removing one would choke the application at some point.

4) A plugin, is a module, but not statically dependant on any other module. These are loaded at runtime *so to speak* and therefore care is taken to make sure the plugin exists before it is used and default action is taken on failure. Think Windows *.lib and *.dll

DLL: Loaded dynamically and therefore code can check if it's cool to use the module
LIB: Statically linked, therefore, it's usage is hard coded in your codebase - removing a plugin should typically have little negative effect on overall operations.

4) A library, is typically a collection of disparate classes and/or functions which are grouped by purpose. Function groups and classes have a one to one relationship with file names.

Cheers :)

Posted: Sun Apr 23, 2006 11:10 am
by John Cartwright
Hockey wrote:
jcart: In terms on putting a percentage on the number of classes that work straight out of the box from framework to framework, I probably hit about 5% around
This suggests, 95% of your classes are written specifically for your applications purpose...??? :?

Being an OOP zealot...I don't like the sounds of that...my number one golden rule of OOP:
Ive gotten as far in this in your post, and I'm going to stop you there. Perhaps that is a big uninflated that figure I gave, but I wanted to show you that it's unlikely that if I drag and dropped a controller from one framework into the next it sure as hell won't work in another framework. For instance, if I switched the controllers of Zend Framework and Cake Framework would you seriously expect it to work?

The reason I asked for his definition of a module is because it is very important to identify exatly what it is before I really get into specific kinds of classes. How I see it, all my classes, like abstraction layers and simple utilities classes (as previously mentioned the Application_SmartStripTags will because all it takes is a simple string, and has all native php processing done inside the class).

If we follow design principles of PHP of inheritance, it is nearly impossible to have the exact same implementation of princinples unless you wrote them both yourself! That is what I'm getting at. Just because only ~5% of my classes work out of the box doesn't mean they are poorly designed, but you have to consider different designs and practices of different programmers, ideas of inheritance vs passing objects. What I'm saying is that it may take a couple minutes to get the class working properly, just not straight out of the box.

Posted: Sun Apr 23, 2006 11:22 am
by Chris Corbyn
Jcart wrote:
Hockey wrote:
jcart: In terms on putting a percentage on the number of classes that work straight out of the box from framework to framework, I probably hit about 5% around
This suggests, 95% of your classes are written specifically for your applications purpose...??? :?

Being an OOP zealot...I don't like the sounds of that...my number one golden rule of OOP:
Ive gotten as far in this in your post, and I'm going to stop you there. Perhaps that is a big uninflated that figure I gave, but I wanted to show you that it's unlikely that if I drag and dropped a controller from one framework into the next it sure as hell won't work in another framework. For instance, if I switched the controllers of Zend Framework and Cake Framework would you seriously expect it to work?

The reason I asked for his definition of a module is because it is very important to identify exatly what it is before I really get into specific kinds of classes. How I see it, all my classes, like abstraction layers and simple utilities classes (as previously mentioned the Application_SmartStripTags will because all it takes is a simple string, and has all native php processing done inside the class).

If we follow design principles of PHP of inheritance, it is nearly impossible to have the exact same implementation of princinples unless you wrote them both yourself! That is what I'm getting at. Just because only ~5% of my classes work out of the box doesn't mean they are poorly designed, but you have to consider different designs and practices of different programmers, ideas of inheritance vs passing objects. What I'm saying is that it may take a couple minutes to get the class working properly, just not straight out of the box.
I agree completely. I'm also pretty confused by what ~Hockey says. So you're basically saying that if it can't be re-used it should never be in an object. How on earth does OOP only lend itself to re-usability? If that was the case you'd just use functions that bind a set pf procedures together :? OOP goes a lot further than providing re-usable code.

As for being able to get components to work "out of the box" I agree... if it's built around a given framework mit will adhere to that framework's API so it's obvious it won't work in other frameworks without some tweaking. I wasn't really getting at that however, I was referring to removing a module from your application and seeing if it had an impact on the working of any other module in that same app. i.e. are your modules truly 100% independent of each other? I'm fine with discussing inter-framework compatibility though... that too is an interesting topic :)

Posted: Sun Apr 23, 2006 11:27 am
by John Cartwright
Maybe we should start another topic.

Posted: Sun Apr 23, 2006 11:35 am
by Chris Corbyn
Jcart wrote:Maybe we should start another topic.
Nah it's cool... it's all still the same subject :)

Posted: Sun Apr 23, 2006 11:35 am
by John Cartwright
Now I'm confused on your definition of a module now that I think about it.

Using your definition of a module, in the Zend Framework I extend each page (IndexController, NewsController, etc) by an ApplicationController which ties together common functionality of all the controllers.
d11 wrote:I was referring to removing a module from your application and seeing if it had an impact on the working of any other module in that same app.
Obviously if I removed my ApplicationController I'm going to get errors firing left and right, which makes sense right? I'm just confused where you are wanting to drive this discussion.

Posted: Sun Apr 23, 2006 12:01 pm
by alex.barylski
Jcart wrote:
Hockey wrote:
jcart: In terms on putting a percentage on the number of classes that work straight out of the box from framework to framework, I probably hit about 5% around
This suggests, 95% of your classes are written specifically for your applications purpose...??? :?

Being an OOP zealot...I don't like the sounds of that...my number one golden rule of OOP:
Ive gotten as far in this in your post, and I'm going to stop you there. Perhaps that is a big uninflated that figure I gave, but I wanted to show you that it's unlikely that if I drag and dropped a controller from one framework into the next it sure as hell won't work in another framework. For instance, if I switched the controllers of Zend Framework and Cake Framework would you seriously expect it to work?

The reason I asked for his definition of a module is because it is very important to identify exatly what it is before I really get into specific kinds of classes. How I see it, all my classes, like abstraction layers and simple utilities classes (as previously mentioned the Application_SmartStripTags will because all it takes is a simple string, and has all native php processing done inside the class).

If we follow design principles of PHP of inheritance, it is nearly impossible to have the exact same implementation of princinples unless you wrote them both yourself! That is what I'm getting at. Just because only ~5% of my classes work out of the box doesn't mean they are poorly designed, but you have to consider different designs and practices of different programmers, ideas of inheritance vs passing objects. What I'm saying is that it may take a couple minutes to get the class working properly, just not straight out of the box.
Fare enough :)

I personally prefer object reuse over anything when implementing solutions in OOP...

If it's not generic or truely representative of an object or component and simply an object interface, I generally don't bother using OOP - as IMHO it's not an object, as an object has properties and methods which act on those properties, but instead, perhaps a package or library with a namespace wrapper.

p.s-I was kind of hoping you'd give me feedback on how I defined framework, etc...I wrote on article a few years back on this subject and it was well received by the C/C++ community, thought I posted it on codeproject.com but it appears I did not and I can't seem to find it again searching google... :?

But as a general gist, does it make sense to you, despite many programmers have their own definitions of what they are, at least in web developer paralance?

Cheers :)

Posted: Sun Apr 23, 2006 12:09 pm
by Chris Corbyn
I think of a framework as a basic skeleton around which to build my application... The only reason I started to roll my own was because I noticed I was always setting up my applications in the same fashion with the same basic skeleton.

Posted: Sun Apr 23, 2006 12:18 pm
by John Cartwright
Hockey wrote: I personally prefer object reuse over anything when implementing solutions in OOP...

If it's not generic or truely representative of an object or component and simply an object interface, I generally don't bother using OOP - as IMHO it's not an object, as an object has properties and methods which act on those properties, but instead, perhaps a package or library with a namespace wrapper.
Going back to my ApplicationController example, which is beating the definition of a module of the moment (:P), so you wouldn't consider this an object? I think you are taking the reusability factor a bit too literal. My ApplicationController is reused many, many many times throughout my applications -- when used within the defined framework. It conforms to certain criteria of the framework and there is no avoiding that. Change the framework and reusability gets a bit shady. It sure is reusable to an extent, but not out of the box as we previously discussed.

Basically, what what you are suggesting is that the ApplicationController has no place in OOP? I'm real confused. It has no properties, it is simply an extension to the base class to extend functionality. By having no proerties and no methods to act upon those properties, what is this then? I don't want to repeat 100 lines of code in each controller, so what are you recommending I do then?
p.s-I was kind of hoping you'd give me feedback on how I defined framework, etc...I wrote on article a few years back on this subject and it was well received by the C/C++ community, thought I posted it on codeproject.com but it appears I did not and I can't seem to find it again searching google... Confused
I want this thread to stay really focussed. At your word, I will split the thread so we can discuss frameworks more.

Posted: Sun Apr 23, 2006 2:30 pm
by alex.barylski
So you're basically saying that if it can't be re-used it should never be in an object
Readme: If your going to comment, make sure you read the *whole*

Well...yes...to a degree, it should be your number one goal during object analsys and discovery...as objects are intended to promote code reuse to a level greater than functions alone.

OOP was designed to assist or make more clear, software development problems/solutions...and problem solving is all about taking a problem and breaking it into smaller more manageable problems and solving each of those in a recursive/iterative manner until problems cannot be broken down any more...ie: your problem becomes atomic.

As you break problems into smaller problems, you can begin to discover some form of heirarchy where one monolithic problem broken into 2 logical sub-problems are combined to solve the previous problem, this is where multiple inheritence comes in handy. Usually however you can solve one monolithic problem by incrementally breaking it into single solutions and use linear inheritence to solve the problem.

This is what is often refered to object discovery and analsys...something many articles and books ignore to explain - depending on the language!!!

Take a problem, break it into a smaller problem which solves a more primitive subset of it's child.

Object discovery usually works top-down, not visa versa...which most OOP articles let you believe, which is a clear indication of a newbie at OOP writting the article - thus the reason I don't read articles when I want to *learn* something but instead I read a book, I use articles to familiarize myself with a topic and if interested I find a high quality book.

Most articles on the subject right away begin disscussing the syntax, and go into inheritence without disscussing how and why object discovery is important first!!!

They detail the basics of OOP, explain encapsulation, etc but don't really explain it's purpose, just that it's handy and immediately developers see some advantages (depending on your experience level of course) and begin using it all over the place - too much of a good thing can be bad.

For obvious reasons, OOP cannot be properly explained in an article, you can exemplify the general idea, but you will likely skip out on alot of details, ie: object discovery and what OOP is *really* about.

I have read at least 10 books on OOP and have spent years(almost 10) considering how and why OOP does what it does and how it is fundametally better at solving problems than procedural programming.

the fact that so many people are ignorant to the idea of object discovery, demonstartes how a little bit of knowledge can actually be a bad thing. I shouldn't say a bad thing, cuz if you use classes over procedural, despite not understanding it, who cares, it's not *really* going to negatively effect your program, except for failing to following OOP principles properly...but we all seem to be advocates of good design and strict confirmance to rules, so perhaps it's important... :P

The point I am trying to make, is that you are correct in saying OOP goes waaaaay beyond reuse...

it's not just for pragmatic use, but fundametally for solving problems...

If OOP is indeed intended to solve problems more effectively and in a more natural way than procedural programming, then reuse should be prioritized - as that solves the problem of solving problems...

I agree that reuse should not be your only requirement when using OOP, but let me make one thing clear - which many OOP enthusiasts fail to realize...

The title Object Oriented Programming...suggests the idea of object is of upmost concern when following it's principles...

An object is a person, place or thing, each of which are composed of communication channels (methods) and properties.

Consider a real world object: You and your friend are holding hands or having a conversation (interfacing with each other) if your heart stops and you die, the interface or communication channel stops, but it doesn't *really* affect your friends life (outside of emotions). This is because you are not bound by implementation, but rather by contract or interface.

In practice, it's best to keep your objects as objects...which are separate entities capable of existing without support from the outside world...(ie: database, etc) any bindings or dependancies should be left to interface not implementation. Thus reuse is born!!!

A database class (NOT an DB abstraction class) is poor use of OOP and indicates naivety...

The object, regardless of the abstraction layer used, is now forever bound to that medium and is therefore not reusable.

Code: Select all

class CxUser{
  function list()
  {
    $adodb->Execute('SELECT * FROM table_users');
  }
}
That is not OOP, as it is not an object in the purest sense of the word. It is a wrapper around traditional procedures...if the database chokes, the object is no good...if you want to change from database to remote storage, you can't without touching the imlementation...and so on.

If your after a library and simply want to prevent namespace collisions, calling these functions statically...cool...thats a good idea (PHP doesn't yet support namespaces, so we can use this as an adhoc solution), but if you instantiate it as an object and pass it around as an object...

Thats your choice...waste of clock cycles if you ask me...but your choice (as in anyone, not yours alone)

However if you (as in anyone) write code like this and tout it as an OOP solution, then I have problems...because then you disambiguate the term *object oriented programming* and confuse newbies and assist in the proliferation of poorly written OO code.

Lastly I will define what an *object* is because people seem to fail to realize this, judging by the number of times I've been in this disscussion on various forums :P

An object, is a separate entity capable of existing entirely on it's own, with no internal dependancy on the outside world (re-use) other than that of interface communication...

Look at real world objects, which OOP is emulating...

A caliper is designed to work with rotors, etc...

if a caliper breaks internally, it's replaced easily and everything is cool. But the caliper DOES NOT rely internally (implementation) on the rotor, only through contract or interface...

So to recap, yes, I am saying if an object doesn't allow reuse, then you might as well write it as a procedure or at least as a static method, making clear it's NOT an object your dealing with.

However, at the same time, to use the above CxUser as an example...

It might make sense to have such an object, despite the loss of reusability, but this isn't so much as object as it is an abstract data type (ADT). As CxUser would be a new intelligent "type" much like Integer, Double, String, etc...

Here's the kicker, for PHP developers...

ADT's are not likely ever derived from, how many things can you make from an Integer? You couldn't exactly make a super integer, because the "type" that object is bound to is fixed - it's an integer!!! I suppose you could make a double integer or even an array (string) of 4 byte integers for some new language which has that many characters...but still...

It's medium is fixed as well, it's 4 bytes(arch. depending) of RAM, much like a CxUser ADT is likely bound to to a SQL database - it's medium is slightly more flexible than that of an plain Integer, but the idea is the same.

A single Integer:
00 00 00 AA

A single CxUser:
fname lname age income addres phone1 phone2

Heres where I have problems with ADT's in web development:

An ADT represents a single "unit" but how often do people have listing functions in there as well?

Code: Select all

class CxUser{
  function create(){}
  function update(){}
  function delete(){}

  function list(){} // Listing function
}
The other caveat of ADT's is they are not normally used as an 'object' is...

You don't typically initialize an ADT, play with modifiers/accessors, etc...

And unlike Integer types which can be used millions of times in any given section of code, an ADT is likely only going to have it's create() called once during any given session, etc...

So PHP has parsed an object to execute one function???

In a compiled environment this wouldn't be bad, but on a web platform, it's wasteful...

You'd be better off forgoing the pleasure of working with OOP in favour of a function library, optimally chopped into individual modules, so only functions needed get parsed.

So again, to recap (for the second time I know :oops: )

When you can't reuse an object, it's likely a good idea to not bother using OOP as it's NOT an object...cuz object implies reusability...

Although technically an ADT is implemented as a class object, fundametally an object and ADT are quite different. One is an object and another a type.

An object and ADT support reuse, but depending on the ambiguous nature of your ADT in question, a ADT may only be usable from with your application.

STL is an example of an ADT library...those are generic container classes or ADT's and although reusable, they don't apply to every applications needs.

The above CxUser example as an ADT also makes me choke, because the nature of database schemas are quite dynamic, your ADT will likely loose it's reusability quickly.

O/RM frameworks seem to really solve this problem nicely - at least the one I'm working on does.

This topic really gets me fired up and I could go on forever, but for the sake of brevity (just kidding) I think I'll stop here...

If anyone argues, I'll continue further...

p.s-I am saying object reuse is important and objects shouldn't be used unless their is the possibility of reuse, but also note my exceptions to the rule, in the case of an ADT and your specific circumstances...and why when using PHP it's sometimes better to modularize your code instead of componentize.

Cheers :)