Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exception to a rule for class that contains only static members. #5077

Closed
wants to merge 1 commit into from

Conversation

polina-c
Copy link
Contributor

@polina-c polina-c commented Jul 24, 2023

Classes like this happen so often that it worse mentioning them as exception: https://api.dart.dev/stable/3.0.6/dart-developer/Service/Service.html

@github-actions
Copy link

Visit the preview URL for this PR (updated for commit 022bc98):

https://dart-dev--pr5077-polina-c-patch-1-in77qeqy.web.app

(expires Mon, 31 Jul 2023 20:07:04 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: d851bc446d3c4d7394c5406c6f07255afc7075f3

@polina-c polina-c requested review from a-siva and bkonyi July 24, 2023 20:19
@parlough parlough requested a review from munificent July 24, 2023 20:36
@parlough parlough added a.effective-dart Relates to the best practices explained in Effective Dart review.tech Awaiting Technical Review labels Jul 24, 2023
Copy link

@a-siva a-siva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be singleton objects instead of single instance objects ?

@munificent
Copy link
Member

Can you give an example of what you mean?

@bkonyi
Copy link

bkonyi commented Jul 25, 2023

Assuming I'm understanding this correctly, I'm not sure it's even worth mentioning the exceptions.

With enhanced enums, there's really no reason to have create new classes of constants, and "enum-like types" are also covered by the functionality introduced with enhanced enums. "Single instance" objects are just singletons and by definition are of a type that is instantiated at least once, making their inclusion in this list of exceptions unnecessary.

@polina-c
Copy link
Contributor Author

polina-c commented Jul 25, 2023

Should it be singleton objects instead of single instance objects ?

'singletone' is a pattern that is useful when exactly one object is needed. So, 'singletone' is a pattern, and 'single object' is a situation, the same as 'when exactly one object is needed', but shorter.

We need situation here. So, I think 'single object' works better.

Am i missing something?

@polina-c
Copy link
Contributor Author

Can you give an example of what you mean?

https://api.dart.dev/stable/3.0.6/dart-developer/Service/Service.html

@polina-c
Copy link
Contributor Author

Assuming I'm understanding this correctly, I'm not sure it's even worth mentioning the exceptions.

With enhanced enums, there's really no reason to have create new classes of constants, and "enum-like types" are also covered by the functionality introduced with enhanced enums. "Single instance" objects are just singletons and by definition are of a type that is instantiated at least once, making their inclusion in this list of exceptions unnecessary.

Enhanced enums are limited to constants.
You cannot convert this class to enhanced enum: https://api.dart.dev/stable/3.0.6/dart-developer/Service/Service.html

singleton is a pattern to implement single instance
static class with set of static methods and instances is another pattern that implements single instance

So, "Single instance" objects are sometimes implemented as singletons, and sometimes differently.

Makes sense?

@bkonyi
Copy link

bkonyi commented Jul 25, 2023

Can you give an example of what you mean?

https://api.dart.dev/stable/3.0.6/dart-developer/Service/Service.html

That class should just be made abstract since there's no instance members that are useful.

Although... I think having an abstract class with all static members is a technically a smell as well since namespacing should be done using the as <namespace> syntax when importing the library. That's a bit more difficult when it comes to the dart:* libraries, but I digress... :)

@polina-c
Copy link
Contributor Author

polina-c commented Jul 25, 2023

Can you give an example of what you mean?

https://api.dart.dev/stable/3.0.6/dart-developer/Service/Service.html

That class should just be made abstract since there's no instance members that are useful.

Although... I think having an abstract class with all static members is a technically a smell as well since namespacing should be done using the as <namespace> syntax when importing the library. That's a bit more difficult when it comes to the dart:* libraries, but I digress... :)

Yes, you can import a library with a namespace to create grouping. However, it means manual crafting (opposite to just adding import with quick fix), that have to be consistent across the client package, i.e. the same namespace should be used everywhere.

And, meaningful grouping for static methods and variables, provided by the package authors, really helps to navigate the code, taking advantage of InteliSense.

May be some day we should stop demonizing namespacing and introduce keyword 'namespace' to use instead of 'class'?...

@jakemac53
Copy link
Contributor

Am i missing something?

Yes, this isn't a Singleton, there is no instance at all. In fact, the Service class is exactly what this rule is advising against, it is a direct violation of the suggestion.

As mentioned above, if this was a singleton it would have a constructor (probably private) and an instance, and then it would be allowed to have these methods.

May be we should stop demonizing namespacing and introduce keyword 'namespace' to use instead of 'class'?...

You can use an extension with static members instead to create a more pure namespace without introducing a type that has no instances. And probably the lint won't trigger either. It is still going against the spirit of this guideline, but it is arguably a better way of creating a namespace, if you feel one is necessary.

@polina-c
Copy link
Contributor Author

polina-c commented Jul 25, 2023

Am i missing something?

Yes, this isn't a Singleton, there is no instance at all. In fact, the Service class is exactly what this rule is advising against, it is a direct violation of the suggestion.

Service is conceptually an object, "a thing". But, as there is no state, there is no need to instantiate it, so there is no need to implement Singleton pattern. However, per me, it makes perfect sense to define abstract class to describe behavior of this "thing". Anything wrong?

@polina-c polina-c changed the title Add exception to a rule. Add exception to a rule for class that contains only static members. Jul 25, 2023
@jakemac53
Copy link
Contributor

jakemac53 commented Jul 25, 2023

However, per me, it makes perfect sense to define abstract class to describe behavior of this "thing". Anything wrong?

The "wrong" part is described in the rule - In idiomatic Dart, classes define kinds of objects. A type that is never instantiated is a code smell. For instance you can now do void myMethod(Service thing) and that function is valid to write but can never be called because there are never any instances of that type.

This is why the extension approach is arguably better, it doesn't introduce this extra Type into the program.

I do think there are valid reasons you might want a namespace in Dart, although I wouldn't use them heavily. This rule isn't a don't, it's an avoid, so if you think you have a good reason to create a namespace go ahead. But you might need to explain to the reviewer your justification for that. And if you are enforcing avoid_classes_with_only_static_members then you will have to ignore it. Or just use an extension to avoid the lint.

@polina-c polina-c closed this Jul 25, 2023
@polina-c
Copy link
Contributor Author

Thanks to everybody for discussion!

@parlough parlough deleted the polina-c-patch-1 branch July 25, 2023 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a.effective-dart Relates to the best practices explained in Effective Dart review.tech Awaiting Technical Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants