In my .Net programming I have taken a lot of design inspiration Domain
Driven Design and Eric Evans book in particular. The idea that a
developing a strong model of the problem domain is the most important
part of application design sits well with me.
It is obvious (to me) how to go about this in C#... a class for
Product, properties for Name, Price etc. Where should I go for advice
on how to model these ideas in Clojure?
As is typically the case with introductory material, the examples I'm
finding mostly deal with small problems which are solved with simple
lists and maps. This is fine for learning syntax and API but it's
hard to see how this scales to a meaningful application.
To give you an idea of where I'm coming from, my current work project
involves a database of around 120 tables and is exposed as a B2B web
site and several desktop applications. This isn't huge, but its big
enough that managing complexity becomes very important.
An open source Clojure project might make for good reading, are there
any out there that are end products rather than frameworks?
Cheers
Barry the Unenlightened
It's basically the same thing. Use namespaces instead of classes and
functions instead of methods.
You can use the same techniques -- encapsulation, abstract data types,
polymorphism -- that you would use in object-oriented programming.
Though only available on github right now, datatypes and protocols
will provide a very flexible, efficient data modeling scheme.
-SS
First, I also like DDD and think that it is a very good approach.
When I first came to Clojure I also tried to map everything to maps
(counterpart of objects), hierarchies, relationships, etc. This design
was the natural mechanism in my previous programming languages to
express everything. After a while I noticed that this is probably not
always the best way to define the domain in Clojure. Why should
objects + hierarchies be the "only true thing"?
After playing around with clojureql I noticed how well the relational
data model maps to a functional language. Processing lists (result
sets), joining, filter, group by, etc. are ideas I found in both
worlds. I am currently working on a toy project where I "declared" the
relational model as my dominant way to express data, persistent as
well as in-memory. So far I can say that it is working seamlessly.
Everything feels natural. The relational model is very well understood
and it was quite easy for me think in this model during coding as
well. Also, I was quite happy that I did not need to work with deep
hierarchies, etc. in a dynamic language anymore. Using the relational
model also gave me the SQL-DDL as an expressive way to define my data
schemes, types, etc.
Cheers,
Roman
A relevant paper Rich brought to the attention of the Clojure
community is:
Also added it as an suggestion in this thread if anyone else is
interested and wants to vote it up:
http://www.reddit.com/r/Clojure/comments/atzz7/full_disclojure_i_need_topics/c0jeke6
Cheers
Barry
Do you plan on setting this up somewhere? I'd be very interested to
see this, but it does not seem to be amongst your github-stuff.
On Jan 25, 12:30 pm, Stuart Sierra <the.stuart.sie...@gmail.com>
wrote:
At the moment I'm writing an account "object". I have some standard
CRUD type functions which operate on a map behind the scenes. I would
like to add some metadata to start specifying rules for validation, UI
generation and so on. The trouble is I can't really figure out where
to attach this metadata as I don't have a type definition as such,
e.g. I would do this in C#:
[Required, MaxLength(50)]
public string Name { get; set; }
defstruct seems promising though I can't find an example with
metadata.
Any pointers of where to start looking?
Cheers
Barry
You can attach metadata to Clojure constructs using the with-meta function:
user=> (def x {:name "Frank"})
#'user/x
user=> (def x-with-metadata (with-meta x {:RequiredParameter true,
:MaxLength 50}))
#'user/x-with-metadata
user=> (:MaxLength (meta x-with-metadata))
50
As for whether you want to define the metadata directly on your map,
or on functions that construct/operate on your map, or somewhere else,
that's your design decision.
e
(def user-metadata {:fields
((:name (required) (max-length 50))
(:email (required) (max-length 250)))})
(defn create-user [name, email]
(with-meta
{:name name :email email}
user-data))
I have a validate function which pulls the metadata from a given
instance and I can also access user-metadata directly for generating
UI forms and so on. The required and max-length functions each
generate little validators which have a predicate, error message
formatter etc.
Is this sensible Clojure?
Cheers
Barry
Am