Is there a standard Dart-way of making sure that all fields of a class are present in a constructor parameter list?
A very simplified example:
class Message{
String header;
String body;
DateTime sentAt;
Message(this.header, this.body, this.sentAt);
Message makeCopy(){
return Message(header, body, sentAt);
}
}
Now, a colleague comes along and adds the field String category, but forgets to add it to the constructor - and even worse, to the copy constructor. Is there a way to make the IDE (IntelliJ) issue a warning or error about this missing new field?
I'm thinking something similar to the warning issued when omitting an enum value from a switch-statement.
Or is there at least some way to make IntelliJ issue such a warning?
You will get warnings or errors if you make your fields final, it seems from your class that it would be a good idea anyway.
Now... granted, that only moves that problem to "how do I ensure my colleague makes all new fields final, too".
To do that, you can declare you class #immutable and then analyzers can warn you.
Analyzers:
pub.dev/packages/pedantic
pub.dev/packages/effective_dart
A possible class declaration:
import 'package:meta/meta.dart';
#immutable
class Message {
final String header;
final String body;
final DateTime sentAt;
const Message(this.header, this.body, this.sentAt);
Message makeCopy() {
return Message(header, body, sentAt);
}
}
Try adding a new field or removing one from the constructor, you will get errors.
There is only one way but it is in most cases the correct way to go.
You make all fields final and enforce immutability which will lead to a compiler error if the field is not initialized in the constructor.
You can use the dartanalyzer to enforce the following rules or at least generate warnings.
https://dart-lang.github.io/linter/lints/prefer_final_fields.html
https://dart-lang.github.io/linter/lints/prefer_const_declarations.html
To get started more easily with dartanalyzer you can look at the pedantic package or my preference lint.
This question already has answers here:
Scala: Can I declare a public field that will not generate getters and setters when compiled?
(2 answers)
Closed 7 years ago.
I wonder if it is possible to declare a public field in a Scala class. Scala normally generates a private field for val and var body variables/constructor parameters and getters/setters with the appropriate visibility.
I would like to know if it is possible to declare a public Java class field in Scala, not a getter.
PS: Why would anyone need that? It may be useful e.g. for integration with Java frameworks relying on fields:
class MyTest extends JUnitSuite {
#Rule
val temporaryFolder = new TemporaryFilder()
// throws java.lang.Exception: The #Rule temporaryFolder must be public
}
This is in response to the P.S, someone else has already posted an answer to the main question.
Because the logic behind using getters in setters (in java, for instance) is to "future-proof" your code, so that if your private field "x" somewhere down the line needs logic every time you get/set it, then you will just modify the method call and won't break any existing code that calls it. Whereas if you had just public fields and the need for logic arose, you would have to create getters/setters and then would break existing code due to changing the contract of the class. So scala just does this automatically to remove boilerplate code.
Hope this helps!
https://github.com/scala/scala/blob/2.11.x/src/library/scala/Predef.scala#L230
??? in scala is a function defined in predef that throws a NotImplementedError
In my project I am using Google Guice in order to inject dependencies, and thought it would be good to have a similar function that throws an exception if the injection never happened, in order to catch missing usages of the injector or missing #Inject annotations.
In my project I have a class that is expecting to be injected
class OScoreboard {
#Inject
val source :Provider[ScoreboardBuilder] = injected;
}
and an object
class ExpectedInjectionException(message: String = null, cause: Throwable = null) extends RuntimeException
object injected extends Nothing{
def apply : Nothing = {
throw new ExpectedInjectionException("Expected an injection")
}
}
But I get the error that injected isn't of type Provider[ScoreboardBuilder]
Am I abusing apply? How else can I reference the scala function apply (or even with a different name) without referencing the object injected?
Also I suspect that even if I fix this error, the function will be eagerly run causing the exception before injection happens, does that mean I need to make every injected field lazy, or is there another solution?
Edit:
The problem was my understanding of Scala.
vals are eagerly computed, so the ???-like function is immediately executed on class construction (which since it's using field injection, occurs immediately before injection happens) causing the field to never be injected.
Values like final fields in Java CAN be injected, because it's only a restriction by the byte code verifier. final fields can be written to fine by using reflection (which Guice does).
In order to answer this question there needs to be a way to delay the execution of the ???-like function/value until the field is first read. I'm unsure how, or if it is even possible. The other option is just to initialize them to null. But that will result in NullPointerExceptions which are famously unhelpful. I was hoping to use a null-like error with an explanation that the injection failed.
First of all: in one place you wrote INJECTED and in the other place injected. I'll assume this was a typo and that you mean the same thing with both.
An assignment like this:
val source :Provider[ScoreboardBuilder] = INJECTED;
will not work because you are trying to assign the object INJECTED to a variable of type Provider[ScoreboardBuilder]. The object is not of that type, so you can't do that assignment.
Maybe you expected that the object would behave like a function and that its apply method would automatically be called, but that's not how it works.
You can define INJECTED as a method inside your class:
class OScoreboard {
#Inject
val source :Provider[ScoreboardBuilder] = INJECTED
private def INJECTED : Nothing =
throw new ExpectedInjectionException("Expected an injection")
}
Or you can put it in a separate object, but then you'd have to import it in your class:
object injected {
def INJECTED : Nothing =
throw new ExpectedInjectionException("Expected an injection")
}
class OScoreboard {
import injected._
#Inject
val source :Provider[ScoreboardBuilder] = INJECTED
}
The problem was my understanding of Scala.
vals are eagerly computed, so the ??? function is immediately executed on class construction (which since it's using field injection, occurs immediately before injection happens) causing the exception to be thrown.
Making it lazy results in the injection happening using reflection without the exception being thrown on construction. HOWEVER the generated Java code is not aware that this happens. So when the injected value is accessed for the first time, the generated code replaces the injected reference with ??? then proceeds to throw the exception.
There is no way that I can see in order to make this work.
Neo4j server provides a REST api dealing with Json format.
I use spring-data-neo4j to map a domain object (in Scala) to a neo4j node easily.
Here's an example of my User node:
#NodeEntity
class User(#Indexed #JsonProperty var id: UserId)
UserId being a value object:
final case class UserId(value: String) {
override def toString = value
}
object UserId {
def validation(userId: String): ValidationNel[IllegalUserFailure, UserId] =
Option(userId).map(_.trim).filter(!_.isEmpty).map(userId => new UserId(userId)).toSuccess(NonEmptyList[IllegalUserFailure](EmptyId))
}
At runtime, I got this error:
Execution exception[[RuntimeException: org.codehaus.jackson.map.JsonMappingException: No serializer found for class com.myApp.domain.model.user.UserId and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: java.util.HashMap["value"])]]
Then, I came across this little article on the web, explaining a solution.
I ended up with this User class:
#NodeEntity
#JsonAutoDetect(Array(JsonMethod.NONE))
class User (#Indexed #JsonProperty var id: UserId)
I also tried to put the #JsonProperty on the UserId value object itself like this:
JsonAutoDetect(Array(JsonMethod.NONE))
final case class UserId(#JsonProperty value: String) {
override def toString = value
}
but I still get exactly the same error.
Did someone using Scala already had this issue?
I think your problem is that case classes don't generate the JavaBean boilerplate (or member fields annotated appropriately) Jackson expects. For example, I believe Scala generates this method in UserId:
public java.lang.String value();
Jackson doesn't know what to do with that. It isn't a recognizable field or a JavaBean-style method (i.e. getValue() or setValue()).
I haven't yet used it, but you might want to try jackson-module-scala as a more Scala-aware wrapper around Jackson. Another option is spray-json.
The reason for the error is that the version of Jackson that you appear to be using (1.x) is not matching up the "value" property to the constructor argument. When applied to constructors, #JsonProperty usually requires a name parameter to match up parameters to properties; with your current setup, I believe the following would work:
case class UserId #JsonCreator() (#JsonProperty("value") value: String)
The Jackson Scala Module also provides more support for Scala-isms, and might possibly handle the UserId class without any Jackson-specific annotations. That said, your version of Jackson is quite old (the current latest version is 2.3.1), and upgrading might not be trivial for your configuration.
I'm currently modifying a class that has 9 different constructors. Now overall I believe this class is very poorly designed... so I'm wondering if it is poor design for a class to have so many constructors.
A problem has arisen because I recently added two constructors to this class in an attempt to refactor and redesign a class (SomeManager in the code below) so that it is unit testable and doesn't rely on every one of its methods being static. However, because the other constructors were conveniently hidden out of view about a hundred lines below the start of the class I didn't spot them when I added my constructors.
What is happening now is that code that calls these other constructors depends on the SomeManager class to already be instantiated because it used to be static....the result is a null reference exception.
So my question is how do I fix this issue? By trying to reduce the number of constructors? By making all the existing constructors take an ISomeManager parameter?
Surely a class doesn't need 9 constructors! ...oh and to top it off there are 6000 lines of code in this file!
Here's a censored representation of the constructors I'm talking about above:
public MyManager()
: this(new SomeManager()){} //this one I added
public MyManager(ISomeManager someManager) //this one I added
{
this.someManager = someManager;
}
public MyManager(int id)
: this(GetSomeClass(id)) {}
public MyManager(SomeClass someClass)
: this(someClass, DateTime.Now){}
public MyManager(SomeClass someClass, DateTime someDate)
{
if (someClass != null)
myHelper = new MyHelper(someOtherClass, someDate, "some param");
}
public MyManager(SomeOtherClass someOtherClass)
: this(someOtherClass, DateTime.Now){}
public MyManager(SomeOtherClass someOtherClass, DateTime someDate)
{
myHelper = new MyHelper(someOtherClass, someDate, "some param");
}
public MyManager(YetAnotherClass yetAnotherClass)
: this(yetAnotherClass, DateTime.Now){}
public MyManager(YetAnotherClass yetAnotherClass, DateTime someDate)
{
myHelper = new MyHelper(yetAnotherClass, someDate, "some param");
}
Update:
Thanks everyone for your responses...they have been excellent!
Just thought I'd give an update on what I've ended up doing.
In order to address the null reference exception issue I've modified the additional constructors to take an ISomeManager.
At the moment my hands are tied when it comes to being allowed to refactor this particular class so I'll be flagging it as one on my todo list of classes to redesign when I have some spare time. At the moment I'm just glad I've been able to refactor the SomeManager class...it was just as huge and horrible as this MyManager class.
When I get around to redesigning MyManager I'll be looking for a way to extract the functionality into two or three different classes...or however many it takes to ensure SRP is followed.
Ultimately, I haven't come to the conclusion that there is a maximum number of constructors for any given class but I believe that in this particular instance I can create two or three classes each with two or three constructors each..
A class should do one thing and one thing only. If it has so many constructors it seems to be a tell tale sign that it's doing too many things.
Using multiple constructors to force the correct creation of instances of the object in a variety of circumstances but 9 seems like a lot. I would suspect there is an interface in there and a couple of implementations of the interface that could be dragged out. Each of those would likely have from one to a few constructors each relevant to their specialism.
As little as possible,
As many as necessary.
9 constructors and 6000 lines in class is a sign of code smell. You should re-factor that class.
If the class is having lot of responsibilities and then you should separate them out. If the responsibilities are similar but little deviation then you should look to implement inheritance buy creating a interface and different implementations.
If you arbitrarily limit the number of constructors in a class, you could end up with a constructor that has a massive number of arguments. I would take a class with 100 constructors over a constructor with 100 arguments everyday. When you have a lot of constructors, you can choose to ignore most of them, but you can't ignore method arguments.
Think of the set of constructors in a class as a mathematical function mapping M sets (where each set is a single constructor's argument list) to N instances of the given class. Now say, class Bar can take a Foo in one of its constructors, and class Foo takes a Baz as a constructor argument as we show here:
Foo --> Bar
Baz --> Foo
We have the option of adding another constructor to Bar such that:
Foo --> Bar
Baz --> Bar
Baz --> Foo
This can be convenient for users of the Bar class, but since we already have a path from Baz to Bar (through Foo), we don't need that additional constructor. Hence, this is where the judgement call resides.
But if we suddenly add a new class called Qux and we find ourselves in need to create an instance of Bar from it: we have to add a constructor somewhere. So it could either be:
Foo --> Bar
Baz --> Bar
Qux --> Bar
Baz --> Foo
OR:
Foo --> Bar
Baz --> Bar
Baz --> Foo
Qux --> Foo
The later would have a more even distribution of constructors between the classes but whether it is a better solution depends largely on the way in which they are going to be used.
The answer: 1 (with regards to injectables).
Here's a brilliant article on the topic: Dependency Injection anti-pattern: multiple constructors
Summarized, your class's constructor should be for injecting dependencies and your class should be open about its dependencies. A dependency is something your class needs. Not something it wants, or something it would like, but can do without. It's something it needs.
So having optional constructor parameters, or overloaded constructors, makes no sense to me. Your sole public constructor should define your class's set of dependencies. It's the contract your class is offering, that says "If you give me an IDigitalCamera, an ISomethingWorthPhotographing and an IBananaForScale, I'll give you the best damn IPhotographWithScale you can imagine. But if you skimp on any of those things, you're on your own".
Here's an article, by Mark Seemann, that goes into some of the finer reasons for having a canonical constructor: State Your Dependency Intent
It's not just this class you have to worry about re-factoring. It's all the other classes as well. And this is probably just one thread in the tangled skein that is your code base.
You have my sympathy... I'm in the same boat.
Boss wants everything unit tested, doesn't want to rewrite code so we can unit test. End up doing some ugly hacks to make it work.
You're going to have to re-write everything that is using the static class to no longer use it, and probably pass it around a lot more... or you can wrap it in a static proxy that accessses a singleton. That way you an at least mock the singleton out, and test that way.
Your problem isn't the number of constructors. Having 9 constructors is more than usual, but I don't think it is necessarily wrong. It's certainly not the source of your problem. The real problem is that the initial design was all static methods. This is really a special case of the classes being too tightly coupled. The now-failing classes are bound to the idea that the functions are static. There isn't much you can do about that from the class in question. If you want to make this class non-static, you'll have to undo all that coupling that was written into the code by others. Modify the class to be non-static and then update all of the callers to instantiate a class first (or get one from a singleton). One way to find all of the callers is to make the functions private and let the compiler tell you.
At 6000 lines, the class is not very cohesive. It's probably trying to do too much. In a perfect world you would refactor the class (and those calling it) into several smaller classes.
Enough to do its task, but remember the Single Responsibility Principle, which states that a class should only have a single responsibility. With that in mind there are probably very few cases where it makes sense to have 9 constructors.
I limit my class to only have one real constructor. I define the real constructor as the one that has a body. I then have other constructors that just delegate to the real one depending on their parameters. Basically, I'm chaining my constructors.
Looking at your class, there are four constructors that has a body:
public MyManager(ISomeManager someManager) //this one I added
{
this.someManager = someManager;
}
public MyManager(SomeClass someClass, DateTime someDate)
{
if (someClass != null)
myHelper = new MyHelper(someOtherClass, someDate, "some param");
}
public MyManager(SomeOtherClass someOtherClass, DateTime someDate)
{
myHelper = new MyHelper(someOtherClass, someDate, "some param");
}
public MyManager(YetAnotherClass yetAnotherClass, DateTime someDate)
{
myHelper = new MyHelper(yetAnotherClass, someDate, "some param");
}
The first one is the one that you've added. The second one is similar to the last two but there is a conditional. The last two constructors are very similar, except for the type of parameter.
I would try to find a way to create just one real constructor, making either the 3rd constructor delegate to the 4th or the other way around. I'm not really sure if the first constructor can even fit in as it is doing something quite different than the old constructors.
If you are interested in this approach, try to find a copy of the Refactoring to Patterns book and then go to the Chain Constructors page.
Surely a class should have as many constructors as are required by the class... this doesnt mean than bad design can take over.
Class design should be that a constructor creates a valid object after is has finished. If you can do that with 1 param or 10 params then so be it!
It seems to me that this class is used to do way, way to much. I think you really should refactor the class and split it into several more specialized classes. Then you can get rid of all these constructors and have a cleaner, more flexible, more maintainable and more readable code.
This was not at direct answer to your question, but i do believe that if it is necessary for a class to have more than 3-4 constructors its a sign that it probably should be refactored into several classes.
Regards.
The only "legit" case I can see from you code is if half of them are using an obsolete type that you are working to remove from the code. When I work like this I frequently have double sets of constructors, where half of them are marked #Deprecated or #Obsolete. But your code seems to be way beyond that stage....
I generally have one, which may have some default parameters. The constructor will only do the minimum setup of the object so it's valid by the time it's been created. If I need more, I'll create static factory methods. Kind of like this:
class Example {
public:
static FromName(String newname) {
Example* result = new Example();
result.name_ = newname;
return result;
}
static NewStarter() { return new Example(); }
private:
Example();
}
Okay that's not actually a very good example, I'll see if I can think of a better one and edit it in.
The awnser is: NONE
Look at the Language Dylan. Its has a other System.
Instat of a constructors you add more values to your slots (members) then in other language. You can add a "init-keyword". Then if you make a instance you can set the slot to the value you want.
Ofcourse you can set 'required-init-keyword:' and there are more options you can use.
It works and it is easy. I dont miss the old system. Writing constructors (and destructors).
(btw. its still a very fast language)
I think that a class that has more than one constructor has more than one responsibility. Would be nice to be convinced about the opposite however.
A constructor should have only those arguments which are mandatory for creating the instance of that class. All other instance variables should have corresponding getter and setter methods. This will make your code flexible if you plan to add new instance variables in the future.
In fact following OO principle of -
For each class design aim for low coupling and high cohesion
Classes should be open for extension but closed for modification.
you should have a design like -
import static org.apache.commons.lang3.Validate.*;
public class Employee
{
private String name;
private Employee() {}
public String getName()
{
return name;
}
public static class EmployeeBuilder
{
private final Employee employee;
public EmployeeBuilder()
{
employee = new Employee();
}
public EmployeeBuilder setName(String name)
{
employee.name = name;
return this;
}
public Employee build()
{
validateFields();
return employee;
}
private void validateFields()
{
notNull(employee.name, "Employee Name cannot be Empty");
}
}
}