Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Recently I have been wondering what convention of holding helper functions is clearer, or what are the pros and cons of each of them.
So far I've been creating simple functions, which I exported individually from a ts file from my /src/core/utils folder. I'm getting more and more often on projects, where a whole class of support functions is created and it's the class that is imported.
My stack is next.js (with typescript) without any additional webpack configuration and none of the dependencies have any real impact on project building.
My question:
What are the advantages of a class over functions?
Doesn't importing the whole class increase the size of the bundle?
I'm starting to think about transferring to classes, because the design of Formatters.formatRating to me seems to be more readable than importing the formatRating function, which does not know where it comes from until I check imports at the top of the file.
Class
export class Formatters {
public static formatRating = (rating: number) = rating.toFixed(1)
}
Function
export formatRating = (rating: number) = rating.toFixed(1)
I know that there is no simple answer. Functions seem more natural when choosing React, but I keep wondering about these classes.
Don't forget your third choice: Objects with function members. That's basically what your class with public static methods is, but you don't need to use class syntax for them.
What are the advantages of a class over functions?
Specifically, you'e asking about classes with only static methods. Classes where you intend to create instances and hold state have advantages over standalone functions, but those advantages wouldn't be relevant to what you're describing.
Without saying whether it's an advantage or not (which is opinion based), the chief differences I can see between using a class with static methods (or an object with function properties) and using individually-exported functions are:
You only have to import the class/object, not each function you want to use.
The name of the class/object can be useful for categorizing he kinds of functions it has, perhaps making the names of the functions themselves shorter (but the class/object name + function name will probably be at least as long).
Doesn't importing the whole class increase the size of the bundle?
It depends on how good the tree-shaking in your bundler is; specifically, whether it's smart enough to omit static methods that are never used. If it's smart enough to prune static methods, then it shouldn't matter. If it's "only" smart enough to prune unused exports, then it would matter — if there are functions/methods that aren't used. If you're using all (or nearly all) of them, they have to be in the bundle anyway.
Related
I am reading The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt, David Thomas. When I was reading about a term called orthogonality I was thinking that I am getting it right. I was understanding it very well. However, at the end of the chapter a few questions were asked to measure the level of understanding of the subject. While I was trying to answer those questions to myself I realized that I haven't understood it perfectly. So to clarify my understandings I am asking those questions here.
C++ supports multiple inheritance, and Java allows a class to
implement multiple interfaces. What impact does using these facilities
have on orthogonality? Is there a difference in impact between using multiple
inheritance and multiple interfaces?
There are actually three questions bundled up here: (1) What is the impact of supporting multiple inheritance on orthogonality? (2) What is the impact of implementing multiple interfaces on orthogonality? (3) What is the difference between the two sorts of impact?
Firstly, let us get to grips with orthogonality. In The Art of Unix Programming, Eric Raymond explains that "In a purely orthogonal design, operations do not have side effects; each action (whether it's an API call, a macro invocation, or a language operation) changes just one thing without affecting others. There is one and only one way to change each property of whatever system you are controlling."
So, now look at question (1). C++ supports multiple inheritance, so a class in C++ could inherit from two classes that have the same operation but with two different effects. This has the potential to be non-orthogonal, but C++ requires you to state explicitly which parent class has the feature to be invoked. This will limit the operation to only one effect, so orthogonality is maintained. See Multiple inheritance.
And question (2). Java does not allow multiple inheritance. A class can only derive from one base class. Interfaces are used to encode similarities which the classes of various types share, but do not necessarily constitute a class relationship. Java classes can implement multiple interfaces but there is only one class doing the implementation, so there should only be one effect when a method is invoked. Even if a class implements two interfaces which both have a method with the same name and signature, it will implement both methods simultaneously, so there should only be one effect. See Java interface.
And finally question (3). The difference is that C++ and Java maintain orthogonality by different mechanisms: C++ by demanding the the parent is explicitly specified, so there will be no ambiguity in the effect; and Java by implementing similar methods simultaneously so there is only one effect.
Irrespective of any number of interfaces/ classes you extend there will be only one implementation inside that class. Lets say your class is X.
Now orthogonality says - one change should affect only one module.
If you change your implementation of one interface in class X - will it affect other modules/classes using your class X ? Answer is no - because the other modules/classes are coding by interface not implementation.
Hence orthogonality is maintained.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
All,
I was recently asked in one of the technical interviews to write a high level design for a File Sysem. My answer to the question was as follows. I would request everyone to please review and let me know if there are suggestions/improvement:
interface BaseFileSystem
{
/*Basic file/folder attributes are:
1. File/Folder Size
2. File/Folder Date created
3. File/Folder Date Modified
4. File/Folder permissions - Read, write and execute
5. File/Folder Owner - Owner of the file who defines permissions for other users
6. File/Folder Visibility - Hidden or Visible
7. File/Folder Name
Hence each one of the above attributes would have public <return type> get() and public void set<AttributeName>(<variable datatype>) */
}
public class File implements BaseFileSystem
{
/*The `File` class should implement all of the methods from interface `BaseFilesystem`.
In addition, it must also implement following specific methods that can only be associated with physical files*/
public String getFileExtension(){….}
public void setFileExtension(String value) {….}
public String[] getAssociatedPrograms(){ …..}
public void executable(){ …. };
}
public class Folder implements BaseFileSystem
{
/*The `Folder` class should implement all of the methods from interface `BaseFileSystem`. In addition, it must also implement following specific methods that can only be associated with the physical 'folders'*/
public BaseFileSystem[] getSubFoldersAndFiles(){ …. }
public void addSubFolderAndFiles(BaseFileSystem fileObj) { …. }
public void executable(){throw new UnsupportedOperationException();}
}
Additionally, any general pointers to such design questions would be greatly appreciated.
There are three essential operations, that are missing:
reading the contents of a file
writing the contents of a file
testing whether a BaseFileSystem is a File or a Folder
On the other hand, there are some operations that I do not consider essential for a file system:
the file extension does not have any significance in all operating systems. Then why should a method exists for setting and retrieving it?
the associated programs only have a meaning in a single computer/os combination. In a general purpose file system, the programms might exists only temporarily (because a different os is booted or the device is moved). It should IMHO not be stored as part of the meta information of a file, because of separation of concerns.
public void executable() seems out of place. But this is only a guess, because I do not know what this method is supposed to do. If this executes an executable file: that should be done by the operating system manually. Also, it has no business being defined in class Folder.
Furthermore, the attributes that you defined in BaseFileSystem make some assumptions about the requirements of the file system. Maybe your simple permissions system is not sufficient or the purpose of the file system and ACLs are needed. Maybe visibility is determined by the name of the file (like in UNIX). You should clarify that beforehand.
From what i know about interview questions, you need to make sure you ask clarifying questions about the file system. The hidden part of a question like that is to make sure you're someone who can identify ambiguity. Also figure out who your users might be, since they might not care about "Date Modified"
When i read this question, i was thinking something *nix-based and would use the command lines! Good luck!
I don't think it makes sense to just give an API. If you follow POSIX, the API is already given to you. Wouldn't it make more sense to describe the data model for the file system? For example, how do you link the data, track used/free blocks, handle modifications, etc...
I didn't like this either:
Hence each one of the above attributes would have public get() and public void set() */
I really detest getters/setters. If I was going to design a file system, I would push any file metadata outside of the file system. Instead provide a generic interface for arbitrary metadata. For example, permissions might be irrelevant on an embedded system, so why make it part of the file system?
Good luck!
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Advantage of Static class over use of Singleton
Usually, everytime I needed a single systemwide object I used the singleton pattern.
M question is, why shouldn't i just implement the object as static and get the single object behaviour naturally ? Are there any cons to use static types over singleton factored object?
A static type is a lot less (unit) testable.
Singletons can be passed around (as parameters) and inherited.
For examples etc see this article:
http://dotnetperls.com/singleton-static
In general you should avoid systemwide objects, as these suggest you have global state. Singleton's are ofter used to manage access to a shared resource (rather than state).
I believe at lest one of the GoF is on record as saying that including singleton's in their book was a mistake and in many cases it's used as an anti-pattern.
depends on what you want to do with the object. if it's just calling methods on it then just use a static. if you want to pass the object around, and do object oriented stuff with it, i.e polymorphism then do it the object way.
What are the pros and cons of having multiple inheritance?
And why don't we have multiple inheritance in C#?
UPDATE
Ok so it is currently avoided because of the issue with clashes resolving which parent method is being called etc. Surely this is a problem for the programmer to resolve. Or maybe this could be resolve simularly as SQL where there is a conflict more information is required i.e. ID might need to become Sales.ID to resolve a conflict in the query.
Here is a good discussion on the pitfalls of multiple inheritance:
Why should I avoid multiple inheritance in C++?
Here is a discussion from the C# team on why they decided not to allow multiple inheritance:
http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85562.aspx
http://dotnetjunkies.com/WebLog/unknownreference/archive/2003/09/04/1401.aspx
It's just another tool in the toolbox. Sometimes, it is exactly the right tool. If it is, having to find a workaround because the language actually prohibits it is a pain and leads to good opportunities to screw it up.
Pros and cons can only be found for a concrete case. I guess that it's quite rare to actually fit a problem, but who are the language designers to decide how I am to tackle a specific problem?
I will give a pro here based on a C++ report-writer I've been converting to REALbasic (which has interfaces but only single-inheritance).
Multiple inheritance makes it easier to compose classes from small mixin base classes that implement functionality and have properties to remember state. When done right, you can get a lot of reuse of small code without having to copy-and-paste similar code to implement interfaces.
Fortunately, REALbasic has extends methods which are like the extension methods recently added to C# in C# 3.0. These help a bit with the problem, especially as they can be applied to arrays. I still ended up with some class hierarchies being deeper as a result of folding in what were previously multiply-inherited classes.
The main con is that if two classes have a method with the same name, the new subclass doesn't know which one to call.
In C# you can do a form of multiple inheritance by including instances of each parent object within the child.
class MyClass
{
private class1 : Class1;
private class2: Class2;
public MyClass
{
class1 = new Class1;
class2 = new Class2;
}
// Then, expose whatever functionality you need to from there.
}
When you inherit from something you are asserting that your class is of that (base) type in every way except that you may implement something slightly differently or add something to it, its actually extremely rare that your class is 2 things at once. Usually it just has behavour common to 2 or more things, and a better way to describe that generally is to have your class implement multiple interfaces. (or possibly encapsulation, depending on your circumstances)
It's one of those help-me-to-not-shoot-myself-in-the-foot quirks, much like in Java.
Although it is nice to extend fields and methods from multiple sources (imagine a Modern Mobile Phone, which inherits from MP3 Players, Cameras, Sat-Navs, and the humble Old School Mobile Phone), clashes cannot be resolved by the compiler alone.
I used to have one class for one file. For example car.cs has the class car. But as I program more classes, I would like to add them to the same file. For example car.cs has the class car and the door class, etc.
My question is good for Java, C#, PHP or any other programming language. Should I try not having multiple classes in the same file or is it ok?
I think you should try to keep your code to 1 class per file.
I suggest this because it will be easier to find your class later. Also, it will work better with your source control system (if a file changes, then you know that a particular class has changed).
The only time I think it's correct to use more than one class per file is when you are using internal classes... but internal classes are inside another class, and thus can be left inside the same file. The inner classes roles are strongly related to the outer classes, so placing them in the same file is fine.
In Java, one public class per file is the way the language works. A group of Java files can be collected into a package.
In Python, however, files are "modules", and typically have a number of closely related classes. A Python package is a directory, just like a Java package.
This gives Python an extra level of grouping between class and package.
There is no one right answer that is language-agnostic. It varies with the language.
One class per file is a good rule, but it's appropriate to make some exceptions. For instance, if I'm working in a project where most classes have associated collection types, often I'll keep the class and its collection in the same file, e.g.:
public class Customer { /* whatever */ }
public class CustomerCollection : List<Customer> { /* whatever */ }
The best rule of thumb is to keep one class per file except when that starts to make things harder rather than easier. Since Visual Studio's Find in Files is so effective, you probably won't have to spend much time looking through the file structure anyway.
No I don't think it's an entirely bad practice. What I mean by that is in general it's best to have a separate file per class, but there are definitely good exception cases where it's better to have a bunch of classes in one file. A good example of this is a group of Exception classes, if you have a few dozen of these for a given group does it really make sense to have separate a separate file for each two liner class? I would argue not. In this case having a group of exceptions in one class is much less cumbersome and simple IMHO.
I've found that whenever I try to combine multiple types into a single file, I always end going back and separating them simply because it makes them easier to find. Whenever I combine, there is always ultimately a moment where I'm trying to figure out wtf I defined type x.
So now, my personal rule is that each individual type (except maybe for child classes, by which a mean a class inside a class, not an inherited class) gets its own file.
Since your IDE Provides you with a "Navigate to" functionality and you have some control over namespacing within your classes then the below benefits of having multiple classes within the same file are quite worth it for me.
Parent - Child Classes
In many cases i find it quite helpful to have Inherited classes within their Base Class file.
It's quite easy then to see which properties and methods your child class inherits and the file provides a faster overview of the overall functionality.
Public: Small - Helper - DTO Classes
When you need several plain and small classes for a specific functionality i find it quite redundant to have a file with all the references and includes for just a 4-8 Liner class.....
Code navigation is also easier just scrolling over one file instead of switching between 10 files...Its also easier to refactor when you have to edit just one reference instead of 10.....
Overall breaking the Iron rule of 1 class per file provides some extra freedom to organize your code.
What happens then, really depends on your IDE, Language,Team Communication and Organizing Skills.
But if you want that freedom why sacrifice it for an iron rule?
The rule I always go by is to have one main class in a file with the same name. I may or may not include helper classes in that file depending on how tightly they're coupled with the file's main class. Are the support classes standalone, or are they useful on their own? For example, if a method in a class needs a special comparison for sorting some objects, it doesn't bother me a bit to bundle the comparison functor class into the same file as the method that uses it. I wouldn't expect to use it elsewhere and it doesn't make sense for it to be on its own.
If you are working on a team, keeping classes in separate files make it easier to control the source and reduces chances of conflicts (multiple developers changing the same file at the same time). I think it makes it easier to find the code you are looking for as well.
It can be bad from the perspective of future development and maintainability. It is much easier to remember where the Car class is if you have a Car.cs class. Where would you look for the Widget class if Widget.cs does not exist? Is it a car widget? Is it an engine widget? Oh maybe it's a bagel widget.
The only time I consider file locations is when I have to create new classes. Otherwise I never navigate by file structure. I Use "go to class" or "go to definition".
I know this is somewhat of a training issue; freeing yourself from the physical file structure of projects requires practice. It's very rewarding though ;)
If it feels good to put them in the same file, be my guest. Cant do that with public classes in java though ;)
You should refrain from doing so, unless you have a good reason.
One file with several small related classes can be more readable than several files.
For example, when using 'case classes', to simulate union types, there is a strong relationship between each class.
Using the same file for multiple classes has the advantage of grouping them together visually for the reader.
In your case, a car and a door do not seem related at all, and finding the door class in the car.cs file would be unexpected, so don't.
As a rule of thumb, one class/one file is the way to go. I often keep several interface definitions in one file, though. Several classes in one file? Only if they are very closely related somehow, and very small (< 5 methods and members)
As is true so much of the time in programming, it depends greatly on the situation.
For instance, what is the cohesiveness of the classes in question? Are they tightly coupled? Are they completely orthogonal? Are they related in functionality?
It would not be out of line for a web framework to supply a general purpose widgets.whatever file containing BaseWidget, TextWidget, CharWidget, etc.
A user of the framework would not be out of line in defining a more_widgets file to contain the additional widgets they derive from the framework widgets for their specific domain space.
When the classes are orthogonal, and have nothing to do with each other, the grouping into a single file would indeed be artificial. Assume an application to manage a robotic factory that builds cars. A file called parts containing CarParts and RobotParts would be senseless... there is not likely to be much of a relation between the ordering of spare parts for maintenance and the parts that the factory manufactures. Such a joining would add no information or knowledge about the system you are designing.
Perhaps the best rule of thumb is don't constrain your choices by a rule of thumb. Rules of thumb are created for a first cut analysis, or to constrain the choices of those who are not capable of making good choices. I think most programmers would like to believe they are capable of making good decisions.
The Smalltalk answer is: you should not have files (for programming). They make versioning and navigation painful.
One class per file is simpler to maintain and much more clear for anyone else looking at your code. It is also mandatory, or very restricted in some languages.
In Java for instance, you cannot create multiple top level classes per file, they have to be in separate files where the classname and filename are the same.
(C#) Another exception (to one file per class) I'm thinking of is having List in the same file as MyClass. Where I envisage using this is in reporting. Having an extra file just for the List seems a bit excessive.