Why do static Create methods exist? - language-agnostic

I was wondering, why do static Create methods exist?
For instance, why use this code:
System.Xml.XmlReader reader = System.Xml.XmlReader.Create(inputUri);
over this code:
System.Xml.XmlReader reader = new System.Xml.XmlReader(inputUri);
I cannot find the rationale for using one over the other, and can't find any relation between classes who use this construct over the other.
Can anyone shed some light on this?

XmlReader is an abstract class. You cannot instantiate it.
Providing a Create method is an instance of the factory pattern. Depending on the specified arguments a different implementation of XmlReader is chosen and returned. For example, there are validating and non-validating XmlReader implementations in the .NET framework.

A more general answer...
The reason people like these kinds of methods, known as "static factory methods", is because you can give them a name (as opposed to constructors). So if you need three different constructors, you can instead create static factory methods which have names relevant to their use.
Another reason is that a factory method doesn't really need to create new objects - it can return the same one over and over if need be.

Because it can actually create and object of derived type that you have no access to or return an abstract class (as dtb answered). This is factory method pattern.

A constructor can only be used to create instances of one specific class, while a static Create method can create an instance of different classes depending on the input.
In the case of the XmlReader class the Create method will return an XmlDictionaryReader, XmlTextReader, XmlValidatingReader or XmlNodeReader, depending on which overload you use and what parameters you send to it.

This pattern allows the XmlReader class to provide you with instances of derived classes tailored to the parameters you passed to Create. Note in particular the overloads that accept an XmlReaderSettings object. A different XmlReader subclass can be returned to you depending on your settings.
A better example is WebRequest.Create(url). Depending on the URL you pass, you may receive an HttpWebRequest, an FtpWebRequest, etc.

Because you don't have to commit to the exact class of object you get. Constructors can only construct objects from exactly one class.
Because you can give the method a meaningful name, e.g. BigInt.probablePrime(). Constructors can only have the same name as the class.
Because you can have more than one factory method for the same parameter type combination, e.g. Point.fromPolarCoords(int, int) and Point.fromCartesianCoords(int, int), but there can be only one constructor Point(int, int).
(A much more detailed answer is given in Bloch's 'Effective Java'.)

Sometimes they exist as a form of self-documentation. I have a db access component that I can instantiate either with a connection string or the name of the connection in the config file. Both of these methods take strings as a parameter so they cannot be differentiated by arguments alone. So I created a FromConnectionString(string) factory method and a FromConnectionName(string) factory method. This nuance would entirely be lost by a new Foo(bool, string) line.

The idea is that this way they can change the implementation of XmlReader and not break any user code (e.g. they can change the actual type that is returned from the Create method).
I personally don't like this approach, because it creates an inverse relationship in the XmlReader class hierarchy. Maybe they thought that the Factory pattern is an overkill?

To encapsulate object creation.

Related

Local parameters in Kotlin's primary constructor of a data class

Regarding data classes it is forbidden to not use var or val keywords in the primary constructor, i.e. every parameter is implicitly turned into a class property. However, sometimes there are cases which I don't want each parameter to be turned into a class property.
So, as far as I can see, there is no chance of passing a parameter in a primary constructor that is accessible only within the constructor and is forgotten after the construction of the instance has finished. Is there a good reason for this?
The only way I see to get around this, is not to use data classes or to use a secondary constructor that allows for non-var/val-prefixed variables. However, having a lot of parameters that need to be passed, a secondary constructor would immensely inflate the class. Of course, I could wrap all the parameters into another object, but that would just kind of shift the problem to another place.
Is there a recommended approach or pattern in order to cope with that?
You are not limited at all, you just have to do things a bit differently.
Data classes are intended to be very clear about what they contain and in what order, and only allow members in the primary constructor parameter list.
But you have other options: use a secondary constructor, and/or create top-level functions with the same name as the class with different overloads, or create factory methods in the companion object:
data class Person(val name: String, val age: Int) {
// secondary constructor
constructor (name: String): this(name, 0) {
// ... make a newborn
}
// factory methods in companion object
companion object {
fun of(name: String, birthdate: LocalDate): Person {
return Person(name, yearsSince(birthdate))
}
}
}
// function with same name as class acting like a constructor
fun Person(name: String, birthdate: LocalDate): Person {
return Person(name, yearsSince(birthdate))
}
// these all work now:
Person("Fred", 30) // primary constructor
Person("Baby") // secondary constructor
Person("Geoff", LocalDate.parse("12/08/1990")) // top-level function
Person.of("Jennifer", LocalDate.parse("01/01/1981") // companion function
You can also hide the primary constructor by making it private, but you cannot hide the copy version of that constructor.
By the way, having data classes with this contract for the primary constructor really help serialization/deserialization libraries know what to do with the class that would be guesswork otherwise. It is a good thing!
Fist thing that I must say is that this is my personal opinion so take it with grain of salt.
From official kotlin documentation
We frequently create classes whose main purpose is to hold data. In such a class some standard functionality and utility functions are often mechanically derivable from the data.
So data classes are supposed to be used as data holders, and they shouldn't contain much logic.
From my perspective when you want to pass something to constructor but class doesn't store that data then there is probably some logic connected with that.
Common situation when you want to do this is:
Using some flag to change behavior of constructor
Passing some class that wraps all data needed and then extract it to each individual field.
In first case then we clearly see that this isn't part of data class use case.
And second case is simply bad code, it introduces unneeded dependency on another class and hides what that class actually needs.
Constructors should be simple, they take data that class requires and bind it to fields, not much logic should reside there, it should be up to those that use constructor to prepare all data, and if there is some repeatable code when creating new instances then it might be good idea to use factory method to encapsulate that.

Using RIO and Sqlite-net in MvvmCross

In the excellent mvvmcross-library I can use RIO binding to prevent unreadable code:
public INC<String>Title = new NC<String>();
Then I can read and write values using Title.Value. Makes the models much more readable.
Normally, this property would be written as:
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
RaisePropertyChanged("Title");
}
}
But when I want to use sqlite-net, these fields cannot be streamed to the database because they are not basic types with a getter and setter.
I can think of a few options how to get around that:
Make a new simple object that is similar to the model, but only with
the direct db-fields. And create a simple import-export static
method on the model. This also could prevent struggling with complex
model-code that never needs to relate to the actual database.
Make sqlite-net understand reading NC-fields. I read into the code of the mapper, but it looks like this is going to be a lot of work because it relies on the getter-setter. I did not find a way to insert custom mapping to a type, that could be generic.
Remove RIO and just put in all the code myself instead of relying on RIO.
Maybe someone has some advice?
Thanks Stuart. It was exactly my thought, so I did implement it that way: my (DB) Models do not contain RIO. Only my viewmodels do, and they reference a Model that is DB-compatible.
So, for posterity the following tips:
- Do not use RIO in your models that need to be database-backed.
- Reference models in your viewmodels. In the binding you can use the . (dot) to reference this model.
This keeps them nicely separated. This gives you also another advantage: if you need to reuse a model (because the same object might be displayed twice on the screen), but under different circumstances, it is much easier to handle this situaties to find this already instantiated model.

static methods that return an instance of an object but behave like a constructor

So I have an object that can be constructed in a few ways. The constructors have signatures like, the one that loads an object from a file:
Object::Object( string filenameToLoadFrom ) ;
And how it behaves is pretty straightforward.
Object( "filename.dat" ) ; // loads object from filename
The constructor signature pretty much says what it does, although a static method Load might arguably be better:
static Object* Object::Load( string filenameToLoadFrom ) ;
(syntax above is slightly incorrect but you get the idea.)
Then we come into cases where what the constructor does isn't immediately obvious from the parameters. a name is needed to make it clear from the API what the constructor does.
The question is, is it a good idea to write static methods that return an instance of the object, just for the sake of being able to name the constructor?
This is actually considered a common secondary benefit of the Factory Method Pattern. It is potentially useful in specific scenarios, especially for things where you have the same argument type providing very different meanings.
For example, it's not uncommon to have a class representing an "Angle" which can be constructed by a single floating point number which could represent degrees or radians. Constructors do not provide enough context (or a clean way) to implement this, where a "factory method" makes this very clear.
I believe it's a good idea especially if you need more than one constructor that both take the same type of parameter(s). For example: static Object* loadFromFile( String fileName) and statc Object* loadFromResorce(String resourceName). You can even make the actual constructor private to enforce the use of the static constructors.

What are better ways to create a method that takes many arguments? (10+?)

