What is the best verb/noun/adjective for adding a lot of convenience methods to class? - oop

Suppose I have a class in, say, Python e.g.:
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
And then I start adding a lot of convenience methods e.g.:
class Date:
# ...
def num_days_in_month(self):
pass
def first_day_of_month(self):
pass
def last_day_of_month(self):
pass
# ...
def next_new_moon(self):
pass
What is the verb for the thing I am doing, and what is the noun for the stuff I am adding to the class, and what is an adjective for a class with a lot of it. I can only think of bad/overly verbose ways of describing this:
The stuff I am adding is "syntactic sugar" and I am "sugaring" or "sweetening" the class, and it makes the class "sweet"/"sugared"
The stuff I am adding is "tooling" and I am "tooling" the class, and it makes that class "tooled'
The things I am adding are "methods" and I am "methoding" the class, and it makes the class ???
The things I am adding are "convenience methods" and I am "conveniencing" the class, and it makes the class "convenienced"
What's the best way?
I don't want just a general world like "developing." I also don't just want a noun, I also want a corresponding single concise verb to describe the act of adding these things (so not "adding convenience methods"). I want to be able to use these in sentences like:
"When designing a class, one important decision to make is how much ____________ to add. On the one hand, you can waste a lot of time __________ing your class and end up with big piles of code that will never get called. On the other, a class that is not ________ enough will require more code to be written by its users.

Related

When is a class a data class?

