OO Application Architecture

25 Aufrufe
Direkt zur ersten ungelesenen Nachricht

Gavin Baumanis

ungelesen,
03.01.2012, 19:46:0703.01.12
an cfau...@googlegroups.com
Hi Everyone,
 
I was recently chatting at work about how we might go about architecting a new application.
I suggested that we have;
Objects,
Service Managers
and Gateways.
 
Whereby the ServiceManager is the public API for the gateway.
 
Then I got asked , "Why?"
 
I explained that it was good practice to separate out the plublic API from the gateway and gave the example of changing database providers.
Eg. Swapping from MS-SQL server to PostGreSQL.
 
With my architecture proposal, you only need to change the gateway (perhaps some minor tweaks to the ServiceManager CFCs.
 
So far so goo... Until I got asked "Why" again.
"You still need to change the code somewhere for the new database flavour.
What is the ServiceManager  doing for us, it seems like a redundant duplication of code?"
 
Subsequently, I have been thinking about it more - and can't come up with a good reason.
 
I could be doing it completely wrong...
But for the most part, my Service layer becomes a duplicate of the Gateway.
* Ensure we have the required arguments for the gateway,
* Call the gateway functions, using the supplied arguments
* Return exactly the gateway's return value(s) to the consumer.
 
99.9% of the time the arguments are exactly the same,
The data / structure (whatever) that is returned from the gateway, is returned unaltered to the consumer, too.
For the very small number of times that I might do some data transformation (in the ServiceManager) before it is returned... well I could simply create "THAT" method in my gateway and have;
* Call the this.GETTER method
* Transform the data as required
* Return the transformed data
 
So am I missing something? Or have I just talked myself out of the requirement for (perhaps, excluding web-services) of ever needing to have a separate service layer to a Gateway CFC?
 
 
Gavin.
 

Mark Mandel

ungelesen,
03.01.2012, 21:09:0703.01.12
an cfau...@googlegroups.com

Short answer -

Often the service layer proxies the gateway, but not always.

Also, there is no reason a archive layer couldn't communicate to multiple gateways and/or services.

Mark

Sent from my mobile doohickey.

--
You received this message because you are subscribed to the Google Groups "cfaussie" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cfaussie/-/TMMO_W0Au4gJ.
To post to this group, send email to cfau...@googlegroups.com.
To unsubscribe from this group, send email to cfaussie+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfaussie?hl=en.

Dave

ungelesen,
03.01.2012, 21:28:5903.01.12
an cfaussie
"I explained that it was good practice to separate out the plublic API
from
the gateway and gave the example of changing database providers. "

Not sure that's a great argument - changing DB's is very rare in
projects.

Question: Does your app consist of just database calls, or is there
ever any "business logic" type stuff going on too?

IMHO, a greater reason to isolate queries to their own "gateway layer"
is that queries tend to be large, ugly things that makes business
logic header to read. IE, if your service layer consists of both
business logic and queries, it's harder to see the business logic.

Having only methods in the gateway that return queries (instead of
structs) also encourages code re-use, ie, method "a" might want the
data as a query for easy display, method "b" might want the data as
struct because it's gotta add form data to is to work out how/what to
save or what's changed.

The duplication isn't too hard to deal with either. Write your wrapper
cfFunction in the service layer, copy/paste it to the gateway layer
and replace the contents with a cfquery tag. Probably adds a minute
or two per method.


dave

Gavin Baumanis

ungelesen,
04.01.2012, 00:15:5004.01.12
an cfau...@googlegroups.com
It's kind of funny - but just after having writtemn the initial post I was doing some work that was perfect for a service ayer / manager CFC.

Although very new, the DAO object was alrready in use, but was returning queries.
Problem for me was; I wanted to do my new work using objects.
(The "greater" view, to perhaps implementing ORM eventually... so working with objects for the new work seemed sensible.)

So, I now have in my manager CFC, a method that returns an object populated from calling the underlying DAO "getter".

I certainly could have made the change in the DAO, and had it return an object instead of a query...
But... while I am not sure how common it is - I can drop back (easily) to the original query if needed, this way, too.
(to perform a query of queries perhaps?)

Also, in this instance, (the new work is relatively small in the number of object types required) - so I can certainly see the value in using the same manager CFC for the few objects / tables that we have deal with.

So - I think I have just talked myself back into using them again...
Sheesh - I might need an afternoon lie-down....

Gavin.

Dale Fraser

ungelesen,
04.01.2012, 01:49:3704.01.12
an cfau...@googlegroups.com

I could argue that the DAO which gets data should return data in the appropriate format.

 

If the DAO doesn’t return data in the necessary format then what is the reason for it returning data in the wrong format.

 

Regards

Dale Fraser

 

http://dale.fraser.id.au

http://cfmldocs.com

http://learncf.com

http://flexcf.com

--

You received this message because you are subscribed to the Google Groups "cfaussie" group.

To view this discussion on the web visit https://groups.google.com/d/msg/cfaussie/-/Xx9BamB2AgQJ.

Dave

ungelesen,
04.01.2012, 14:45:4604.01.12
an cfaussie
"So - I think I have just talked myself back into using them again...
Sheesh - I might need an afternoon lie-down.... "

Yep, learning this stuff can be an absolute mind-f**k, I'd say that
most of it comes from experience - ie, trying something on a project,
figuring out what does't feel right and looking into other design
approaches next time, etc. A lot of things that seem like overkill on
a new/small project make a lot more sense as the project gets larger.


RE: DAO's. My approach is to define the DAO's responsibility as
"mapping single objects to DB records." The service layer / managers
should not know/care about how the objects get persisted/un-persisted
(queries via the CFQuery Tag). Your DAO "layer" consist classes (one
per object, eg, fooDAO) which contains methods like read(fooID), which
returns a object of type foo, and save(foo), which figures out if we
are doing an insert/update & persists the object.

The advantage of this approach is that when you feel comfortable with
using ORM, you can change your entire code base to ORM simply by
changing your DAO's & not having to change your entire service layer.

IE, under ORM, you still have a fooDAO.read(fooID) but instead of
these methods calling cfQuery tags, they change to be calls to
entityLoad("foo", arguments.fooID), the same applies to fooDAO.save(),
which would call entitySave(arguments.foo). Your service layer still
calls fooDAO.read(fooID), etc


I think that this ability, which is refereed to as "change an objects
internal implementation without changing it's external interface" is
one of the real benefits of OO programming & is probably one of the
skills/thought processes to learn first.

Think of your objects/classes as "black boxes" that operate on other
objects. If you calling code has no knowledge of how these black
boxes work, then it does not need to change when you decide to change
the inner workings of the black boxes. IE, you can change code in one
area without breaking other areas of your system.




The funny thing is that as your learn more about OO, you will probably
take a different approach to the above problem. EG, doing object
creation in factories, which are different to your service layer,
which will then call DAO "layer" (which does not do object creation)
or a ORM "layer" - ie, the purists will think my above solution far
from perfect, and they would be right - but there is no point in
trying to learn perfect OO all in one day.




Dave

Gavin Baumanis

ungelesen,
04.01.2012, 17:23:2404.01.12
an cfau...@googlegroups.com
Hi Dave,
Thanks for the reply.

I do however have some questions, in fact the same questions asked of me when I first proposed the serviceCFC and DaoCFC approach to my colleagues.


On 05/01/2012, at 6:45 AM, Dave wrote:

RE: DAO's.  My approach is to define the DAO's responsibility as
"mapping single objects to DB records." The service layer / managers
should not know/care about how the objects get persisted/un-persisted
(queries via the CFQuery Tag).  Your DAO "layer" consist classes (one
per object, eg, fooDAO) which contains methods like read(fooID), which
returns a object of type foo, and save(foo), which figures out if we
are doing an insert/update & persists the object.

The advantage of this approach is that when you feel comfortable with
using ORM, you can change your entire code base to ORM simply by
changing your DAO's & not having to change your entire service layer.

IE, under ORM, you still have a fooDAO.read(fooID) but instead of
these methods calling cfQuery tags, they change to be calls to
entityLoad("foo", arguments.fooID), the same applies to fooDAO.save(),
which would call entitySave(arguments.foo).   Your service layer still
calls fooDAO.read(fooID), etc


Regardless of what CFC your changing,
You still need to edit XX number of functions to now use entityLoad() / entitySave() etc.
What have I "really" achieved by having the DAO separate from the service layer, if it is merely the location of that code changed that is different?

Also, by having the service layer as well, I am now creating an awful lot of duplicate code.
I now must have;
serviceLayerCFC.getMyObject() AND
daoCFC.getMyObject()


And that is for every CRUD operation for every object.
That is a substantial amount of code duplication ... and while copy/paste | code generation are your friends in this regard...
It still increasing the amount of code, the amount of unit tests I need to write / maintain and the total lines of code that I need to wade through for debugging / troubleshooting.

It almost seems like "someone" at some point in time said;
"this is how to do OO application architecture for (insert some language here... Java | Smalltalk | COBOL | C++ ..."

And subsequently when CF MX came out... all the "classically" trained developers chimed in with;
"Well you need to have a separate service layer to the gateway/DAO"
And because it was said - by someone that was respected... it must be gospel, simply because that's how they did it with Java | Smalltalk ....

It is worth noting, that CFBuilder's ORM object generator extension ONLY creates;
object.cfc
objectService.cfc - there is no separated gateway/DAO.

Now, I am not saying that you and everyone else that proclaims that having a separate service CFC from the gateway/DAO are wrong.
I don't profess to know the answer - and thus the entire point of this thread...

I am just saying, "Show me a definitive, real world example, where having the two separated has made a substantial impact on the delivery time of an application.
Or show me an example whereby having them separated has had XXX positive effect.

Simply saying it should be this way, because a design pattern in the Gang of Four's book says so... or because that's the way it is done in Java / C++ and they're OO languages, so therefore it MUST be the way to do it in dynamically typed CFML... I just don't buy it.



I think that this ability, which is refereed to as "change an objects
internal implementation without changing it's external interface" is
one of the real benefits of OO programming & is probably one of the
skills/thought processes to learn first.

Think of your objects/classes as "black boxes" that operate on other
objects.  If you calling code has no knowledge of how these black
boxes work, then it does not need to change when you decide to change
the inner workings of the black boxes.  IE, you can change code in one
area without breaking other areas of your system.


But I still have to change code "somewhere", right?
What difference does it make where I change it?
I wholly agree that maintaining the "public API" of the DAO can / does limit the amount of code changes needed to be made elsewhere.
But because I have unit tests... finding those "other" spots is relative easy.

But as you mentioned in an earlier reply ...
Who ever really changes their DAO / persistence technology after an application has been deployed?
So the main advantage of loosely coupling the DAO and objects, via the service CFC, would seem to offer a limited "real world" benefit.

It is also not lost on me what Dale asked in his earlier reply.
If the DAO is not returning the data in the appropriate format, why not just change the returnType / structure of the DAO?
In my case, this application is relatively new so any code that replies on the query object being returned could and probably should be changed to use objects.
Otherwise further complications might arise later with respect to data concurrency, particularly if we implement ORM and now have some stuff being modified directly in SQL.

Lastly, please, realise I am not trying to "shoot down" your suggestions / methodology, I am just trying to "flesh out" how "I" am going to benefit from the separation of the service and gateway/DAO CFCs.


Gavin.

Mark Mandel

ungelesen,
04.01.2012, 17:39:5404.01.12
an cfau...@googlegroups.com
Why not use onMissingMethod and Abstract Classes to proxy service calls down to the gateway, and that takes away 95% of the work? (real world statistic)

Mark 


On Thu, Jan 5, 2012 at 9:23 AM, Gavin Baumanis <BeauE...@gmail.com> wrote:
Also, by having the service layer as well, I am now creating an awful lot of duplicate code.
I now must have;
serviceLayerCFC.getMyObject() AND
daoCFC.getMyObject()



Gavin Baumanis

ungelesen,
04.01.2012, 18:05:3604.01.12
an cfau...@googlegroups.com
Hi Mark,
 
OK. By implementing onMissingMethod - I have saved some (perhaps, nearly all) of the extra typing...
 
But the extra "layer" is still in my application.
And now it's a little less apparent than actually having the extra code actually written in the service CFCs.
 
While I realise you're specifically speaking to my complaint of duplicate code...
I'm still skeptical - as to the requirement of having the separation in the first place.
Where's the smoking gun?
 
I'm genuinely not tying to be argumentative for the sake of being argumentative - But simply taking it on faith, because "everyone" says so, isn't cutting the mustard for me at the moment.
 
Gavin.

Mark Mandel

ungelesen,
04.01.2012, 18:20:0204.01.12
an cfau...@googlegroups.com
Really, a service layer is a public facing API to a grouping of functionality.

This could mean accessing multiple gateways, or interacting with other services, or adding extra caching or other functionality around existing gateway methods.

A gateway is just data access - nothing more.

Mark

--
You received this message because you are subscribed to the Google Groups "cfaussie" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cfaussie/-/RY-anMgSNdwJ.

To post to this group, send email to cfau...@googlegroups.com.
To unsubscribe from this group, send email to cfaussie+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfaussie?hl=en.

Dave

ungelesen,
04.01.2012, 18:29:1504.01.12
an cfaussie
"Lastly, please, realise I am not trying to "shoot down" your
suggestions /
methodology," -- Understood.

It comes down to how large the app will be. If it's a few pages then
your right, it does not matter.

Where is starts to matter is as your app grows and you are larger and
larger amounts of "business logic". - Where does that logic go? -
The Service Layer.

This service layer is where most of your important code ends up. By
important, I mean the stuff that's going to end up in longer methods
that do stuff with >1 object. Some methods are going to be kind of
complex, some simple, but this "layer" is where your going to be
spending most of your time coding and debugging. Your service layer
starts to have lots of these methods. (as well as those pesky pass-
though methods to gateways).

I'm looking at a single service-layer class of 5k lines and I've
probably got another 20 of them that are larger then that.

If my service layer was worried about loading/saving objects and
gateway methods, it would be 10 times as large. That hypothetical 50k
class would be a lot harder to maintain & debug. (in fact, it would
not compile) I'd waste a lot of time just scrolling through looking
for the important stuff.

Your queries are fairly standard/easy (compared to your business
logic). There is no real value in the code and you can just code-gen
them. They rarely need debugging/thinking about, when they do, they
are usually fairly easy/obvious problems to fix just from the DB error
messages. They are unimportant and therefore they can sit in the
corner on their own :)


As you have noted, non-OO code works too :) - The real benefit of OO
code is that it makes the application more maintainable (cheaper to
own/run), hopefully reducing bugs in the process. - Yes, it comes at
the expense of having to write more code up front, but you get used to
that and find techniques to make that easier. - There are good code
gen's out there for CF, or you can roll your own to suit your needs -
the default builder one isn't great. You can also use techniques like
Mark's onMissingMethod below to reduce typing.

You will probably benefit from watching some of the Google code videos
like this one http://www.youtube.com/watch?v=wEhu57pih5w subject
matter can be pretty heavy, but will open your eyes to the bigger
picture.


"" I am just saying, "Show me a definitive, real world example, where
having the two separated has made a substantial impact on the
delivery time of an application. Or show me an example whereby
having them separated has had XXX positive effect ""

I'm working on a app with many hundreds of thousands of lines of code,
thousands of classes, etc - It does not use all the best oo
principles, but it is still a hell of a lot maintainable then the
alternative. We did need to switch our persistence framework out to
cater for ORM (ie, from Transfer to ORM), a project that is part way
through at the moment - we converted around 50 classes from transfer
to ORM in a 2 developer week time period - and that's including
testing. It's a fairly pain free project because we use basic OO
principals.


Your app might not be that big now, however if you start thinking in
terms of OO design now your app will be in a better position to more
maintainable as it grows larger and more importantly, it gives you
experience with using common OO principles, so if/when you ever go
onto a larger, OO based project, you will have already had experience
with the basics.


Good luck!

Andrew Scott

ungelesen,
04.01.2012, 20:06:5804.01.12
an cfau...@googlegroups.com
Gavin,

I will second what Dave is saying below..

The mind set is not to continue to believe that procedural is the key to everything, but to begin to understand that the patterns have and where designed to introduce code separation in its many forms, for a stronger purpose in life.

By taking code and placing them into Service layers, and DAO's and beans etc you are then basically saying that I am separating the business logic and database code. This promotes stronger code re-use above all else, and encourages people to think harder about the needs of their objects, especially when it comes to the likes of Database Objects.

You began to argue that the only need would be to have a tier layer that could just be switched out at will, if the need arises and is sort of an example that can be applied, as you have stated. By switching from say reactor, or transfor over to hibernate does become a lot easier. But the bigger picture is you are defining straight away that you are going to be promoting code re-use.

For example you would design and implement a section of code, lets say a forum to your application. You would tend to keep that as tightly integrated to itself as possible. This would mean that you could just pull this out and replace this at will, because you have defined an API that allows you do so. Sure you would need to make some changes to incorporate the new forum that you might like to replace it with, but that would be minimal because you have kept that layer separate.

OO and patterns is no different in thinking than that, ColdFusion makes it hard to think like this because it is procedural right from the word go. It takes a stronger mind to see that the patterns have been introduced to provide easier testing, debugging, and most importantly stronger code re-use.

Something that 99% of people tend to not see.


-- 
Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/

Dave

ungelesen,
09.01.2012, 14:47:5709.01.12
an cfaussie
I just saw this on another group -
http://www.silverwareconsulting.com/index.cfm/2009/5/31/Building-An-Object-Oriented-Model--Recording-and-Sample-Code-Available
is a presentation that gives you a great overview of OO in cf.

Gavin Baumanis

ungelesen,
10.01.2012, 20:00:4610.01.12
an cfau...@googlegroups.com
Firstly,
Thanks to everyone for replying.
 
I realise, completely of my own creation, that readers might not be aware that I have any knowledge of OO conceots - or perhaps, no pracitcal experience, in the use of OOP.
But this isn't the case.
 
I recently transformed an application that was about 800,000 lines per installation (it was a bespoke application) into a single-sourced, multi-stacked application, using CF-ORM and it most certainly has a serivce layer and "manager" CFCs.
I am certain that I convinced myself (by reading / learning, or someone telling me that the separation of DAO and the objects it gets / sets is an appropriate layer to have in an application.
 
The purpose of the post, wasn't so much about what the theory is, or what it tells us... but whether or not actually served a practical purpose in real-world applications.
 
My memory of the "objectifiying" of the old application was;
The manager CFC "pretty  much / nearly always" was simply a "stub" - interface like implementation of the methods in the DAO.
That is to say  - leaving aside the architectural benefits of creating a public API,
The workload - involved in creating a service layer (whether copy/paste or generated or handwritten  - was an awful lot of duplication, seemingly for the sake of duplication.
 
I did - but it was rare - that the public API would differ from the DAO.
 
The question asked of me, and ultimately, my question in this thread was;
If it is "nearly" always a duplication of code - then why can't I simply have those specific few differences, catered for in the DAO - with an extra method there - instead of having a service layer?
 
The answer might well come down to something like;
"Because it is such a well known architectural design choice, people simply expect an OO coded application to have one.
And subsequently has become a standard. - Much like a framework...
And to that, I would argue a framework doesn't really do anything for you - but ensure that you (and everyone else involved in the same application) always code in the same manner, and use the same architectural choices."
 
For me - that is a good enough argument to use a framework - any and all other benefits a framework provides - is simply gravy in my mind.
 
If the answer is similiar here, then so be it.
 
I appreciate Mark's point that the if you implemenmt caching or someother "thing" then already having a service layer, assists you greatly.
and if you're creating an app from scratch, then having the caching separate from the SQL (enititySave() etc ) is a good design choice too.
 
For something simple, like a not-so regularly visited blog for instance - then I could sympathise with the argument that it is a lot of duplication - just because the OOP theory says it's a good idea to have a service layer.
 
Don't shoot me - I am just the messenger!
 
 
Gavin.
 

Dave wrote:
I just saw this on another group -
http://www.silverwareconsulting.com/index.cfm/2009/5/31/Building-An-Object-Oriented-Model--Recording-and-Sample-Code-Available
 is a presentation that gives you a great overview of OO in cf.

Andrew Scott

ungelesen,
10.01.2012, 22:01:5910.01.12
an cfau...@googlegroups.com
Gavin,

I am a little confused on the statement of Duplicate code? I am a strong believer that there should never be duplicated code, any chance you can whip up a quick example of what you mean by this.

-- 
Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/



Gavin Baumanis

ungelesen,
10.01.2012, 23:15:0810.01.12
an cfau...@googlegroups.com
Sure thing.
 
gavinsManagerCFC
...
<cffunction name="getgavinsObject">
    <cfargument name = "ag1" required="true"... >
    <cfargument name = "ag2 required="true"... >
 
    <cfreturn gavinsDAOCFC.getGavinsObject(arg1 = "#arguments.arg1#, arg2 = "#arguments.arg2# >
</cffunction>
 
 
gavinsDAOCFC
...
<cffunction name="getgavinsObject">
    <cfargument name = "ag1" required="true"... >
    <cfargument name = "ag2 required="true"... >
 
    ... Some SQL
        WHERE column1 = "#arguments.arg1#"
       AND column2 = "#arguments.arg2#"
 
    return something (maybe)
</cffunction>
 
In this case the getGavinsObject in gavinsManagerCFC is "practically" a stub / duplication of the function in the DAO.
The argument is why bother?
 
Why not just call the DAO version of the CFC and do away with the managerCFC entirely?
 
 
Gavin.

Mark Mandel

ungelesen,
10.01.2012, 23:20:4610.01.12
an cfau...@googlegroups.com
AbstractBase classes and onMissingMethod...

Mark

--
You received this message because you are subscribed to the Google Groups "cfaussie" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cfaussie/-/upAXP3qmn78J.

To post to this group, send email to cfau...@googlegroups.com.
To unsubscribe from this group, send email to cfaussie+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfaussie?hl=en.

Gavin Baumanis

ungelesen,
10.01.2012, 23:27:4210.01.12
an cfau...@googlegroups.com
Hi Mark,
I realise you mentioned this already in this same thread...
 
But I think the "penny has finally dropped".
By using onMissingMethod, you only need to write the code in the ManagerCFC that is "actually" different from the method in the DAO.
 
Embarassingly, I have even used onMissingMethod in exactly the same way - while "playing around" with RocketBoots' "Galaxy" SOA CFC last year...
 
So, there is no duplicate code argument to be had here.
 
Gavin.

Mark Mandel

ungelesen,
10.01.2012, 23:31:3210.01.12
an cfau...@googlegroups.com
Yup -

And to make things 3x as fun, using something like:

To generate most of your basic DAO/Gateway methods using onMissingMethod as well, you barely have to write anything at all.

Mark

 
Gavin.

--
You received this message because you are subscribed to the Google Groups "cfaussie" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cfaussie/-/spBU7eoUpzQJ.

To post to this group, send email to cfau...@googlegroups.com.
To unsubscribe from this group, send email to cfaussie+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cfaussie?hl=en.

Gavin Baumanis

ungelesen,
10.01.2012, 23:50:3510.01.12
an cfau...@googlegroups.com
Nice  - I'll have to have a play with that!
 
 

Andrew Scott

ungelesen,
10.01.2012, 23:52:1810.01.12
an cfau...@googlegroups.com
Technically this is not a duplicate of Code, because you are separating the database away from the service/business logic. This means that if you go from transfer/reactor over to CF-ORM you are essentially just removing that tier and replacing it.

And it also promotes code reuse of the database tier. Because you may have logic in your service layer to do something different with the results, in more than one case of logic. But the code to return the result doesn't change.

So there is potentially two things you are doing, re-use of code and easy abstraction and removal if the need ever arises for something better.

-- 
Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/


Andrew Myers

ungelesen,
11.01.2012, 01:09:1311.01.12
an cfau...@googlegroups.com
On 11/01/2012, at 3:53 PM, Andrew Scott <and...@andyscott.id.au> wrote:

> Technically this is not a duplicate of Code,

Yeah it's more 'boileplate' I guess?

Gavin Baumanis

ungelesen,
11.01.2012, 01:44:0811.01.12
an cfau...@googlegroups.com
"Technically"?

In the very initial post is this;
But for the most part, my Service layer becomes a duplicate of the Gateway.
* Ensure we have the required arguments for the gateway,
* Call the gateway functions, using the supplied arguments
* Return exactly the gateway's return value(s) to the consumer.

I suppose it is close to implementing an interface in terms of the code that is required to successfully run an application using a service layer.
If -  you're using the service layer at it's simplest - proxying the DAO / gateway.
And for the most part - that is 99.99% of what I have used a service layer for.

So, since the function Name is the same,
The arguments are named the same, 
The arguments are the same in number 
The arguments are the same in type...

In fact I (previously) wrote the DAO by;
Copy/pasting the the function from the serviceCFC
Add the required SQL
Alter as necessary the cfreturn code.

So apart from the "guts" of the DAO method - the service CFC version was / is a duplication of code found in the DAO version.

The intent  / the purpose of the two, is clearly different.... but it IS technically a duplication of code.
diff myServiceCFC, myDaoCFC even agrees with me.


Gavin


On Wednesday, January 11, 2012 3:52:18 PM UTC+11, Andrew Scott wrote:
Technically this is not a duplicate of Code, 

Andrew Scott

ungelesen,
11.01.2012, 03:08:4911.01.12
an cfau...@googlegroups.com
Hehe.

So Gavin, what you are saying is that you can create a CFC have the method named the same, same arguments and its duplicate code? Regardless that the meat and guts of the logic is not the same?

Sorry that kinda doesn't sound like duplicate code to me :-)

And your example shows that. And the thing to remember is that the actual DAO is returning a result, that by all intent and purposes is code reuse.

For example

<cffunction name="getgavinsObject">
    <cfargument name = "ag1" required="true"... >
    <cfargument name = "ag2 required="true"... >
 
    <cfreturn gavinsDAOCFC.getGavinsObject(arg1 = "#arguments.arg1#, arg2 = "#arguments.arg2# >
</cffunction>

Gets the data from the database tier, but getGavinsObjectJson might make the same call to gavinsDAOCFC.getGavinsObject but instead convert the object to JSON before returning it.

So technically there is no duplication of code, you have taken a call and separated for reuse by other logic within your code.

-- 
Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/



Gavin Baumanis

ungelesen,
11.01.2012, 22:28:4211.01.12
an cfau...@googlegroups.com

With the greatest of reservations about feeding the trolls....

 

What alternate universe do you live in, Andrew?

 

I clearly stated

The intent of the two CFCs is different.

and

that for "MY" work - the ServiceCFC was all but, always an empty stub for the method in the DAO CFC.

 

Given;

 

SericeCFC

1 <cffunction name="getStuff>

2 <cfargument name="name1">

3 <cfargument name="name2">

4 <cfargument name="name3">

5 <cfargument name="name4">

6 <cfargument name="name5">

7

8 <cfreturn DAO_CFC.getStuff(name1, name2, name3, name4, name5 >

9 </cffunction>

 

 

DAO_CFC

1 <cffunction name="getStuff>

2 <cfargument name="name1">

3 <cfargument name="name2">

4 <cfargument name="name3">

5 <cfargument name="name4">

6 <cfargument name="name5">

7

8 <cfquery name="myQuery">

9 SELECT * from #arguments,name1 where column1 = #arguments.name2" and column2 = #arguments.nam3# and column3=#arguments.name4# and column22 in (#arguments.name5#)

10 </cfquery>

11

12 <cfreturn myQuery >

13 </cffunction>

 

Under what circumstances, on planet earth, is lines 1 through 7, in either CFC not a duplicate of the other?

Whereby "duplicate" means;

(according to thefreedictionary.com)

1. Identically copied from an original.

 

I even stated in my post that I created the DAO CFC by copy / pasting the code from the Service CFC.

And included the caveat of;

So apart from the "guts" of the DAO method

And also provided the proof - that the application "diff" agreed with me.

 

But alas,

I forgot you know absolutely everything about everything and that you are never, ever, wrong.

Obviously,  I am wrong. As must be every file “diffing” tool in existence.

 

Please accept my apology for not completely / wholly agreeing with you, instantly.

I am not sure what came over me,

I will never, ever doubt you or your stunning and dazzling ColdFusion brilliance, again.

 

In Andrew Scott We Trust - because he says so.

Andrew Scott

ungelesen,
11.01.2012, 23:02:4011.01.12
an cfau...@googlegroups.com
Gavin,

Wait a minute, I wanted to confirm what you were defining as duplicate, personally I dont consider lines 1 - 7 duplicate because they are defining the method itself and what you need to pass, yes by definition you can make the assumption that because the method and arguments are the same they could be considered duplicate.

But I wanted to ask because I also consider the code in the middle as part of the method as well.

Don't get me wrong I can see what your saying, and yes I do disagree with it being duplicate in that case. I didn't want to tread on your toes, I just wanted to get a clearer picture on what you are talking about.

Hell one could argue that every time I write, or copy the following line.

<cfquery name="result" datasource="datasource">

Is duplicate because I copied and pasted it, by your definition. Sorry Gavin you fell into that one.

But I still stand by the abstraction, service and gateway abstraction. The DAO is always a personal choice on whether you want to also go that route as well, I think if I read you right you have gone that route, and you maybe right in that you don't see a need in your current situation on whether you need the DAO route.

Now without going into further arguments, you argument can also be applied to all OO principles as well, because if we extend an abstract component or even a normal component your lines 1 to 7 will have to be duplicated to keep the confusion to a minimum, and allow for the method to be overridden, and have the same arguments.

So if you follow that rule of OO principle, would you take the same stance as it being duplicated if you want to change the behaviour of the abstract method?

Which I guess I failed to convey across to you.

I think if you watch the video by Bob Silverberg, it may make more sense to you. As he does also go into more refactoring off the code to keep all code to a minimum, while still allowing for OO principles to apply. A lot of the stuff can be moved to an abstract layer as he has indicated to reduce what you described, but you still risk the chance that you may need to override the abstract layer, so that the meat and bones of the method has different logic.
And those lines 1 - 7 that you have listed as being duplicate are indeed a thing that we can't ignore from time to time, it just part of the design of our application.

I think Bob explains this very well in the video, and does highlight what I was trying to convey.


-- 
Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/



--
You received this message because you are subscribed to the Google Groups "cfaussie" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cfaussie/-/7z5ENOHbIvMJ.
Allen antworten
Antwort an Autor
Weiterleiten
0 neue Nachrichten