I was looking at some code of a fellow developer, and almost cried. In the method definition there are 12 arguments. From my experience..this isn't good. If it were me, I would have sent in an object of some sort.
Is there another / more preferred way to do this (in other words, what's the best way to fix this and explain why)?
public long Save (
String today,
String name,
String desc,
int ID,
String otherNm,
DateTime dt,
int status,
String periodID,
String otherDt,
String submittedDt
)
ignore my poor variable names - they are examples
It highly depends on the language.
In a language without compile-time typechecking (e.g. python, javascript, etc.) you should use keyword arguments (common in python: you can access them like a dictionary passed in as an argument) or objects/dictionaries you manually pass in as arguments (common in javascript).
However the "argument hell" you described is sometimes "the right way to do things" for certain languages with compile-time typechecking, because using objects will obfuscate the semantics from the typechecker. The solution then would be to use a better language with compile-time typechecking which allows pattern-matching of objects as arguments.
Yes, use objects. Also, the function is probably doing too much if it needs all of this information, so use smaller functions.
Use objects.
class User { ... }
User user = ...
Save(user);
It decision provides easy way for adding new parameters.
It depends on how complex the function is. If it does something non-trivial with each of those arguments, it should probably be split. If it just passes them through, they should probably be collected in an object. But if it just creates a row in a table, it's not really big deal. It's less of a deal if your language supports keyword arguments.
I imagine the issue you're experiencing is being able to look at the method call and know what argument is receiving what value. This is a pernicious problem in a language like Java, which lacks something like keyword arguments or JSON hashes to pass named arguments.
In this situation, the Builder pattern is a useful solution. It's more objects, three total, but leads to more comprehensible code for the problem you're describing. So the three objects in this case would be as such:
Thing: stateful entity, typically immutable (i.e. getters only)
ThingBuilder: factory class, creates a Thing entity and sets its values.
ThingDAO: not necessary for using the Builder pattern, but addresses your question.
Interaction
/*
ThingBuilder is a static inner class of Thing, where each of its
"set" method calls returns the ThingBuilder instance being worked with
while the final "build()" call returns the instantiated Thing instance.
*/
Thing thing = Thing.createBuilder().
.setToday("2012/04/01")
.setName("Example")
// ...etc...
.build();
// the Thing instance as get methods for each property
thing.getName();
// get your reference to thingDAO however it's done
thingDAO.save(thing);
The result is you get named arguments and an immutable instance.

Why do constructors not return values?

Please tell me why the constructor does not return any value. I want a perfect technical reason to explain to my students why the constructor does not have any return type.
What actually happens with the constructor is that the runtime uses type data generated by the compiler to determine how much space is needed to store an object instance in memory, be it on the stack or on the heap.
This space includes all members variables and the vtbl. After this space is allocated, the constructor is called as an internal part of the instantiation and initialization process to initialize the contents of the fields.
Then, when the constructor exits, the runtime returns the newly-created instance. So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime.
Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.
Well, in a way it returns the instance that has just been constructed.
You even call it like this, for example is Java
Object o = new Something();
which looks just like calling a "regular" method with a return value
Object o = someMethod();
How is a constructor supposed to return a return value? The new operator returns the newly created instance. You do not call a ctor, newdoes it.
MyClass instance = new MyClass();
If the ctor would return a value, like so:
public int MyClass()
{
return 42;
}
Where would you receive the integer?
(I'm biased towards C++, so regarding other languages, take this with a grain of salt.)
Short answer: You don't want to have to explicitly check for success for every single object construction in your code.
Somewhat longer answer: In C++, constructors are called for dynamically as well as for globally and automatically allocated objects. In this code
void f()
{
std::string s;
}
there is no way for the constructor of s (std::string::string()) to return any value. Either it succeeds - then we can use the object, or it throws an exception - the we never get a chance to try to use it.
IMO, that's the way it should be.
A constructor is some method automatically called when you initialize a new instance of an object.
This method is there if you need to initialize your object to a given state and run few default methods.
Actually you can imagine the constructor always return the instance of the object created that would be a good image.
When you call a constructor the return value is the new object:
Point pt = new Point(1,2);
But within the constructor itself, you're not actually creating and returning the object; it's been created before your code starts, you're just setting up the initial values.
Point::Point(int x, int y) {
this->x = x;
this->y = y;
}
The lack of a return type reflects the fact that constructors are used differently than other functions. A return type of null, while technically accurate, doesn't reflect well the fact that the code is used as if it returns an object. However, any other return type would indicate that your code is supposed to return something at the end, which is also incorrect.
Constructor doesn’t return anything not even Void. Though some of the answers have mentioned that Constructor do return reference to the newly created object , which is not true. It’s the new operator that returns the object.
So Why constructor doesn’t return any value
Because its not supposed to return anything. The whole purpose of constructor is to initialize the current state of the object by setting the initial values.
So Why doesn’t it even return Void
This is actually a Design constraint which has been placed to distinguish it from methods. public void className() is perfectly legal in java but it denotes a method and not a constructor. To make the compiler understand that it’s a constructor , it requires a way to distinguish it.
all answers are biased towards C++/Java. there is no reason a constructor does not return a value other than the language design.
look at a constructor in a broader sense: it is a function which constructs a new object. you can write perfectly valid constructors in C:
typedef struct object object;
int object_create( object **this );
this is perfect OOP in C and the constructor returns value (this can also be called a factory, but the name depends on the intention).
however, in order to create an object automatically (to satisfy some type cast, or conversion for example), there have to be some rules defined. in C++, there is an argument-less constructor, which is inferred by the compiler if it is not defined.
the discussion is broader than what we think. Object Oriented Programming is a name which describes a way of thinking about programming. you can have OO in almost any language: all you need is structures and functions. mainstream languages like C++ and Java are so common that we think they define "the way". now look at the OO model in Ada: it is far from the model of C++ but is still OO. i am sure languages like Lisp have some other ways of doing OO.
One point that hasn't yet been discussed is that the constructor of class "foo" must be usable not only when creating instances of foo, but also when creating instances of classes derived from foo. In the absence of generics (which weren't available when Java, C++, or .net were designed) there would be no way for foo's constructor to return an object of any derived class. Therefore, what needs to happen is for the derived-class object to be created via some other means and then made available to foo's constructor (which will then be able to use the object in question as a foo when doing its initialization).
Even though the VM implementation of a constructor isn't to return any value, in practice it kind of does - the new object's reference. It would then be syntactically weird and / or confusing to be able to store one or both of the new object's reference and an additional return value in one statement.
So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime. Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.
Constructor is not directly called by the user's code. It's called by the memory allocation and object initialization code in the run time. Its value is not visible to the user.
In case of C#, the syntax for declaring object is :
classname objectname= new constructor();
According to this line, if we are using assignment operator(=) then it should return some value. But the main objective of a constructor is to assign values to variables, so when we use a new keyword it creates instance of that class, and constructor assigns values to the variable for that particular instance of object, so constructor returns assigned values for that objects's instance.
We can not call constructors independently. Instead they are automatically called whenever objects are created.
Ex:
MyDate md = new Mydate(22,12,2012);
In above example new will return a memory location which will be held by md, and programatically we can not return multiple values in single statements.
So constructors can not return anything.
From what I know about OO design methodologies, I would say the following:
1)By allowing a constructor to return a value, framework developer would allow the program to crash in an instant where the returned value is not handled. To keep the integrity of the program workflow, not allowing a return value from the initialization of an object is a valid decision. Instead, language designer would suggest/force the coders to use getter/setter - access methods.
2)Allowing the object to return a value on initialization also opens possible information leaks. Specially when there are multiple layer or access modifications applied to the variables/methods.
As you aware that when object is created constructor will be automatically called So now imagine that constructor is returning an int value. So code should like this...
Class ABC
{
int i;
public:
int ABC()
{
i=0;
return i;
}
.......
};
int main()
{
int k= ABC abc; //constructor is called so we have to store the value return by it
....
}
But as you aware that stament like int k= ABC abc; is not possible in any programming language. Hope you can understand.
i found it helpful
This confusion arises from the assumption that constructors are just like any other functions/methods defined by the class. NO, they are not.
Constructors are just part of the process of object creation. They are not called like other member functions.
I would be using Java as my language in the answer.
class SayHelloOnCreation {
public SayHelloOnCreation() {
System.out.println("Hello, Thanks For Creating me!");
}
}
class Test {
public static void main(String[]args) {
SayHelloOnCreation thing = new SayHelloOnCreation(); //This line here, produces an output - Hello, Thanks For Creating me!
}
}
Now let us see what is happening here. in java, we use the new keyword to create an instance of a class. And as you can see in the code, in the line, SayHelloOnCreation thing = new SayHelloOnCreation();, the expression after the assignment operator runs before assignment is done. So using the keyword new, we call the constructor of that class (SayHelloOnCreation()) and this constructor creates an object on the Java Heap. After the object is created, a reference to that object is assigned to the thing reference of type SayHelloOnCreation.
The point that I am trying to keep here is that if constructors were allowed to have a return type, Firstly the strongly typed nature of the language would be compromised (Remember I am speaking about Java here).
Secondly, an object of class SayHelloOnCreation is created here so by default I guess the constructor returns a reference of the same type, to avoid ClassCastException.
A method returns the value to its caller method, when called explicitly. Since, a constructor is not called explicitly, who will it return the value to. The sole purpose of a constructor is to initialize the member variables of a class.