I think I understand Value Objects ( they have no conceptual identity, set of its attributes is its definition etc) and how they differ from Entities, but I'm still puzzled whether a value of a primitive type ( int, string ...) being assigned directly to property of an Entity is also considered a VO.
For example, in the following code an object ( of type Name ) assigned to Person.Name is a VO, but are values assigned to Person.FirstName, Person.LastName and Person.Age also considered VO?
public class Person
{
public string FirstName = ...
public string LastName = ...
public int Age = ...
public Name Name = ...
...
}
public class Name
{
public string FirstName = ...
public string LastName = ...
public int Age = ...
}
thank you
It doesn't matter if a value is a primitive type (such as string or int) or a complex type composed of primitive types (such as Name). What matters is that you think of it as a mere "value" without any identity -- then it is a value object.
The decision to keep it a primitive or wrap it in a class is an implementation detail. Specific types are easier to extend in the future / add functionality than primitive types.
Check this related question... Value objects are more an implementation thing that a "conceptual" one... If you think about it, singleton and flyweight pattern are about turning an object with an identity to an value object for optimization purposes... It's also related to choosing to implement something as mutable or immutable. You can always say that Person is immutable, but after a while, you are a "new" person with different attributes. It's an implementation decision, not a domain or conceptual one. (Immutable things tend to be value objects, and the mutable ones identity objects).
Related
I have doubts about where I should check my invariants...
For example, I have a Question aggregate with the following invariant:
The question's text must be not null
The question's text must have a length between 100 and 500 characters
I have read that the best place to check the invariants is in aggregate's constructor, but I have also read it would be recommended push domain logic in value objects, for example.
A possible aggregate's implementation could be:
public class Question {
private final id: QuestionId;
private final text: QuestionText
public Question(id: String, text: String) {
// verify invariants
ensureLengthText(text); // this method verifies the invariant
this.id = new QuestionId(id);
this.text = new QuestionText(text);
}
}
QuestionId and QuestionText are value objects.
In this case, in the aggregate we can see the invariant explicitly.
But, if we push that invariant logic in QuestionText value object, in the aggregate we will not see that invariant... then, what would be the best approach?
If you can easily enforce an invariant (e.g. "Question texts cannot be shorter than 100 characters nor longer than 500 characters") in a value object, I recommend doing so. Question inherits that invariant (and any and all others from QuestionText) by saying that text is a QuestionText.
Haskell enables one to construct algebraic data types using type constructors and data constructors. For example,
data Circle = Circle Float Float Float
and we are told this data constructor (Circle on right) is a function that constructs a circle when give data, e.g. x, y, radius.
Circle :: Float -> Float -> Float -> Circle
My questions are:
What is actually constructed by this function, specifically?
Can we define the constructor function?
I've seen Smart Constructors but they just seem to be extra functions that eventually call the regular constructors.
Coming from an OO background, constructors, of course, have imperative specifications. In Haskell, they seem to be system-defined.
In Haskell, without considering the underlying implementation, a data constructor creates a value, essentially by fiat. “ ‘Let there be a Circle’, said the programmer, and there was a Circle.” Asking what Circle 1 2 3 creates is akin to asking what the literal 1 creates in Python or Java.
A nullary constructor is closer to what you usually think of as a literal. The Boolean type is literally defined as
data Boolean = True | False
where True and False are data constructors, not literals defined by Haskell grammar.
The data type is also the definition of the constructor; as there isn't really anything to a value beyond the constructor name and its arguments, simply stating it is the definition. You create a value of type Circle by calling the data constructor Circle with 3 arguments, and that's it.
A so-called "smart constructor" is just a function that calls a data constructor, with perhaps some other logic to restrict which instances can be created. For example, consider a simple wrapper around Integer:
newtype PosInteger = PosInt Integer
The constructor is PosInt; a smart constructor might look like
mkPosInt :: Integer -> PosInteger
mkPosInt n | n > 0 = PosInt n
| otherwise = error "Argument must be positive"
With mkPosInt, there is no way to create a PosInteger value with a non-positive argument, because only positive arguments actually call the data constructor. A smart constructor makes the most sense when it, and not the data constructor, is exported by a module, so that a typical user cannot create arbitrary instances (because the data constructor does not exist outside the module).
Good question. As you know, given the definition:
data Foo = A | B Int
this defines a type with a (nullary) type constructor Foo and two data constructors, A and B.
Each of these data constructors, when fully applied (to no arguments in the case of A and to a single Int argument in the case of B) constructs a value of type Foo. So, when I write:
a :: Foo
a = A
b :: Foo
b = B 10
the names a and b are bound to two values of type Foo.
So, data constructors for type Foo construct values of type Foo.
What are values of type Foo? Well, first of all, they are different from values of any other type. Second, they are wholly defined by their data constructors. There is a distinct value of type Foo, different from all other values of Foo, for each combination of a data constructor with a set of distinct arguments passed to that data constructor. That is, two values of type Foo are identical if and only if they were constructed with the same data constructor given identical sets of arguments. ("Identical" here means something different from "equality", which may not necessarily be defined for a given type Foo, but let's not get into that.)
That's also what makes data constructors different from functions in Haskell. If I have a function:
bar :: Int -> Bool
It's possible that bar 1 and bar 2 might be exactly the same value. For example, if bar is defined by:
bar n = n > 0
then it's obvious that bar 1 and bar 2 (and bar 3) are identically True. Whether the value of bar is the same for different values of its arguments will depend on the function definition.
In contrast, if Bar is a constructor:
data BarType = Bar Int
then it's never going to be the case that Bar 1 and Bar 2 are the same value. By definition, they will be different values (of type BarType).
By the way, the idea that constructors are just a special kind of function is a common viewpoint. I personally think this is inaccurate and causes confusion. While it's true that constructors can often be used as if they are functions (specifically that they behave very much like functions when used in expressions), I don't think this view stands up under much scrutiny -- constructors are represented differently in the surface syntax of the language (with capitalized identifiers), can be used in contexts (like pattern matching) where functions cannot be used, are represented differently in compiled code, etc.
So, when you ask "can we define the constructor function", the answer is "no", because there is no constructor function. Instead, a constructor like A or B or Bar or Circle is what it is -- something different from a function (that sometimes behaves like a function with some special additional properties) which is capable of constructing a value of whatever type the data constructor belongs to.
This makes Haskell constructors very different from OO constructors, but that's not surprising since Haskell values are very different from OO objects. In an OO language, you can typically provide a constructor function that does some processing in building the object, so in Python you might write:
class Bar:
def __init__(self, n):
self.value = n > 0
and then after:
bar1 = Bar(1)
bar2 = Bar(2)
we have two distinct objects bar1 and bar2 (which would satify bar1 != bar2) that have been configured with the same field values and are in some sense "equal". This is sort of halfway between the situation above with bar 1 and bar 2 creating two identical values (namely True) and the situation with Bar 1 and Bar 2 creating two distinct values that, by definition, can't possibly be the "same" in any sense.
You can never have this situation with Haskell constructors. Instead of thinking of a Haskell constructor as running some underlying function to "construct" an object which might involve some cool processing and deriving of field values, you should instead think of a Haskell constructor as a passive tag attached to a value (which may also contain zero or more other values, depending on the arity of the constructor).
So, in your example, Circle 10 20 5 doesn't "construct" an object of type Circle by running some function. It directly creates a tagged object that, in memory, will look something like:
<Circle tag>
<Float value 10>
<Float value 20>
<Float value 5>
(or you can at least pretend that's what it looks like in memory).
The closest you can come to OO constructors in Haskell is using smart constructors. As you note, eventually a smart constructor just calls a regular constructor, because that's the only way to create a value of a given type. No matter what kind of bizarre smart constructor you build to create a Circle, the value it constructs will need to look like:
<Circle tag>
<some Float value>
<another Float value>
<a final Float value>
which you'll need to construct with a plain old Circle constructor call. There's nothing else the smart constructor could return that would still be a Circle. That's just how Haskell works.
Does that help?
I’m going to answer this in a somewhat roundabout way, with an example that I hope illustrates my point, which is that Haskell decouples several distinct ideas that are coupled in OOP under the concept of a “class”. Understanding this will help you translate your experience from OOP into Haskell with less difficulty. The example in OOP pseudocode:
class Person {
private int id;
private String name;
public Person(int id, String name) {
if (id == 0)
throw new InvalidIdException();
if (name == "")
throw new InvalidNameException();
this.name = name;
this.id = id;
}
public int getId() { return this.id; }
public String getName() { return this.name; }
public void setName(String name) { this.name = name; }
}
In Haskell:
module Person
( Person
, mkPerson
, getId
, getName
, setName
) where
data Person = Person
{ personId :: Int
, personName :: String
}
mkPerson :: Int -> String -> Either String Person
mkPerson id name
| id == 0 = Left "invalid id"
| name == "" = Left "invalid name"
| otherwise = Right (Person id name)
getId :: Person -> Int
getId = personId
getName :: Person -> String
getName = personName
setName :: String -> Person -> Either String Person
setName name person = mkPerson (personId person) name
Notice:
The Person class has been translated to a module which happens to export a data type by the same name—types (for domain representation and invariants) are decoupled from modules (for namespacing and code organisation).
The fields id and name, which are specified as private in the class definition, are translated to ordinary (public) fields on the data definition, since in Haskell they’re made private by omitting them from the export list of the Person module—definitions and visibility are decoupled.
The constructor has been translated into two parts: one (the Person data constructor) that simply initialises the fields, and another (mkPerson) that performs validation—allocation & initialisation and validation are decoupled. Since the Person type is exported, but its constructor is not, this is the only way for clients to construct a Person—it’s an “abstract data type”.
The public interface has been translated to functions that are exported by the Person module, and the setName function that previously mutated the Person object has become a function that returns a new instance of the Person data type that happens to share the old ID. The OOP code has a bug: it should include a check in setName for the name != "" invariant; the Haskell code can avoid this by using the mkPerson smart constructor to ensure that all Person values are valid by construction. So state transitions and validation are also decoupled—you only need to check invariants when constructing a value, because it can’t change thereafter.
So as for your actual questions:
What is actually constructed by this function, specifically?
A constructor of a data type allocates space for the tag and fields of a value, sets the tag to which constructor was used to create the value, and initialises the fields to the arguments of the constructor. You can’t override it because the process is completely mechanical and there’s no reason (in normal safe code) to do so. It’s an internal detail of the language and runtime.
Can we define the constructor function?
No—if you want to perform additional validation to enforce invariants, you should use a “smart constructor” function which calls the lower-level data constructor. Because Haskell values are immutable by default, values can be made correct by construction; that is, when you don’t have mutation, you don’t need to enforce that all state transitions are correct, only that all states themselves are constructed correctly. And often you can arrange your types so that smart constructors aren’t even necessary.
The only thing you can change about the generated data constructor “function” is making its type signature more restrictive using GADTs, to help enforce more invariants at compile-time. And as a side note, GADTs also let you do existential quantification, which lets you carry around encapsulated/type-erased information at runtime, exactly like an OOP vtable—so this is another thing that’s decoupled in Haskell but coupled in typical OOP languages.
Long story short (too late), you can do all the same things, you just arrange them differently, because Haskell provides the various features of OOP classes under separate orthogonal language features.
I have a grammar that looks like
A:
...
B:
...
I want to be able to give each element of type B some serial ID. So every time that the grammar creates a B object, it gets a (unique) new ID as a field.
I tried to do something like:
B:
myID=Tracer.getID()
...
where:
class Tracer {
static int ID=0;
static int getID() { return ID++;}
But I can't call external java class from the grammar.
It would be better if it's solvable without touching the src-gen files.
Thanks.
Are you aware that in textual models, there is no such thing as object identity? I.e. you fundamentally can't say that any two objects in different ASTs are identical. You can only establish an interpretation of equivalence using diff algorithms.
That aside, if you only need a temporary identity, what about using Object.hashCode()?
What is the difference between immutable and final?
For example, this
#Immutable
public MyClass {
String property1
MyOtherClass property2
List myLIst
}
and
public final MyClass {
final String property1
final MyOtherClass property2
final List myLIst
}
The #Immutable annotation instructs the compiler to execute an AST transformation which adds the necessary getters, constructors, equals, hashCode and other helper methods that are typically written when creating immutable classes with the defined properties.
[1]
So, #Immutable generates helper functionality, similar to "case classes" in Scala.
The final keyword instructs the compiler that the particular variable is immutable, as it means in Java.
The first class is equivalent to the second class with several helper functions.
[1] http://groovy.codehaus.org/gapi/groovy/transform/Immutable.html
The #Immutable annoatation causes the compiler to transform a class such that it cannot be changed after construction. The final modifier - when applied to a variable/field - ensures that the variable cannot be reassigned after construction. When applied to a class, final prevents the class from being extended.
When a class is declared immutable, the types of all the properties must also be immutable, or the compiler must know how to make them immutable, which it does for Date, Collection, Map, etc. So in your example above MyOtherClass must also be immutable.
To illustrate the difference between a final field and an immutable field
class FinalClass {
final List list
}
because list is final, you cannot reassign it after construction like this:
def fc = new FinalClass(list: [])
fc.list = [] // throws a ReadOnlyPropertyException
But you can mutate this field, e.g.
def fc = new FinalClass(list: [])
fc.list << new Object()
By contrast, a field of an immutable class can neither be reassigned nor mutated. For example, if FinalClass is annotated with #Immutable the following attempt to mutate a field would cause an exception to be thrown
def fc = new FinalClass(list: [])
fc.list << new Object() // throws an UnsupportedOperationException
I have the following code (note the code below doesnt update the property)
private void queryResultsFilePath_Click(object sender, EventArgs e)
{
Library.SProc.Browse browser = new Browse();
browser.selectFile(QueryResultFilePath);
}
and
public class Browse
{
public void selectFile(string propertyName)
{
...
propertyName = browserWindow.FileName;
}
}
Now i realise that i need to change the second method so that it returns a string and manually assign it to the property in the first example.
What im unsure of is that i thought that when i assigned a ref type as an actual parameter of a method, a copy of its value on the stack (ie its memory address in the heap) was copied to the new location on the stack for the methods formal parameter, so they are both pointing to the same memory address on the heap. So when i changed the value of the formal parameter, it would actually change the value stored on the heap and thus the actual parameters value.
Obviously im missing something since im having to return a string and manually assign it to the property. If someone could point out what ive misunderstood id appreciate it.
Thanks.
I believe the missing piece here is: strings are immutable.
Although you pass it by reference, as soon as anything attempts to mutate the string, a new string is created leaving the old one intact.
I believe it is the only reference type that has enforced immutability.
From MSDN:
Strings are immutable--the contents of a string object cannot be
changed after the object is created, although the syntax makes it
appear as if you can do this. For example, when you write this code,
the compiler actually creates a new string object to hold the new
sequence of characters, and that new object is assigned to b. The
string "h" is then eligible for garbage collection.
Further reading:
http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/e755cbcd-4b09-4a61-b31f-e46e48d1b2eb
If you wish the method to "change" the caller's string then you can simulate this using the ref keyword:
public void SelectFile(ref string propertyName)
{
propertyName = browserWindow.FileName;
}
In this example, the parameter propertyName will be assigned to in the method, because of ref being used, this also changes the string that the caller is pointing to. Note here that immutability is still enforced. propertyName used to point to string A, but after assignment now points to string B - the old string A is now unreferenced and will be garbage collected (but importantly still exists and wasn't changed - immutable). If the ref keyword wasn't used, the caller would still point at A and the method would point at B. However, because the ref keyword was used the callers variable now points to string B.
This is the same effect as the following example:
static void Main(string[] args)
{
MyClass classRef = new MyClass("A");
PointToANewClass(ref classRef);
// classRef now points to a brand new instance containing "B".
}
public static void PointToANewClass(ref MyClass classRef)
{
classRef = new MyClass("B");
}
If you try the above without the ref keyword, classRef would still point to an object containing "A" even though the class was passed by reference.
Don't get confused between string semantics and ref semantics. And also don't get confused between passing something by reference and assignment. Stuff is technically never passed by reference, the pointer to the object on the heap is passed by value - hence ref on a reference type has the behaviour specified above. Also hence not using ref will not allow a new assignment to be "shared" between caller and method, the method has received its own copy of the pointer to the object on the heap, dereferencing the pointer has the usual effect (looking at the same underlying object), but assigning to the pointer will not affect the callers copy of the pointer.
I'm really grateful to Adam Houldsworth, because I've finally understood how the .NET framework uses reference parameters and what happens with the string.
In .NET there are two kind of data types:
value type: primitive types like int, float, bool, and so on
reference type: all the other objects, including string
In the case of reference type, the object is stored in the heap, and a variable only holds a reference pointing to this object. You can access the object's properties through the reference and modify them. When you pass one of this variables as parameter, a copy of the reference pointing to the same object is passed on to the method body. So, when you access and modify properties, you are modifyin gthe same object stored on the heap. I.e, this class is a reference object:
public class ClassOne
{
public string Desc { get; set; }
}
When you do this
ClassOne one = new { Desc = "I'm a class one!" };
there's an object on the heap pointed to by the reference one. If you do this:
one.Desc = "Changed value!";
the object on the heap has been modified. If you pass this reference as a parameter:
public void ChangeOne(ClassOne one)
{
one.Desc = "Changed value!"
}
The original object on the heap is also changed, because one helds a copy of the original reference that points to the same object on the heap.
But if you do this:
public void ChangeOne(ClassOne one)
{
one = new ClassOne { Desc ="Changed value!" };
}
The original object is unchanged. That's because one was a copy of the reference that it's now pointing to a different object.
If you pass it explicitly by reference:
public void ChangeOne(ref ClassOne one)
{
one = new ClassOne { Desc ="Changed value!" };
}
one inside this method is not a copy of the outer refernce, but the reference itself, so, the original reference now points to this new object.
strings are inmutable. This means that you cannot change a string. if you try to do so, a new string is created. So, if you do this:
string s = "HELL";
s = s + "O";
The second line creates a new instance of string, with the value "HELLO" and "HELL" is abandoned on the heap (left to be garbage collected).
So it's not possible to change it if you pass it as a parameter like this:
public void AppendO(string one)
{
one = one + "O";
}
string original = "HELL";
AppendO(original);
the original string is left as is. The code inside the function creates a new object, and assign it to one, which is a copy of original reference. But original keeps pointing to "HELL".
In the case of value types, when they are passed as parameters to a function, they are passed by value, i.e. the function receives a copy of the original value. So, any modification done to the object inside the function body won't affect the original value outside the function.
The problem is that, although string is a reference type, it looks as if it behaves like a value type (this applies to comparisons, passing parameters, and so on).
However, as explained above, it's possible to make the compiler pass a reference type by reference using the ref keyword. This also also works for strings.
You can check this code, and you'll see that the string is modified (this would also apply to an int, float or any other value type):
public static class StringTest
{
public static void AppednO(ref string toModify)
{
toModify = toModify + "O";
}
}
// test:
string hell = "HELL";
StringTest.AppendO(ref hell);
if (hell == "HELLO")
{
// here, hell is "HELLO"
}
Note that, for avoiding errors, when you define a parameter as ref, you also have to pass the parameter with this modifier.
Anyway, for this case (and similar cases) I'd recommend you to use the more natural functional syntax:
var hell = StringTest.AppendO(hell);
(Of course, in this case, the function will have this signature and corresponding implementation:
public static string AppendO(string value)
{
return value + "O";
}
If you're going to make many changes to a string, you should use the StringBuilder class, which works with "mutable strings".
How a property, of type string, is passed
Strings are immutable and therefore you are passing copies of them to methods. This means that the copy changes but the original parameter stays the same.