In my business logic I have to deal with a lot of entity IDs, all of them of type String, which can cause confusion especially when you pass a couple of them as method parameters. So I thought about introducing a little type safety with inline classes. I know, inline classes are still marked as experimental in v1.3. Nevertheless, has anyone ever tried to use an inline class as the #Id property within a DB mapping context, in my case a MongoDB with Spring Data.
#Entity
class User {
#Id
var id: UserId
}
with
inline class UserId(val id: String)
I guess there is no unboxing of the underlying property, so _id will end up as an object in the DB? And what about Spring's CrudRepository interfaces? It seems compilable but will it work eventually:
interface UserRepository : CrudRepository<User, UserId>
Probably using AttributeConverter to convert the inline class to a primitive might do the job. Any experiences with this?
Inline classes result in completely new types, not just a typed Alias. Even if our code base knows what this new type is the MongoDB doesn't right? So you cannot store the inline class directly into the corresponding primitive type Fields
There is an unresolved ticket for Spring Data Commons: https://github.com/spring-projects/spring-data-commons/issues/1947
Related
I have a class:
open data class Person(var name: String)
and another class:
data class Student(var reg: String) : Person("")
this gives me an error that:
error: modifier 'open' is incompatible with 'data'
if I remove data from Person class it's fine.
why kotlin open and data incompatible?
From https://kotlinlang.org/docs/reference/data-classes.html:
To ensure consistency and meaningful behavior of the generated code, data classes have to fulfil the following requirements:
The primary constructor needs to have at least one parameter;
All primary constructor parameters need to be marked as val or var;
Data classes cannot be abstract, open, sealed or inner;
(before 1.1) Data classes may only implement interfaces.
So the main point is that data class has some generated code (equals, hashCode, copy, toString, componentN functions). And such code must not be broken by the programmer. As a result, data class has some restrictions.
As the documentation states,
Data classes cannot be abstract, open, sealed or inner;
The reason why they cannot be inherited is that inheriting from a data class causes an ambiguity with how their generated methods (equals, hashcode, etc.) should work. See further discussion about this in an answer to another question.
Since Kotlin 1.1, the restrictions on data classes have been lifted slightly: They can now inherit from other classes, as described in detail in the related proposal. However, they still cannot be inherited from themselves.
Note that data classes “only” provide the extra convenience of the automatic equals, hashcode, toString, component, and copy functions. If you don’t need those, then a class like the following still has properties with getters/setters and a constructor in a very brief form, and has no limitations on how you can use it with inheritance:
class User(val name: String, var age: Int)
In C# there's a quite huge difference between interfaces and classes. Indeed, a class represents a reference-type, so that we can actually create objects modeled on that class, while interfaces are meant to be contracts that a class sign to in order to ensure the existence of a certain behavior. In particular we can't create instances of interfaces.
The whole point with interfaces is to expose behavior. A class implements it by giving one explicit implementation of said behavior.
In that case, although interfaces may contain properties, most of the time we care about interfaces because of behavioral issues. So most of the type, interfaces are just contracts of behavior.
On TypeScript, on the other hand, I've seem something that made me quite uneasy, and in truth I've seen this more than once, which is the reason for this question.
In one tutorial I saw this:
export interface User {
name: string; // required with minimum 5 chracters
address?: {
street?: string; // required
postcode?: string;
}
}
But wait a minute. Why User is an interface? If we think like C#, User shouldn't be an interface. In truth, looking at it, it seems like we are defining the data type User, instead of a contract of behavior.
Thinking like we do in C#, the natural thing would be this:
export class User {
public name: string;
public address: Address;
}
export class Address {
public street: string;
public postcode: string;
}
But this thing of using interfaces like we do with classes, to just define a data type, rather than defining a contract of behavior, seems very common in TypeScript.
So what interfaces are meant for in TypeScript? Why do people use interfaces in TypeScript like we use clases in C#? How interfaces should be properly used in TypeScript: to establish contracts of behavior, or to define properties and object should have?
Consider that in Javascript, data is often exchanged as plain objects, often through JSON:
let data = JSON.parse(someString);
Let's say this data is an array of User objects, and we'll pass it to a function:
data.forEach(user => foo(user))
foo would be typed like this:
function foo(user: User) { ... }
But wait, at no point did we do new User! Should we? Should we have to write a class User and map all the data to it, even though the result would be exactly the same, an Object with properties? No, that would be madness just for the sake of satisfying the type system, but not change anything about the runtime. A simple interface which describes how the specific object is expected to look like (to "behave") is perfectly sufficient here.
I also came to Typescript from a C# background and have wondered the same things. I was thinking along the lines of POCOs (is POTO a thing?)
So what interfaces are meant for in TypeScript?
The Typescript Handbook seems to say that interfaces are meant for "defining contracts within your code".
Why do people use interfaces in TypeScript like we use classes in C#?
I agree with #deceze's answer here.
John Papa expands on the subject of classes and interfaces on his blog. He suggests that classes are best suited for "creating multiple new instances, using inheritance, [and] singleton objects". So, based on the intent of Typescript interfaces as described in the Typescript Handbook and one man's opinion, it would appear that classes are not necessary to establish contracts in Typescript. Instead, you should use interfaces. (Your C# senses will still be offended.)
Interfaces should be properly used in TypeScript: to establish contracts of behavior, or to define properties and object should have?
If I understand the question, you are asking if interfaces should establish contracts of behavior or contracts of structure. To this, I would answer: both. Typescript interfaces can still be used the same way interfaces are used in C# or Java (i.e. to describe the behavior of a class), but they also offer the ability to describe the structure of data.
Furthermore, my coworker got on me for using classes instead of interfaces because interfaces produce no code in the compiler.
Example:
This Typescript:
class Car implements ICar {
foo: string;
bar(): void {
}
}
interface ICar {
foo: string;
bar(): void;
}
produces this Javascript:
var Car = (function () {
function Car() {
}
Car.prototype.bar = function () {
};
return Car;
}());
Try it out
Interfaces in typescript are similar to interfaces in C# in that they both provide a contract. However opposed to C# interfaces which only contain methods typescript interfaces can also describe fields or properties that objects contain. Therefore they can also be used for things which are not directly possible with C# interfaces.
A major difference between interfaces and classes in typescript is that interfaces don't have a runtime representation and there won't be any code emitted for them. Interfaces are very broadly usable. For example you can use object literals to construct objects with satisfy an interface. Like:
let user: User = {
name: 'abc',
address: {
street: 'xyz',
},
};
Or you can assign any data objects (e.g. received through JSON parsing) to an interface (but your pre-checks should assert that it's really valid data). Therefore interfaces are very flexible for data.
On the other hand classes have a type associated at runtime to them and there is code generated. You can check the type at runtime with instanceof and there's a prototype chain set up. If you define User as a class it won't be a valid user unless you call the constructor function. And you can't just define any kind of suitable data to be a User. You would need to create a new instance and copy the properties over.
My personal rule of thumb:
If I'm dealing with pure data (of varying sources) I use interfaces
If I'm modelling something which has an identity and state (and probably attached methods to modify the state) I'm using a class.
How interfaces should be properly used in TypeScript: to establish contracts of behavior, or to define properties and object should have?
Interfaces in TypeScript are shape contracts, describing the expected structure of an object. If a value has a certain interface annotation, you expect it to be an object featuring the members defined in the interface. Members can be values or functions (methods). Generally, their behavior (function bodies) is not part of the contract. But you can specify if they are readonly or not.
So what interfaces are meant for in TypeScript? Why do people use interfaces in TypeScript like we use clases in C#?
Typescript interfaces can play the same role as C# interfaces if they are expected to be implemented by TypeScript classes.
But not only a class can implement an interface; any kind of value can:
interface HelloPrinter {
printHello(): void
}
The following object is not a class but nevertheless implements the interface:
{
printHello: () => console.log("hello")
}
Thus we can do
const o: HelloPrinter = {
printHello: () => console.log("hello")
}
and the TypeScript compiler won't complain.
The object implements our interface without forcing us to write a class.
Working with interfaces is more lightweight than working with (interfaces and) classes.
But if you need to know the type name (class/interface name) during runtime then classes are the right choice, because interface names are only known at compile time.
Using only the native deserialization mechanism, you cannot deserialize an instance of a specific class. You can only deserialize into a plain-old-javascript-object. Such objects can adhere to typescript interfaces but cannot be an instance of a class. If you need to deal with data that crosses a serialization boundary such as data expected from a webservice, use interfaces. If you need to generate new instances of such values yourself, just construct them literally or create a convenience function that returns them - objects that adhere to that interface.
A class can itself implement an interface, but it might get confusing if you expect to deal with both locally constructed class instances AND deserialized, reconstituted plain objects. You'd never be able to rely on the class-basis of the object and so there'd be no benefit of also defining it as a class for that exact purpose.
I've had success in creating a ServerProxy module responsible for sending code back and forth from a webservice - the webservice call and the returned result. If you're binding to knockout models or similar, you can have a class that encapsulates the ui-bound model with a constructor that knows how to lift a returned plain-old-javascript-object that adheres to the webservice's interface-only contract into an instance of your model class.
I missed a few CS classes, namely the ones going over topics such as polymorphism, inheritence, and abstract classes. I'm not asking you to do my homework but I have no idea where to even start to get further guidance, so giving me a skeleton or something would help me greatly, I'm so confused.
So the problem is to create an employee abstract class with two subclasses, permanentEmployee and TempEmployee.I must store information such as name,department,and salary in these subclasses and then order them according to how the user wants them ordered. I know I start out like this
public abstract class Employee
{
}
public class TempEmployee extends Employee
{
\\variables such as name, salary, etc, here?
}
public class PermEmployee extends Employee
{
\\here too?
}
but I have no idea how to store variables in there much less access them later for ordering and displaying,. Please guidance.
If all you're looking for is an example of class-level data members in Java, this should help:
public class SomeClass {
private int someInt;
public int getSomeInt() {
return this.someInt;
}
public void setSomeInt(int someInt) {
this.someInt = someInt;
}
}
Regarding polymorphism, be aware that methods are polymorphic, but values are not. As you place values and methods (getters and setters) in your base class and derived classes, I encourage you to experiment with these concepts thoroughly. Try moving the entire value/getter/setter to the base class, try moving just the value but not the getter/setter, try putting the value in both and the getter/setter in both, etc. See how it behaves.
Make sure that any value/method/etc. that you put in your base class is applicable to all derived classes. If there's ever an exception to that rule, then you would need to move that member out of the base class and into only derived classes where it applies. Note that you can have a complex hierarchy of base classes to accommodate this if needed.
When it comes time to access these members for sorting/display/etc., consuming code would use the getters/setters. For example:
SomeClass myInstance = new SomeClass();
myInstance.setSomeInt(2);
System.out.println(myInstance.getSomeInt());
I am not sure which language you working with, but as it has "extends" I am sure you are not working with c# or CSharp, it can be Java. So I would recommend you to go for TutorialsPoint. This particular article has abstraction described here.
Just to make it easy for you, in Interface and abstraction we always create a structure or the base, it has all the common things defined or declared (Obviously interface has only methods and no variables can be declared inside it).
So as said, in above example, EmployeeId, EmployeeName, EmployeeAddress ...etc should be defined in the base class that is Abstract Base class Employee, But in TempEmployee you can have a criteria such as EmpTermPeriod, EmpContractRenewalDate, EmpExternalPayrollCompanyName (Have made names long and self descriptive) and PermEmployee to have fields like EmpJoiningDate, EmpConfirmationDate, EmpGraduityDate...etc.
I hope it helps.
What is the philosophy behind making the instance variables public by default in Scala. Shouldn't making them private by default made developers make less mistakes and encourage composition?
First, you should know that when you write:
class Person( val name: String, val age: Int ) {
...
}
name and age aren't instance variables but accessors methods (getters), which are public by default.
If you write instead:
class Person( name: String, age: Int ) {
...
}
name and age are only instance variables, which are private as you can expect.
The philosophy of Scala is to prefer immutable instance variables, then having public accessors methods is no more a problem.
Private encourages monoliths. As soon as it's easier to put unrelated functionality into a class just because it needs to read some variables that happen to be private, classes start to grow.
It's just a bad default and one of the big reasons for classes with more than 1000 lines in Java.
Scala defaults to immutable, which removes a massive class of errors that people often use private to restrict (but not remove, as the class' own methods can still mutate the variables) in Java.
with immutables which are preferred in many places, public isn't so much of an problem
you can replace a public val with getters and setters without changing the client code, therefore you don't need the extra layer of getters and setters just in case you need it. (Actually you do get that layer but you don't notice it most of the time.)
the java anti pattern of private field + public setters and getters doesn't encapsulate much anyway
(An additional view supplementing the other answers:)
One major driver behind Java's encapsulation of fields was the uniform access policy, i.e. you didn't have to know or care whether something was implemented simply as a field, or calculated by a method on the fly. The big upside of this being that the maintainer of the class in question could switch between the two as required, without needing other classes to be modified.
In Java, this required that everything was accessed via a method, in order to provide the syntactic flexibility to calculate a value if needed.
In Scala, methods and fields can be accessed via equivalent syntax - so if you have a simple property now, there's no loss in encapsulation to expose it directly, since you can choose to expose it as a no-arg method later without your callers needing to know anything about the change.
I've written a Scala trait, named Cache[A,B], to provide a caching API. The Cache has the following methods, asyncGet(), asyncPut(), asyncPutIfAbsent(), asyncRemove().
I'm going to have a few static methods, such as getOrElseUpdate(key: A)(op: => B). I don't want methods like this as abstract defs in the Cache trait because I don't want each Cache implementation to have to provide an implementation for it, when it can be written once using the async*() methods.
In looking at Google Guava and parts of the Java library, they place public static functions in a class that is the plural of the interface name, so "Caches" would be the name I would use.
I like this naming scheme actually, even though I could use a Cache companion object. In looking at much of my code, many of my companion objects contain private val's or def's, so users of my API then need to look through the companion object to see what they can use from there, or anything for that matter.
By having a object named "Caches" is consistent with Java and also makes it clear that there's only public functions in there. I'm leaning towards using "object Caches" instead of "object Cache".
So what do people think?
Scala's traits are not just a different name for Java's interfaces. They may have concrete (implemented) members, both values (val and var) and methods. So if there's a unified / generalized / shared implementation of a method, it can be placed in a trait and need not be replicated or factored into a separate class.
I think the mistake starts with "going to have a few static methods". Why have static methods? If you explain why you need static methods, it will help figure out what the design should be.