Comments (11)
but if you need to use multiple (and it's at least how I use it), in my opinion it's anyway more convenient to work with single
for that case there are interfaces BaseProviders
, SportProviders
, FoodProviders
, EntertainmentProviders
, VideoGameProviders
and you can create a custom faker implementing only certain interfaces,
E.g. in case you need to have only HealthCare
and Food
you can create custom faker like
public class MyCustomFaker extends BaseFaker implements FoodProviders, HealthCareProviders {
public MyCustomFaker() {
}
public MyCustomFaker(Locale locale) {
super(locale);
}
public MyCustomFaker(Random random) {
super(random);
}
public MyCustomFaker(Locale locale, Random random) {
super(locale, random);
}
public MyCustomFaker(Locale locale, RandomService randomService) {
super(locale, randomService);
}
public MyCustomFaker(FakeValuesService fakeValuesService, FakerContext context) {
super(fakeValuesService, context);
}
}
after that
var faker = new MyCustomFaker();
and in autocompletion there will be both food and healthcare related methods
from datafaker.
Ps: I'm also fine with moving things around, no problem!
from datafaker.
@filipowm thanks for your suggestions, they are certainly good ideas, but breaking the api a little bit is something we do with consideration, breaking the api a lot is something we generally try to avoid. We want to make it easy for people to adopt, and whether they come from Javafaker or a previous version of Datafaker, the migration is generally trivial.
I'm not sure if the proposed change brings the benefit of breaking the API at this moment. But don't let go of this idea, we can change our mind in the future!
from datafaker.
Hi @filipowm , great suggestion, we would absolutely appreciate a contribution from someone who has experience in the healthcare domain, so yes, a PR would be very welcome, and happy to help if you need it!
from datafaker.
Fantastic. So let me play around it a bit in upcoming days/weeks 😉
from datafaker.
I started from moving around existing code to suit new structure (and grouping some stuff together), and I started thinking if it wouldn't be worthwhile to a bit "break" how providers are structured and make API more fluent, by providing here intermediate grouping provider.
Details below ↓
The idea
Logically group providers, in this case under healthcare
providers group there will be other providers related to medical stuff.
As-is
Example code how it works today:
var medicine = faker.medical().medicineName();
var symptom = faker.medical().symptoms();
var blood = faker.bloodtype().bloodGroup();
To-be
The new API could look like this
var medicine = faker.healthcare().medication().drugName(); // well, it might be another long discussion about drug vs medicine ;-)
var symptom = faker.healthcare().condition().symptom();
var blood = faker.healthcare().blood().group();
Looking at the class diagram, it would simply be about adding grouping providers interface like HealthcareProvidersGroup
, that Faker
would implement. Treat this as a draft, cause there are still few things I would need to figure out.
classDiagram
Faker ..|> HealthcareProvidersGroup
HealthcareProvidersGroup --|> ProviderRegistration : I'm not sure if this implements would\n make sense here, cause it's just\n grouping of other ProviderRegistration(s)
HealthcareProviders --|> ProviderRegistration
HealthcareProviders --> HealthcareProvidersGroup
Blood --> HealthcareProviders
Medication --> HealthcareProviders
class ProviderRegistration {
<<interface>>
}
class Faker {
}
class HealthcareProvidersGroup {
<<interface>>
+healthcare() HealthcareProviders
}
class HealthcareProviders {
+blood() Blood
+medication() Medication
+...()
}
class Blood {
+group() String
+...()
}
class Medication {
+drugName() String
+...()
}
Pros & cons
Pros:
- better logical grouping of providers, making them more focused and (imo) easier to find relevant ones for the user
- potential for reusing provider names, but in different context, eg.
Device
in healthcare context is different than generalDevice
and I would find it totally fine to have both, but in different contexts - would be a nice introduction to reworking and modularizing existing codebase (eg. grouping finance-related providers, entertainment)
Cons:
- breaks existing commonly used flat structure
- well... more typing for the API consumer 😅
What do you think about that?
from datafaker.
From one side it could make to introduce a group like healthcare
or Medical
or something similar in case we have enough providers to put in it e.g. > 5.
From the other side I don't understand why should we have this method healthcare()
?
Why people should write code
var medicine = faker.healthcare().medication().drugName();
if
var medicine = faker.medication().drugName();
is shorter?
I don't see a benefit and it is hard to persuade people to write something longer if the result is same
Also there is another problem: such approach will break concistency between java api and expressions calls which could be used either in yaml
files or in expression
methods.
Moreover if you try to generate something 1000_000_000 times or more, you will see that this code
for (int i = 0; i < 1000_000_000; i++) {
var medicine = faker.medication().drugName();
// whatever other code
}
is suboptimal because each time faker.medication()
will lead to hashmap hash calculations.
I would assume that code with healthcare()
would be even more suboptimal
more optimal way is something like
var medication = faker.medication();
for (int i = 0; i < 1000_000_000; i++) {
var medicine = medication.drugName();
// whatever other code
}
then hash will be calculated only once and it will be executed faster
from datafaker.
Thanks @snuyanzin for feedback.
Actually I see introducing healthcare()
(and in future maybe other too) just a handy way to group related providers, and make it easier for users to find what they need, instead of scrolling through ever-growing number of providers. I came with that because I found quite a few new providers around health I would like to add. Right now it makes me a bit frustrated when I'm scrolling through providers under faker
to find the relevant one, unless I exactly know what I'm looking for. So yes, it's convenience. The same way I could see introducing grouping for already existing entertainment
, food
, sport
and videogame
.
Could you explain more about the consistency you mentioned? Seems like this is something I am missing.
Also good point with the lookup to hashmap and hash calculation, yet in my opinion in scenarios where faker is used (mostly tests I bet) impact of hash calculation is negligible -- after that it will be just 2*O(1)
to get the needed provider once it's in cache after first usage.
Same approach with caching providers could work when grouping is used:
var medication = faker.medication(); // this one is taken from cache
for (int i = 0; i < 1000_000_000; i++) {
var medicine = medication.drugName();
// whatever other code
}
would work same way as
var medication = faker.healthcare().medication(); // both healthcare and medication will be taken from cache (I already investigated how to approach that and it's easily doable), but in this case it would be 3x lookup
for (int i = 0; i < 1000_000_000; i++) {
var medicine = medication.drugName();
// whatever other code
}
So tl;dr; for me its mostly about convenience of usage, and necessarily not only for new users. Other benefits I mentioned are more of a side effect.
from datafaker.
(and in future maybe other too) just a handy way to group related providers, and make it easier for users to find what they need, instead of scrolling through ever-growing number of providers.
For that reason there are SportFaker
, FoodFaker
and others which could be used in a way
var faker = new SportFaker();
and then in autocompletion there will be only sport related providers or food related.
I would rather go this way and have something like
var faker = new HealthCareFaker();
we can invoke java code via expressions like mentioned here https://www.datafaker.net/documentation/expressions/#options
and in most cases it is used in yaml
configuration. There is an assumption that first there is provider name and then a method name. In case you try to use the construction with healthcare
it will not work
from datafaker.
Now I get it, thanks! I never used expressions so far, so here came my lack of knowledge 🙃 Certainly expressions would not work, and to make it work would require some changes in FakeValuesService
, especially calculation of dotIndex
(where there might be multiple for chained calls) and resolveFakerObjectAndMethod
to allow chained methods like healthcare.medication.drugName
.
Nice hint with dedicated faker instances, but if you need to use multiple (and it's at least how I use it), in my opinion it's anyway more convenient to work with single
var faker = new Faker();
instead of
var sportFaker = new SportFaker();
var healthcareFaker = new HealthCareFaker();
Yet this somehow alleviates the need for stricter grouping.
I will move on with how it is now, but I will be happy to revisit grouping in future. If you would like to make that happen, you can count on my help. Thanks again @snuyanzin !
from datafaker.
Closing this issue for now, but feel free to send a pull request for contributing medical fakers, that would be very appreciated.
from datafaker.
Related Issues (20)
- Intermitted expressions failures during testing HOT 8
- Regexify method doesn't recognise "^" and "$" chars in datafaker before 2.2.0. HOT 7
- Remove public methods from `IdNumber` that are not intended to be directly called HOT 8
- How to specify country-specific setting, not language-specific? HOT 2
- Feature request: add support to generate a random PNG/SVG. HOT 1
- 2.3.0 Release HOT 13
- Password generation does not always contain a lowercase letter HOT 3
- Publishing docs works now HOT 1
- Memory leak in maps containing FakerContext as a key HOT 30
- Memory leak for seeded random use case HOT 3
- Create a dictionary of obscene words HOT 8
- java.lang.ClassCastException for finance.credit_card provider with Enum argument in Faker expression HOT 5
- Problems with module-info.java with version 2.3.0 HOT 33
- New Project to improving tests HOT 9
- Locale specific generation performance degradation HOT 1
- Fix publishing of snapshots HOT 4
- Code coverage report is broken HOT 4
- Unable to resolve expression during build HOT 12
- Add weighted selection HOT 2
- Faker().locality().allSupportedLocales() returns empty when Datafaker is embedded in Spring Boot Uber JAR HOT 25
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from datafaker.