cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Juan José Gil <mat...@gmail.com>
Subject Re: Add ActiveRecord support to Cayenne
Date Thu, 27 Dec 2012 03:05:26 GMT
@Дробеня Илья The 4 samples you put are far too easy to implement with a
mix of special templates (por findAll, query and newInstance) and a
non-standard SuperClass (for delete operation)

I've already tried that, and it works, but its not silver bullet...
Once you tried that, you want properties for improve the DSL for query
construction, then you would like to have sorting orders, then you want
some capabilites for tune the query "a la gae"...

you are implementing Cayenne metadata in code, with configured cayenne
metadata... :S


2012/12/26 Дробеня Илья <drobenyai@tut.by>

> Why AR is simpler than row data gateway (that used in cayenne).
>
> Examples,
>
> 1.
>
> SelectQuery select1 = new SelectQuery(Painting.class);
> List paintings1 = context.performQuery(select1);
>
> vs
>
> Painting.findAll()
>
> What is simple?
>
> 2.
>
> Expression qualifier2 = ExpressionFactory.likeIgnoreCaseExp(
>                 Painting.NAME_PROPERTY,
>                 "gi%");
> SelectQuery select2 = new SelectQuery(Painting.class, qualifier2);
> List paintings2 = context.performQuery(select2);
>
> vs
>
> Painting.query("name like $1", "gi%")
>
> 3.
>
> context.deleteObject(picasso);
> context.commitChanges();
>
> vs
>
> picasso.delete();
> picasso.commitChanges(); // or Cayenne.commitChanges()
>
> Simple one argument less.
>
> 4.
>
> context.newObject(Painting.class);
>
> vs
>
> Paintint.newInstance()
>
> What is more elegant? One agrument less.
>
> My opinion - code must be such simple such needed for solve problem. If AR
> allow use to resolve problem - it more simple solution - best to use it.
> If we need more flexibility - need to use explicit context.
>
> About separation - I think design must has functional nature (for example
> need to separate model on Policy, Claim, Cover, House, Home). UI on
> components (Label, Button, Field)
> And only when we need some flexible features - create technical separation
> on controller, DAO, contexts. First if possible need to have only
> functional separation. KISS - http://en.wikipedia.org/wiki/KISS_principle
>
> GRASP - Information Expert (
> http://en.wikipedia.org/wiki/GRASP_(object-oriented_design) )
>
> method should allow to class which data it use!
>
> context.deleteObject(picasso);
>
> deleteObject need to move to picasso
>
> SelectQuery select2 = new SelectQuery(Painting.class, qualifier2);
> List paintings2 = context.performQuery(select2);
>
> performQuery need to move to Painting.
>
> This is the best OOP design. And for me need to separate context only when
> we need anvanced features that do not possible in current design.
>
>
> 2012/12/27 Дробеня Илья <drobenyai@tut.by>
>
> > About my experience.
> >
> > I took part at projects where used all 3 wideused models.
> >
> > 1. Project with Anemic Domain Model - insurance automation
> >
> > Technologies: WebSphere Portal + Spring + Hibernate
> > Technology is working, all good. But classes is really big - business
> > logic is not reused and very complex - becuase do not used OOP, used
> still
> > procedure programming from 70s. We have anemic class (record from
> Pascal),
> > and services - (modules from Pascal). Do this is modern? Fowler, Eric
> > Evans, Kent Beck & other do not used ~ 10 years such solutions.
> >
> > DI is good - but when guys creates much of service for each method, and
> do
> > not model domain - it is point to fail.
> >
> > About such way it is named "Transaction Script" - it is useful for middle
> > complexity enterprise applications -
> >
> http://www.hamishgraham.net/page/Work-Habits.aspx/Architecture/Business-Layer
> >
> > And fail big projects. For example in our project we have much of self
> > developed DSL (business rules in excel, validation language for forms in
> > admin page, database schema declaration in excel), all forms of
> application
> > was components and was reusable. Application was as constructor - anlyst
> > may create from it what need for business. Then it was really hard to
> > develop, on add 1 report generation I spent 1,5 month. Because for add
> one
> > line need to debug 100 services that call one to another and has similar
> > names.
> >
> > But I found way - as combine transaction script and domain model. Need to
> > use bounded context and transalate anemic model to simple parts of rich.
> It
> > is really improve quality (just by code metrics). But this is another
> > discussion, when I have time - I create special presentations. On search
> of
> > this way I spent 4 years and it is really simplify complex and do not
> > understandable logic in enterprise, allow to simple cover it up to 100%
> by
> > unit test.
> >
> > 2. Project with Domain Driven Design - education domain
> > Technologies - Spring + Hibernate.
> >
> > We create DAO - for access to database, model - usual POJO with
> > annotations. And it's contains business logic - without logic for access
> to
> > DB (according Eric Evans DDD).
> >
> > We use DI only for isolate different layers / technologies one from one.
> > No stupid injection of one method to another. And services contains
> > application logic - set of steps that need to process some transactions
> or
> > operation. for example (1. create user, 2. send to it email 3. add it to
> > queue for send it to partnet application). All business logic in
> entities,
> > and entities has deep decomposition. For example in anemic we have
> Policy,
> > in DDD we will decople it on CustomerName, House,  Phone, Coverage. One 1
> > table we have ~5 different classes. And all of its loaded with root class
> > from root DAO. And all needed business logic in such classes.
> >
> > It really good, it's work, it's more simple for complex business logic
> and
> > allow cover ~99% of business logic by simple unit tests.
> >
> > 3. ActiveRecord - good choice for simple projects. But I develop call
> > center software and loan management system using this technology. Also I
> > design platform using Groovy/Grails for such applications.
> > Technologies: Groovy / Grails, Spring.
> > For small and middle size enterprise applications - it's work good. Big
> > applications I do not develop using this pattern.
> >
> > And just inject in entities all possible reusable DAO methods. Without
> > thinking - do it is will used. In my application such methods cover ~ 85%
> > of cases that need for work with persistence. It was really simple and
> > usefule. But it add dependency on persistence framework. And we do not
> > change it - for example if migrate from SQL to NoSQL. But Grails support
> > and such features ;)
> >
> > I am not a fan of AR, but it is really useful for small and midle size
> > applications. I am fan of DDD and CQRS, but for this purposes Cayenne is
> > not a good solutions. But for AR - it is the best choice.
> >
> > For example, in which projects I will use Cayenne AR. We have portal and
> > need to develop such features as separate applications - messaging,
> > registration, feedback form, simple analytics forms. For this purposes I
> > just use AR. Why for such small tasks I need to code services, why I need
> > to inject classes to context, context to classes. I simple create AR
> > entities and start to use it. I do not spent much time, and create
> > solutions that correlates with requirements. Also if I have 5 entities,
> do
> > I really need services for its.
> >
> > > @emeka, in that regar of having rich models, how are you resolving the
> > > injection of services in your models? Or are you accessing your
> > > dependencies using static factories?
> > Why do you need inject one business logic method to other? Why use DI for
> > business logic. From my perspective - it is usefule for clear
> dependencies
> > on technologies and on difeerent subsystems. Do really need ibject on
> > method (in service) in  another method that creates similar operations. I
> > propose use DI only for application logic.
> >
> http://stackoverflow.com/questions/1456425/business-and-application-logic
> > Inject possible logic in domain other in services.
> >
> > > query building, etc... but, after many tries, I don't think
> > > that java is the rigth lang for this kind of programming (too wordy),
> > maybe
> > > cayenne+scala or cayenne+groovy would be a nice try ;)
> > interesting in which cases you think we will have problems?
> >
> > cayenne+scala or cayenne+groovy - this is next features after AR ;)
> >
> > > Perhaps I misunderstood your idea... would your wrapper create a
> > singleton Context that lives for the life of the application or one per
> > persisted object?
> > I propose to inject it through DI.
> >
> > For example
> > SpringContextHolder.getSpringContex().getBean("cayenneContex")
> > and user may specify how to receive it. maybe one per thread / request,
> > maybe other way.
> >
> > Have a nice day!
> >
> > 2012/12/27 emeka okafor <emeka_1978@yahoo.com>
> >
> >> It depends on what you call service. Is a service a message call that is
> >> remote in the sense that it is outside of the same JVM or is a service
> any
> >> random function that do not belong to the domain object? If I am
> working in
> >> a j2ee/spring environment i.e I want to use ejbs or have a container
> >> managed my objects, then you are right and I am going to have a problem
> >> integrating cayenne objects into that environment and will do all kind
> of
> >> gymnastic to accomodate for that, by creating fake pojos with wrapper
> and
> >> annotations so that the container can inject those services. In this
> case,
> >> my cayenne objects become naked(cayenne is not to blame for that).
> >> Personally I would rather program in groovy with metaprogramming than do
> >> all that stuff if I had to. Beside that I rather do simple stuffs like
> the
> >> webobjects guys do. You do not hear them complain about such things like
> >> services, and dependency injection and what not. I mean, last time I
> >> checked, Apple Itunes
> >>  was running on a technologie similar to cayenne.
> >>
> >>
> >> ________________________________
> >>  From: Juan José Gil <matero@gmail.com>
> >> To: user@cayenne.apache.org; emeka okafor <emeka_1978@yahoo.com>
> >> Sent: Wednesday, December 26, 2012 10:32 PM
> >> Subject: Re: Add ActiveRecord support to Cayenne
> >>
> >> @emeka, in that regar of having rich models, how are you resolving the
> >> injection of services in your models? Or are you accessing your
> >> dependencies using static factories?
> >>
> >> @Дробеня Илья, in some pet projects I was using some very "powered"
> >> templates, wich constructs me metadata in my models and i use that for
> >> accessing fields at models (as some kind of reflection, but without the
> >> mess of java), query building, etc... but, after many tries, I don't
> think
> >> that java is the rigth lang for this kind of programming (too wordy),
> >> maybe
> >> cayenne+scala or cayenne+groovy would be a nice try ;)
> >>
> >>
> >> 2012/12/26 emeka okafor <emeka_1978@yahoo.com>
> >>
> >> > I am a little bit surprised that you call the cayenne way "anemic
> domain
> >> > model". I do not see what is anemic in this case.
> >> > /rant
> >> > The fact that a domain object has the ability to call save() on
>  itself
> >> or
> >> > not has nothing to do with anemism or richness. In cayenne you can and
> >> > should put your business logic in your domain objects. You only have
> >> > problems when you have to integrate with all the j2ee stuffs. They
> have
> >> > services all over the place, they create interfaces for everything
> >> (Spring
> >> > really pushed the enveloppe very far in that regard) because the
> >> > implementation may change somewhere in the future. As a result You
> have
> >> > your DAO implemented as a service and have to pass objects id to that
> >> > service to traverse relationships. Really unless you are having
> scaling
> >> > problems, the DAO as a service thing is weird. I was fortunate to work
> >> with
> >> > webobjects after a couple of years doing all the jee stuffs and only
> >> after
> >> > that did I learn what real domain driven design means, because it was
> >> > natural. No need for weird interfaces, weird pojos, weirds
> annotations.
> >> Now
> >> > what does it have to do with
> >> >  active records, actually nothing. It is just that someone said that
> >> with
> >> > cayenne you have an anemic domain model, which is not true.
> >> > /end of the rant
> >> >
> >> >
> >> > ________________________________
> >> >  From: Andrus Adamchik <andrus@objectstyle.org>
> >> > To: user@cayenne.apache.org
> >> > Sent: Wednesday, December 26, 2012 6:25 PM
> >> > Subject: Re: Add ActiveRecord support to Cayenne
> >> >
> >> > In ROP case the root cause is 2 separate disjoint models (doesn't
> matter
> >> > rich or anemic). A single anemic model would've allowed to define a
> >> common
> >> > set of "services".
> >> >
> >> > So while I am still on this rant, I think the "rich/anemic model"
> >> > discussion at the end may come down to modularity
> >> > requirements/expectations. One of the modularity paradigms is this:
> >> > "coarse-grained modules are easier to use, but harder to reuse; and a
> >> > corollary - fine-grained modules are harder to use, but easier reuse".
> >> >
> >> > For instance WO-world wasn't very keen on modularity, so rich models
> >> > worked relatively well (or was it because the original Objective C
> >> > implementation of WO allowed for categories to redefine existing
> >> classes in
> >> > runtime? ;)). JEE and enterprise apps in general strive for better
> >> > modularity so defining lots of business logic high up in your
> dependency
> >> > tree is going to cause lots of pain.
> >> >
> >> > But then again, I admit not everyone is writing the same applications
> >> that
> >> > I do :)
> >> >
> >> > Andrus
> >> >
> >> > On Dec 26, 2012, at 8:04 PM, Aristedes Maniatis <ari@maniatis.org>
> >> wrote:
> >> >
> >> > > On 26/12/12 11:40am, Andrus Adamchik wrote:
> >> > >> Ilya's point that we discussed a bit offline was that AR-like
> design
> >> is
> >> > more object-oriented, with object providing all operations on
> >> themselves.
> >> > The context will be taken from the current thread (something we
> already
> >> > provide). One piece of theory behind it is a reference to the Fowler's
> >> > criticism of "anemic domain model":
> >> > http://en.wikipedia.org/wiki/Anemic_domain_model  .
> >> > >
> >> > > I find this quite interesting. One problem we are trying to solve
on
> >> our
> >> > project right now is bringing together logic between the client and
> >> server
> >> > entities in a ROP system. Because Cayenne entities inherit from
> >> different
> >> > superclasses (what's with that?), it is very hard to keep the business
> >> > logic in a one place.
> >> > >
> >> > > Anemic models are all very well, but what do you do with the code?
> It
> >> > seems that all the options available to us aren't terribly convenient
> to
> >> > use. We either end up with zillions of interfaces or lots of static
> >> methods.
> >> > >
> >> > > AR is the opposite of anemic. All the Rails projects I've seen tend
> to
> >> > throw lots of code into the model. But because Ruby uses duck-typing
> >> > instead of interfaces, things don't get quite so messy. Even searching
> >> is
> >> > rooted in the model classes:
> >> > >
> >> > >   Artist.find(:name, "bob").sort(:age)
> >> > >
> >> > > or something like that.
> >> > >
> >> > > Ari
> >> > >
> >> > > --
> >> > > -------------------------->
> >> > > Aristedes Maniatis
> >> > > GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A
> >> > >
> >> >
> >>
> >
> >
> >
> > --
> > С уважением, Илья Дробеня.
> >
>
>
>
> --
> С уважением, Илья Дробеня.
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message