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.
Related
I'm new to functional languages and I was wondering why we can't pass a parameter by reference.
I found anserws saying that
you are not supposed to change the state of objects once they have been created
but I didn't quite get the idea.
It's not so much that you can't pass references, it's that with referential transparency there isn't a programmer-visible difference between references and values, because you aren't allowed to change what references point to. This makes it actually safer and more prevalent in pure functional programming to pass shared references around everywhere. From a semantic point of view, they may as well be values.
I think you have misunderstood the concept. Both Scheme and C/C++ are pass by value languages and most values are addresses (references).
Purely functional languages can have references and those are passed by value. What they don't have is redefining variables in the same scope (mutate bindings) and they don't have the possibility to update the object the reference points to. All operations return a fresh new object.
As an example I can give you Java's strings. Java is not purely functional but its strings are. If you change the string to uppercase you get a new string object in return and the original one has not been altered.
Most languages I know of are pass by value. Pass by name is alien to me.
Because if you pass params by reference you could change something in the parameter, which could introduce a side effect. Consider this:
function pay(person, cost) {
person.wallet -= cost;
}
function money(person) {
return person.wallet;
}
let joe = { name: "Joe", wallet: 300 };
console.log(money(joe)); // 300
pay(joe, 20);
console.log(money(joe)); // 280
The two money(joe) are taking the same input (the object joe) and giving different output (300, 280). This is in contradiction to the definition of a pure functional language (all functions must return the same output when given the same input).
If the program was made this way, there is no problem:
function pay(person, cost) {
return Object.freeze({ ...person, wallet: person.wallet - cost });
}
function money(person) {
return person.wallet;
}
let joe = Object.freeze({ name: "Joe", wallet: 300 });
console.log(money(joe)); // 300
let joe_with_less_money = pay(joe, 20);
console.log(money(joe)); // still 300
console.log(money(joe_with_less_money)); // 280
Here we have to fake pass-by-value by freezing objects (which makes them immutable) since JavaScript can pass parameters only one way (pass by sharing), but the idea is the same.
(This presupposes the implications of the term "pass-by-reference" that apply to languages like C++, where the implementation detail affects mutability, not the actual implementation detail of modern languages, where references are typically passed under the hood but immutability is assured by other means.)
I want to understand how hashmap works if an object has enum, because everytime an enum provides a random number. I provide below the code.
public class Person {
private String name;
private EmpType eType;
//equals() & hashcode() implementation
}
public enum EmpType {
PERMANENT,TEMPORARY
}
If an object has enum, everytime it provides a different hashcode. If the map is serialized, can we ensure that we can retrieve the same value for a particular object ?
The hash code is varies only from one JVM execution to another. Within one program it remains constant, so hash maps will work fine. Serialization of hash maps doesn't involve storing hash code at all. It just serializes its elements (keys and values) and recalculates hash code when those are deserialized.
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).
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.
Let say we have :
Map hm = new HashMap();
How to avoid putting duplicate values(Emplyees) in this HashMap?
I assume you are coding in Java, so:
if(!myMap.containsKey(myKey)){
myMap.put(myKey, myValue);
}
The good thing with HashMap is that the containsKey method takes constant time (or constant amortized time) regardless of the number of elements in your map so you can call it without bothering of the time it may take!
If you use an other language, the logic remains the same.
I think duplicate values in Map can be removed using this generic method if your userdefined object is overridden with equals and hashcode from object class
public static <K, V > Map<K,V> genericMethodtoDeleteMapduplicate(Map<K, V> pMap) {
Map<K,V> mapWithoutDup=new HashMap<>();
Set<V> totalvaluesPresent=new HashSet<>();
for (Map.Entry<K, V> a : pMap.entrySet()) {
if(totalvaluesPresent.add(a.getValue())){
mapWithoutDup.put(a.getKey(), a.getValue());
}
}
return mapWithoutDup;
}
Not sure what language you are using but in java for Hashmap their are:
boolean containsKey(Object key)
- Returns true if this map contains a mapping for the
specified key.
and
boolean containsValue(Object value)
- Returns true if this map maps one or more keys to the
specified value.
Just call which ever one makes more sense for you to check if the entry is already in the map, if it is then you know its a duplicate, otherwise put it in. I'm certain whatever language you are using will have something similar!!