Java has these strange vocabulary words like "POJO" and "Bean" and it's very weird for me to hear that I don't have the right magic beans to grow some sort of program beanstalk but here we are.
By contrast, I find Haskell's data
declarations sublimely simple.
I came up with a mental model for beans and I want to know if it is too simple -- if there is something that it is not capturing or if there is something more restrictive than that. This is to compare it to Haskell's Last monoid combined with its product types, so that a bean like
@Data
@NoArgsConstructor
class ClientContact implements Serializable {
private Long clientId;
private String displayName;
private String emailAddress;
private String notes;
}
is perhaps meant to just be a monoid like,
data ClientContact =
ClientContact { clientId :: Last Integer
, displayName :: Last Name
, emailAddress :: Last Email
, notes :: Last Notes
} deriving (Eq, Read, Show)
-- why can't we derive Monoid? sigh...
instance Semigroup ClientContact where
ClientContact a b c d <> ClientContact a' b' c' d' =
ClientContact (a <> a') (b <> b') (c <> c') (d <> d')
instance Monoid ClientContact where
mempty = ClientContact mempty mempty mempty mempty
This "looks like" the sorts of Java code I am seeing, e.g.
-- maybe some of the setters/getters are more common in the codebase
instance HasClientId ClientContact where
getClientId = clientId
setClientId cid = mempty {clientId = Last(Just cid)}
-- maybe some have some extra functionality on them?
setDisplayName name = mempty {displayName = trim name}
-- but the point is, ~= return myContact.setClientId(123).setDisplayName("CR Drost")
return $ myContact <> setClientId 123 <> setDisplayName "CR Drost"
-- Or, ~= BeanUtils.copyProperties(postData, dbContact, "clientId", "emailAddress")
let newContact = dbContact <> postData{clientId = mempty, emailAddress = mempty}
Is this what beans are meant to capture? Something about "I am gonna have a parser that needs to initialize an empty ClientContact and then slowly add parameters to it, I want to ensure that there is a sort of basic algebra to these things and I am willing to make everything nullable to ensure that can happen" or so?
Or are beans meant to also be used with, say, arbitrary side-effects and perhaps other stateful or monoidal behaviors, and this description is too simple? Is the contract something other than "after a set, every get must return that value until some other set happens...?" For example is something still a Bean if every setWhatever() has a side-effect of saving the whatever to a database?