Last active
September 4, 2023 12:01
-
-
Save martynov-alex/c7aabb3016288b061f78ae5fb98e8031 to your computer and use it in GitHub Desktop.
Queue example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'dart:collection'; | |
| void main() async { | |
| final repository = ProductDetailRepository(); | |
| final service = RecentlyWatchedService(productDetailRepository: repository); | |
| await Future.delayed(const Duration(seconds: 1)); | |
| service.add(const Product(7)); | |
| service.add(const Product(3)); | |
| service.add(const Product(2)); | |
| service.add(const Product(3)); | |
| service.add(const Product(5)); | |
| service.add(const Product(7)); | |
| service.add(const Product(8)); | |
| print(service.products); | |
| final repoProducts = await repository.getRecentlyWatchedProducts(); | |
| print(repoProducts); | |
| } | |
| const _maxProductsQuantity = 6; | |
| /// A service that allows you to track previously watched products. | |
| class RecentlyWatchedService { | |
| final IProductDetailRepository _productDetailRepository; | |
| final _products = Queue<Product>(); | |
| List<Product> get products => _products.toList(); | |
| RecentlyWatchedService({ | |
| required IProductDetailRepository productDetailRepository, | |
| }) : _productDetailRepository = productDetailRepository { | |
| _init(); | |
| } | |
| /// Add recently watched product. | |
| void add(Product product) { | |
| _handleNewProduct(product); | |
| _saveRecentlyWatchedProducts(); | |
| } | |
| void _handleNewProduct(Product product) { | |
| if (_products.isEmpty) { | |
| _products.addFirst(product); | |
| return; | |
| } | |
| _products.remove(product); | |
| final hasReachedMax = _products.length >= _maxProductsQuantity; | |
| if (hasReachedMax) _products.removeLast(); | |
| _products.addFirst(product); | |
| } | |
| Future<void> _init() async { | |
| try { | |
| final products = | |
| await _productDetailRepository.getRecentlyWatchedProducts(); | |
| if (products.isEmpty) return; | |
| _products.addAll(products); | |
| } on Object catch (e, stack) { | |
| // Handle error. | |
| print('Error $e, stack $stack'); | |
| } | |
| } | |
| Future<void> _saveRecentlyWatchedProducts() async { | |
| try { | |
| await _productDetailRepository.saveRecentlyWatchedProducts( | |
| products: _products.toList(), | |
| ); | |
| } on Object catch (e, stack) { | |
| // Handle error. | |
| print('Error $e, stack $stack'); | |
| } | |
| } | |
| } | |
| class Product { | |
| final int id; | |
| const Product(this.id); | |
| @override | |
| String toString() => id.toString(); | |
| @override | |
| bool operator ==(Object other) => | |
| identical(this, other) || other is Product && id == other.id; | |
| @override | |
| int get hashCode => id.hashCode; | |
| } | |
| /// Repository interface. | |
| abstract interface class IProductDetailRepository { | |
| /// Get a list of previously watched products. | |
| Future<List<Product>> getRecentlyWatchedProducts(); | |
| /// Save previously watched products. | |
| Future<void> saveRecentlyWatchedProducts({ | |
| required List<Product> products, | |
| }); | |
| } | |
| class ProductDetailRepository implements IProductDetailRepository { | |
| final _products = <Product>[const Product(0), const Product(9)]; | |
| ProductDetailRepository(); | |
| @override | |
| Future<List<Product>> getRecentlyWatchedProducts() async => | |
| Future.delayed(const Duration(seconds: 1), () => _products); | |
| @override | |
| Future<void> saveRecentlyWatchedProducts({ | |
| required List<Product> products, | |
| }) async => | |
| Future.delayed(const Duration(seconds: 1), () { | |
| _products | |
| ..clear() | |
| ..addAll(products); | |
| }); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment