In various examples of an onEvent sometimes the variables are declared as final and sometimes not.
For example:
public void onEvent(final ValueEvent entry, final long sequence, final boolean onEndOfBatch)
opposed to
public void onEvent(ValueEvent entry, long sequence, boolean onEndOfBatch)
Please can I get a comment on the reason and use of final?
The short answer is the LMAX coding standards call for parameters to be final, however that is just a matter of convention.
Adding final to the parameter just means that the method cannot change the value of the primitives or re-assign the references for the objects passed through. See here for further details on final
Many people consider assigning a new value to a parameter to be bad practice and lead to many subtle bugs.
Related
Let me preface this by apologising if this was asked before (I could not find a similar question when doing a quick search).
The DDD pattern is centered around defining and isolating aggregates to split the business complexity into a more manageable chunks, and it is strictly forbidden for an aggregate to hold any kind of relation to other aggregates. The references to the other aggregates are instead to be stored as ids that can then be used to fetch the other aggregates on demand. Therefore a single aggregate would only contain its properties, value objects and references to other aggregates.
To use a common example (User, Order) it would look as such:
public class User {
private Long id;
private List<Long> orders;
}
and
public class Order {
private Long id;
private Long userId;
}
However I have seen multiple sources use another layer of encapsulation for the aggregate references, turning them from the property types (as defined in the example above) into value objects like shown below:
public class User {
private Long id;
private List<OrderId> orders;
}
and
public class Order {
private Long id;
private UserId userId;
}
I am rather new to DDD so I want to understand the benefit of doing so when working with non-composite ids.
On the first glance I see a lot of pretty obvious drawbacks (or such they seem to me!), like explosion in quantity of common base types, serialization issues, extra complexity when working with the code and accessing the values stored within these holders, however I am sure that it would not be done so without a very good reason that I am overlooking somewhere.
Any comments, thoughts or feedback would be very welcome!
This is a domain abstraction
private UserId userId;
This is a data structure
private Long userId;
Your domain logic (probably) doesn't care, or need to care, about the underlying data structure that supports representations of UserId, or how they are stored in the database, or any of that nonsense.
The broad term is "information hiding" -- creating firewalls around decisions such that the decision can be changed without that change cascading into the rest of the system. See Parnas 1971.
There are some mistake detection benefits as well. Consider
todays_order.userId + yesterdays_order.userId
That's utter nonsense code; adding two identifiers together doesn't do anything useful. But adding to Long values together is a perfectly normal thing to do in other contexts, and the compiler isn't going to catch this mistake.
recindOrder(orderId, userId)
Did you catch the bug? I've got the arguments in the wrong order! When the method signature is
recindOrder(Long userId, Long orderId)
The machine can't help me catch the problem, because I haven't given it the hints that it needs to look beyond the data structures.
There is also a theory that by providing an explicit representation of the domain value, that code attracts other related functions that otherwise might not find a home -- in effect, it improves the coherence of your design.
(In my experience, that's less true of semantically opaque types like identifiers than it is for numerical abstractions like money. However, if you have some identifiers that are reserved, then the identifier type becomes a convenient place to document the reservation.)
Assuming that I want that following Value Object contains always capitalized String value. Is it eligible to do it like this with toUpperCase() in constructor?
class CapitalizedId(value: String) {
val value: String = value.toUpperCase()
// getters
// equals and hashCode
}
In general, I do not see a problem of performing such a simple transformation in a value object's constructor. There should of course be no surprises for the user of a constructor but as the name CapitalizedId already tells you that whatever will be created will be capitalized there is no surprise, from my point of view. I also perform validity checks in constructors to ensure business invariants are adhered.
If you are worried to not perform operations in a constructor or if the operations and validations become too complex you can always provide factory methods instead (or in Kotlin using companion, I guess, not a Kotlin expert) containing all the heavy lifting (think of LocalDateTime.of()) and validation logic and use it somehow like this:
CapitalizedId.of("abc5464g");
Note: when implementing a factory method the constructor should be made private in such cases
Is it eligible to do it like this with toUpperCase() in constructor?
Yes, in the sense that what you end up with is still an expression of the ValueObject pattern.
It's not consistent with the idea that initializers should initialize, and not also include other responsibilities. See Misko Hevery 2008.
Will this specific implementation be an expensive mistake? Probably not
According to DDD principles, it's often advised that value objects be used to encode values which don't have a life cycle of their own, but are merely values. By design, such objects are made immutable. They often replace primitives, which makes the code more semantic and error-safe.
The rationale is very sensible, but sometimes it leads to some cumbersome operations. For example, consider the case where an address is encoded as a value object along the lines of:
class Address extends ValueObject {
public Address(String line1, String line2, String postalCode, String String country) {
...
}
...
}
In an application, it wouldn't be unusual for a user to change only one field of an address. In order to achieve that in code, one would have to do something like:
String newCity = ...;
Address newAddress = new Address(
oldAddress.getLine1(),
oldAddress.getLine2(),
oldAddress.getPostalCode(),
newCity,
oldAddress.getCountry());
This could lead to some very repetitive and overly verbose code. What are some good strategies for avoiding this, while keeping immutable value objects?
My own ideas:
Private setters, which could enable helper methods like this:
public Address byChangingPostalCode(String newPostalCode) {
Address newAddress = this.copy();
newAddress.setPostalCode(newPostalCode);
return newAdress;
}
A downside is that the object now isn't immutable anymore, but as long as that's kept private, it shouldn't be a problem, right…?
Make the value object a full-fledged entity instead. After all, the need for fields to be modified over a longer time indicates that it does have a life cycle. I'm not convinced by this though, as the question regards developer convenience rather than domain design.
I'll happily receive your suggestions!
UPDATE
Thanks for your suggestions! I'll go with private setters and corrective methods.
There's nothing wrong with having immutable values return other immutable values.
Address newAddress = oldAddress.correctPostalCode(...);
This is my preferred approach within the domain model.
Another possibility is to use a builder
Address new Address = AddressBuilder.from(oldAddress)
.withPostalCode(...)
.build()
I don't like that one as much, because build isn't really part of the ubiquitous language. It's a construction I'm more likely to use in a unit test, where I need a whole address to talk to the API but the test itself only depends on a subset of the details.
Private setters, which could enable helper methods like this:
This is my preferred solution for changing a Value object. The naming of the method should be from the ubiquitous language but this can be combined to a team/programming language convention. In PHP there is a known convention: immutable command method names start with the word "with". For example withCorrectedName($newName).
The object must not be fully constant but only act as such in order to be considered immutable.
Make the value object a full-fledged entity instead.
It wouldn't be a ValueObject anymore, so don't!
I would solve this with derive methods:
Address newAddress = oldAddress.derive( newPostalCode);
Address newAddress = oldAddress.derive( newLine1 );
And so on...
Please excuse my naivety as I am not familiar with exploiting or eliminating software vulnerabilities, so I may be asking a question that doesn't make any sense. This is something I was thinking about recently and couldn't find anything online that specifically addressed my question.
Please compare the following classes (Java):
public class ProvidesCollection {
private Item[] items;
public Item[] getItemsArray() {
return Arrays.copyOf(items, items.length);
}
}
public class ContainsCollection {
private Item[] items;
public void actionItem(int itemNumber, ItemAction itemAction) {
if(itemNumber < 0 || itemNumber > items.length)
return; // Or handle as error
Item i = items[itemNumber - 1];
if(i != null)
itemAction.performOn(i);
}
}
The ProvidesCollection class is a typical OO design. The caller is trusted to loop through the items array returned from getItemsArray. If the caller forgets to do a bounds check it could open the code to a buffer overflow attack (if I'm not mistaken). I know Java's memory management avoids buffer overflows, so maybe Java is a bad example. Lets assume there is no mechanism for catching overflows.
The ContainsCollection class keeps the array completely hidden. Notice how the actionItem method allows the programmer to check for input errors and resolve them. Those responsible for implementing the API have more control over the data and flow of execution.
I would like to know, is the ContainsCollection class more secure than the ProvidesCollection class? Is there any evidence that avoiding return values (void methods) helps at all to remove a hacker's ability to exploit errors in the code?
No, void methods are not intrinsically more secure than methods that return values. You can write secure methods that return values, and you can write insecure methods that return nothing.
Typically, you will have void methods when you want to encapsulate some code that achieves a side-effect. For example, sending a file to a printer, changing the internal state of an object, or performing some other action. That should be the litmus test of whether or not the signature's return type should be void -- when it's a "fire and forget" type of operation.
Methods that return values are really only more insecure than void methods when they expose sensitive data to unscrupulous people. However that doesn't mean that the same unscrupulous people couldn't pass certain data into a void method's arguments to compromise security. Though void methods don't return values, they can still throw exceptions. A caller could possibly learn certain things about a void method's data by making it throw exceptions and try/catching them. Also, I have had the unfortunate opportunity to read code that logged passwords to trace files, and that logging method was void.
Say your Item object had properties like CreditCardNumber and SocialSecurityNumber. In this case, your first method may potentially expose a security vulnerability. However you could mitigate that by encrypting those values before returning the array reference (or do not even expose them at all). Any operations that need to operate with the credit card number to perform a side-effect action (such as authorizing a transaction) could be marked void, and do the decryption internally (or obtain the unencrypted value in an encapsulated operation).
But it's not necessarily the method's return signature that makes it more or less secure -- it's the data that is being exposed, and who it's being exposed to. Remember, anyone can write a silly void method that writes their database connection string to a public web page.
Update
...say a vulnerability exists because a method returns a bad value or
from bad usage of the return value. How can you fix the problem if
users depend on the returned value? There is no chance to go back and
remove the return because others depend on it.
If you need to, then you introduce a breaking change. This is a good reason to have clients depend on abstractions like interfaces rather than concrete types. Where you must have concrete types, design them carefully. Expose the minimum amount of information needed.
In the end, all data is just text. Your Item class will have string, integer, boolean, and other primitive values or nested objects that wrap primitives. You can still make changes to the encapsulated getItemsArray method to obfuscate sensitive data before returning the value if needed. If this has the potential to break client code, then you decide whether to bite the bullet and issue a breaking change or live with the flaw.
Is the void method better because you can fix it?
No. Then, you would end up with an API that only performs actions, like a black hole where you send data and never hear from it again. Like I said before, a method should be void if it performs some side effect and the caller does not need to get anything back (except possibly catching exceptions). When your API needs to return data, return an abstraction like an interface rather than a concrete type.
I like the new Dynamic keyword and read that it can be used as a replacement visitor pattern.
It makes the code more declarative which I prefer.
Is it a good idea though to replace all instances of switch on 'Type' with a class that implements dynamic dispatch.
class VistorTest
{
public string DynamicVisit(dynamic obj)
{
return Visit(obj);
}
private string Visit(string str)
{
return "a string was called with value " + str;
}
private string Visit(int value)
{
return "an int was called with value " + value;
}
}
It really depends on what you consider a "good idea".
This works, and it works in a fairly elegant manner. It has some advantages and some disadvantages to other approaches.
On the advantage side:
It's concise, and easy to extend
The code is fairly simple
For the disadvantages:
Error checking is potentially more difficult than a classic visitor implementation, since all error checking must be done at runtime. For example, if you pass visitorTest.DynamicVisit(4.2);, you'll get an exception at runtime, but no compile time complaints.
The code may be less obvious, and have a higher maintenance cost.
Personally, I think this is a reasonable approach. The visitor pattern, in a classic implementation, has a fairly high maintenance cost and is often difficult to test cleanly. This potentially makes the cost slightly higher, but makes the implementation much simpler.
With good error checking, I don't have a problem with using dynamic as an approach here. Personally, I'd probably use an approach like this, since the alternatives that perform in a reasonable manner get pretty nasty otherwise.
However, there are a couple of changes I would make here. First, as I mentioned, you really need to include error checking.
Second, I would actually make DynamicVisit take a dynamic directly, which might make it (slightly) more obvious what's happening:
class VistorTest
{
public string DynamicVisit(dynamic obj)
{
try
{
return Visit(obj);
}
catch (RuntimeBinderException e)
{
// Handle the exception here!
Console.WriteLine("Invalid type specified");
}
return string.Empty;
}
// ...Rest of code
The visitor pattern exists primarily to work around the fact that some languages do not allow double dispatch and multiple dispatch.
Multiple dispatch or multimethods is the feature of some object-oriented programming languages in which a function or method can be dynamically dispatched based on the run time (dynamic) type of more than one of its arguments. This is an extension of single dispatch polymorphism where a method call is dynamically dispatched based on the actual derived type of the object. Multiple dispatch generalizes the dynamic dispatching to work with a combination of two or more objects.
Until version 4, C# was one of those languages. With the introduction of the dynamic keyword, however, C# allows developers to opt-in to this dispatch mechanism just as you've shown. I don't see anything wrong with using it in this manner.
You haven't changed the type safety at all, because even a switch (or more likely dispatch dictionary, given that C# does not allow switching on type) would have to have a default case that throws when it can't match a function to call, and this will do exactly the same if it can't find a suitable function to bind to.