I know what classes are about, but for better understanding I need a use case. Recently I discovered the construct of data classes. I get the idea behind normal classes, but I cannot imagine a real use case for data classes.
When should I use a data class and when I use a "normal" class? For all I know, all classes keep data.
Can you provide a good example that distinguishes data classes from non-data classes?
A data class is used to store data. It's lighter than a normal class, and can be compared to an array with key/value (dictionary, hash, etc.), but represented as an object with fixed attributes. In kotlin, according to the documentation, that adds those attributes to the class:
equals()/hashCode() pair
toString() of the form "User(name=John, age=42)"
componentN() functions corresponding to the properties in their order of declaration.
copy() function
Also it has a different behavior during class inheritence :
If there are explicit implementations of equals(), hashCode(), or toString() in the data class body or final implementations in a
superclass, then these functions are not generated, and the existing
implementations are used.
If a supertype has componentN() functions that are open and return compatible types, the corresponding functions are generated for the
data class and override those of the supertype. If the functions of
the supertype cannot be overridden due to incompatible signatures or
due to their being final, an error is reported.
Providing explicit implementations for the componentN() and copy() functions is not allowed.
So in kotlin, if you want to describe an object (a data) then you may use a dataclass, but if you're creating a complex application and your class needs to have special behavior in the constructor, with inheritence or abstraction, then you should use a normal class.
I do not know Kotlin, but in Python, a dataclass can be seen as a structured dict. When you want to use a dict to store an object which has always the same attributes, then you should not put it in a dict but use a Dataclass.
The advantage with a normal class is that you don't need to declare the __init__ method, as it is "automatic" (inherited).
Example :
This is a normal class
class Apple:
def __init__(size:int, color:str, sweet:bool=True):
self.size = size
self.color = color
self.sweet = sweet
Same class as a dataclass
from dataclasses import dataclass
#dataclass
class Apple:
size: int
color: str
sweet: bool = True
Then the advantage compared to a dict is that you are sure of what attribute it has. Also it can contains methods.
The advantage over to a normal class is that it is simpler to declare and make the code lighter. We can see that the attributes keywords (e.g size) are repeated 3 times in a normal class, but appear only once in a dataclass.
The advantage of normal class also is that you can personalize the __init__ method, (in a dataclass also, but then you lose it's main advantage I think) example:
# You need only 2 variable to initialize your class
class Apple:
def __init__(size:int, color:str):
self.size = size
self.color = color
# But you get much more info from those two.
self.sweet = True if color == 'red' else False
self.weight = self.__compute_weight()
self.price = self.weight * PRICE_PER_GRAM
def __compute_weight(self):
# ...
return (self.size**2)*10 # That's a random example
Abstractly, a data class is a pure, inert information record that doesn’t require any special handling when copied or passed around, and it represents nothing more than what is contained in its fields; it has no identity of its own. A typical example is a point in 3D space:
data class Point3D(
val x: Double,
val y: Double,
val z: Double
)
As long as the values are valid, an instance of a data class is entirely interchangeable with its fields, and it can be put apart or rematerialized at will. Often there is even little use for encapsulation: users of the data class can just access the instance’s fields directly. The Kotlin language provides a number of convenience features when data classes are declared as such in your code, which are described in the documentation. Those are useful when for example building more complex data structures employing data classes: you can for example have a hashmap assign values to particular points in space, and then be able to look up the value using a newly-constructed Point3D.
val map = HashMap<Point3D, String>()
map.set(Point3D(3, 4, 5), "point of interest")
println(map.get(Point3D(3, 4, 5))) // prints "point of interest"
For an example of a class that is not a data class, take FileReader. Underneath, this class probably keeps some kind of file handle in a private field, which you can assume to be an integer (as it actually is on at least some platforms). But you cannot expect to store this integer in a database, have another process read that same integer from the database, reconstruct a FileReader from it and expect it to work. Passing file handles between processes requires more ceremony than that, if it is even possible on a given platform. That property makes FileReader not a data class. Many examples of non-data classes will be of this kind: any class whose instances represent transient, local resources like a network connection, a position within a file or a running process, cannot be a data class. Likewise, any class where different instances should not be considered equal even if they contain the same information is not a data class either.
From the comments, it sounds like your question is really about why non-data classes exist in Kotlin and why you would ever choose not to make a data class. Here are some reasons.
Data classes are a lot more restrictive than a regular class:
They have to have a primary constructor, and every parameter of the primary constructor has to be a property.
They cannot have an empty primary constructor.
They cannot be open so they cannot be subclassed.
Here are other reasons:
Sometimes you don't want a class to have a copy function. If a class holds onto some heavy state that is expensive to copy, maybe it shouldn't advertise that it should be copied by presenting a copy function.
Sometimes you want to use an instance of a class in a Set or as Map keys without two different instances being considered as equivalent just because their properties have the same values.
The features of data classes are useful specifically for simple data holders, so the drawbacks are often something you want to avoid.

Aren't class member varialbes as bad as global variable?

We all know the following code is bad because of the use of global variable:
a = 3.14
def inc():
global a
a += 1
inc()
b = a
It is so bad that in python one has to intentionally declare global to "break" the ban. But in the name of OO, how come the code below is justified:
class A:
def __init__(self):
self.a = 3.14
def inc(self):
self.a += 1
A_instance = A()
A_instance.inc()
b = A_instance.a
Within the scope of the class instance, isn't the member variable simply the same as global variable? "self" basically grant unrestricted access to all variable to any member function regardless the necessity, making it very stateful, prone to mistakes, and difficult to read (basically all the bad traits of global var)?
We also know the clean and better way is:
def inc(_a):
return _a+1
a = 3.14
b = inc(a)
So that the function inc() is at least stateless and has a predictable behavior. What's the best practice to use class and make it as stateless as possible? Or by definition, is OO always stateful and one has to go functional programming without classes at all? I also heard people say #static methods are stupid, break encapsulation, and should be avoided...
It comes down to whether you need to save state or not. If you do need to save state then it needs to be saved somewhere. Classes allow you to save state alongside the methods that operate on that state and enforce a class-local scope that is less error prone than storing state within a global scope.
As a concrete example, I recently implemented a Tree class for a forest simulation. One of the variables that is important to associate with a tree is its age. Where should the age of the tree be stored? It makes more sense to store it within the Tree class than outside of it.
If protecting the age of the tree from being manipulated by code outside of the class was important, I could have used Python's excellent #property syntax for that purpose, or less directly through the Python _varname variable naming convention.
Within the class, yes, the age of the tree is visible to the other methods, but that is a relatively narrow scope, certainly not akin to a global scope if your classes are written with a single responsibility in accord with SOLID object oriented design principles.
Now the reason why the concept of self is not considered bad practice is that if you are to create a class everything within that class ought to be related in one way or another which usually is class attributes that class instances are initialized with via the __init__ dunder method. Basically, if you are going to create a class then there ought to be a link of some sort, a class global if you will which are class attributes
usually the idea that creating classes with just self like this
class A:
def __init__(self):
self.a = 3.14
def inc(self):
self.a += 1
is not something that is often seen, rather people chose the way which is generally in many opinions considered cleaner and more predictable
class A:
def __init__(self, a):
self.a = a
def inc(self):
self.a += 1
With this when you declare class instances you have more control of what is actually there, so class instances are hence declared with variables
A_instance = A(3.14) #a will be 3.14 in this instance
B_instance = A(3.142) #a will be 3.142 in this instance
and so on.
Class variables that are declared outside the __init__ function but inside the class, itself are considerably different and that would look like
class A:
a = 22/7
def __init__(self):
....
with this a would be a global variable throughout the class(not the instance but the class itself). So what does that look like
class A:
a = 22/7
def __init__(self, item):
self.item = item
A_instance = A(3.14)
B_instance = A(5)
Although A_instance and B_instance are completely different and A_instance.item will equal 3.14 while B_instance.item will equal 5 both of these will have the class variable a as 22/7
A_instance.a #this will return a value of 22/7
B_instance.a #this will also return a value of 22/7
So the class variable remains consistent/the same throughout all instances of that class unless it is actively altered.
Point is if you are going to create a class it should have specific variables that are intertwined with each other and affect all a particular group of functions, these are the functions you make into class methods as such the use of self within classes is not wrong if used properly

OOP: class inheritance to add just one property vs constructor argument

I'm new to OOP and I'm in the following situation: I have something like a report "Engine" that is used for several reports, the only thing needed is the path of a config file.
I'll code in Python, but this is an agnostic question.So, I have the following two approaches
A) class ReportEngine is an abstract class that has everything needed BUT the path for the config file. This way you just have to instantiate the ReportX class
class ReportEngine(object):
...
class Report1(ReportEngine):
_config_path = '...'
class Report2(ReportEngine):
_config_path = '...'
report_1 = Report1()
B) class ReportEngine can be instantiated passing the config file path
class ReportEngine(object):
def __init__(self, config_path):
self._config_path = config_path
...
report_1 = ReportEngine(config_path="/files/...")
Which approach is the right one? In case it matters, the report object would be inserted in another class, using composition.
IMHO the A) approach is better if you need to implement report engines that are different from each other. If your reports are populated using different logic, follow this approach.
But if the only difference among your report engines is the _config_path i think that B) approach is the right one for you. Obviosly, this way you'll have a shared logic to build every report, regardless the report type.
Generally spoken, put everything which every Report has, in the superclass. Put specific things in the subclasses.
So in your case, put the _config_path in the superclass ReportEngine like in B) (since every Report has a _config_path), but instanciate specific Reports like in A), whereas every Report can set its own path.
I don't know Python, but did a quick search for the proper syntax for Python 3.0+, I hope it makes sense:
class ReportEngine(object):
def __init__(self, config_path):
self._config_path = config_path
def printPath(self):
print self._config_path
...
class Report1(ReportEngine):
def __init__(self):
super().__init__('/files/report1/...')
Then a
reportObj = Report1()
reportObj.printPath()
should print
'/files/report1/...'
Basically the main difference is that approach A is more flexible than B(not mutual change in one report does not influence other reports), while B is simpler and clearer (shows exactly where the difference is) but a change affecting one report type would require more work. If you are pretty sure the reports won't change in time - go with B, if you feel like the differences will not be common in the future - go with A.

What is the difference between polymorphism and duck typing?

I'm a little confused with the two terms, here's what I know:
Polymorphism is the ability of object of different types to be handled by a common interface. While duck typing, is a kind of dynamic typing that allows objects of different types to respond to the same methods.
From what I understand, polymorphism is more about creating an interface that can be shared across different classes. And duck typing is about loose typing that will allow methods to be called as long as it is found on the receiver of the message.
Is this correct? I'm pretty confused on the two, they seem related but I do not know what their relationship is. Thanks a lot in advance!
Polymorphism (in the context of object-oriented programming) means a subclass can override a method of the base class. This means a method of a class can do different things in subclasses. For example: a class Animal can have a method talk() and the subclasses Dog and Cat of Animal can let the method talk() make different sounds.
Duck typing means code will simply accept any object that has a particular method. Let's say we have the following code: animal.quack(). If the given object animal has the method we want to call then we're good (no additional type requirements needed). It does not matter whether animal is actually a Duck or a different animal which also happens to quack. That's why it is called duck typing: if it looks like a duck (e.g., it has a method called quack() then we can act as if that object is a duck).
So are these related? They are simply separate features that a programming language may have. There are programming languages which have polymorphism but that do not have duck typing (such as Java). There are also languages that have polymorphism and duck typing (such as Python).
This is an example for Polymorphism in Python.
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof! Woof!'
animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print(animal)
print(animal.name + ': ' + animal.talk())
This is an example for duck Typing in Python.
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")
def name(self):
print("ITS A DUCK NO NAME")
class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather from the ground and shows it.")
def name(self):
print("John Smith")
def in_the_forest(duck):
duck.quack()
duck.feathers()
duck.name()
def game():
for element in [Duck(), Person()]:
in_the_forest(element)
game()
In polymorphism we see subclass (Cat and Dog) inheriting from the parent class (Animal) and overriding the method Talk.
In case of duck typing we don’t create a subclass instead new class is created with method having same name but different function.
Short Answer:
Duck typing is one way of achieving Polymorphism.
Another way is by using static typing.
Long Answer:
There are two different concepts involved here, typing and programming technique.
Duck typing is a type of typing. And typing means when to throw error when an object passed around isn't what is expected. Duck typing is a kind of typing where it throws error when the program is running and the method being called isn't available. Static typing comes with compile time checking, so if the type info doesn't match, it will throw error when you compile the code. And that is typing.
Polymorphism is a programming technique where you allow multiple types of object to fulfill certain responsibilities. You can do that by using a base type to represent all the child class types. You can use duck typing to represent all the different types that have the needed methods. You can use an interface to represent all the types that implement the interface.
There are answers saying polymorphism is inheritance, and that is not correct. Although you can use inheritance to create polymorphic behavior and usually that's what you do, but that's not what polymorphism is about.
For one, you don't need inheritance to have polymorphism as described above.
Secondly, the term "Polymorphism" is more meaningful in the context of the client code that depends on abstraction, and not the implementation code. Just because you have a super class and a few other classes that inherit from it and overriding some methods does not mean it's polymorphism, to create polymorphism you have to write client code in a polymorphic way to consume these classes.
Two type Polymorphism
Method overloading(Compile time Polymorphism ).
Method overriding(Run Time Polymorphism ).
Method overloading :- same function name and different data type is known as Method overloading
Example :
int addTwovalues(int a, int b)
{ return (a+b)}
float addTwovalues(float a, float b)
{ return (a+b)}
Method overriding :- same function name and same data type but different Class
is known as Method overriding.
class a
{
virtual int addtwovalues()
{ // to do }
}
class b:a
{
override int addtwovalues()
{ // to do }
}
a obj=new a();
obj.addtwovalues();
b objb=new a();
objb.addtwovalues(); //run time Polymorphism

Rails 3: Best location for reusable function called aftersave

My app has points / awards that can be achieved after a number of actions take place, which generally trigger when a record has been added (completing a mission, etc.)
I wrote a fairly involved function that audits all of the data, and awards the proper amount of points, user ranking, etc. This needs to be called after each one of these records is saved.
I know I can use Observers to call the function after a number of model saves, but I am unclear on where exactly the put said function, and how to call it.
Much appreciated in advance!
Observers usually go in app/models/. You can automatically generate an observer class for a model with the command rails generate observer YourModel. This will generate the file `app/models/your_model_observer.rb'.
By the way, aftersave is not a very descriptive method name. If it does a lot of things it's better to break it up into several methods each of which do one thing, and give each a descriptive name, e.g.:
class YourModelObserver < ActiveRecord::Observer
def after_save your_model_instance
calculate_points your_model_instance
assign_awards your_model_instance
end
private
def calculate_points inst
# ...
end
def assign_awards inst
# ...
end
end