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

Proposal: make Card an extendable class #15

Open
brainwo opened this issue Aug 31, 2024 · 0 comments
Open

Proposal: make Card an extendable class #15

brainwo opened this issue Aug 31, 2024 · 0 comments

Comments

@brainwo
Copy link
Contributor

brainwo commented Aug 31, 2024

Background

Currently the class Card only holds properties as follows:

factory Card.def(
DateTime due,
DateTime lastReview, [
@Default(0) double stability,
@Default(0) double difficulty,
@Default(0) int elapsedDays,
@Default(0) int scheduledDays,
@Default(0) int reps,
@Default(0) int lapses,
@Default(State.newState) State state,
]) = _Card;

Applications will have to store their own data on top of existing Card object. For example, a typical flashcard will need to store "Card Name", "Deck", and so on.

class MyCard {
  Card card;
  String cardName;
  String deck;
  ... // and others...
}

Some of applications may also have multiple card types, so inheriting a class containing common properties would makes sense for this.

abstract class MyCard {
  Card card;
  String cardName; 
  String deck;
  ...
}

class TextCard extends MyCard {
  String text;
  ...
}

class ImageCard extends MyCard {
  File image;
  ...
}

But doing this, makes a convoluted API design.

final fsrs = FSRS();
final textCard = TextCard();
final now = DateTime(2022, 11, 29, 12, 30, 0, 0);
final schedulingCards = fsrs.repeat(textCard.card, now);
textCard.card = schedulingCards;
print(textCard.card.due);

It would be simpler if TextCard inherit Card properties instead, removing extra hops it needs to get accessing the Card object using .card. But since Card is constructed with a factory for private class _Card, Card can't be extended by another class.

class TextCard extends Card {
  final String text; 

  TextCard({required this.text});
// ^^^^^^^^
// The generative constructor 'Card Card()' is expected, but a factory was found.
// Try calling a different constructor of the superclass, or making the called // constructor not be a factory constructor.
}

Proposal

From the above description, I suggest changing the Card API to make it extendable/inherited by other classes, this will allow the object to access to Card's properties and further make the API cleaner.

// fsrs/models.dart
abstract class Card {
  const Card({
    ... // implementation of the Card model
  });
  ... // implementation of the Card model
}

// app/model.dart
class TextCard extends Card {
  String text;  
  ...
}

class ImageCard extends Card {
  Image image;
  ...
}

// app/main.dart
var imageCard = ImageCard();
imageCard.due; // get card due
imageCard.image; // get card image

imageCard = fsrs.repeat(imageCard, now); // scheduling a card

This code isn't a final decision, I'm still not sure how it should be for the most part. As for the modifiers, I would refer to this documentation first: Class modifiers for API maintainers | Dart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant