vendredi 29 décembre 2023

How to use the Command Pattern when dealing with different parameters

Having a look at the UML diagrams for the Command Pattern reported here and here, the class of the invoker object (the one that inkoves the execute() method of a command object) must provide a setCommand() method to allow the client code to set the proper command object on the invoker: but how can such method be used when dealing with command objects that have different parameters which, additionally, are known only at runtime? I'll try to make an example.

class Messenger
{
  public function sendEmail(string $email, string $subject, string $body): void { ... }
  public function sendSms(string $phone, string $text): void { ... }
}

interface Command
{
  public function execute(): void;
}

class SendEmailCommand implements Command
{
  private readonly Messenger $messenger;
  private readonly string $email;
  private readonly string $subject;
  private readonly string $body;

  public function __constructor(Messenger $messenger)
  {
    $this->messenger = $messenger;
  }

  public function setEmail(string $email): void { $this->email = $email; }
  public function setSubject(string $subject): void { $this->subject = $subject; }
  public function setBody(string $body): void { $this->body = $body; }

  public function execute(): void
  {
    $this->messenger->sendEmail($this->email, $this->subject, $this->body);
  }
}

class SendSmsCommand implements Command
{
  private readonly Messenger $messenger;
  private readonly string $phone;
  private readonly string $text;

  public function __constructor(Messenger $messenger)
  {
    $this->messenger = $messenger;
  }

  public function setPhone(string $phone): void { $this->phone = $phone; }
  public function setText(string $text): void { $this->text = $text; }

  public function execute(): void
  {
    $this->messenger->sendSms($this->phone, $this->text);
  }
}

In such a scenario how much is it useful to have a setCommand(Command $command) on the invoker class? In some languages I would even get an error later when trying to call setX() because the Command interface doesn't define them. Would it be a bad idea to do something like this?

class EmailSendButton()
{
  private readonly Messenger $messenger;

  public function __constructor(Messenger $messenger)
  {
    $this->messenger = $messenger;
  }

  public function onClick(): void
  {
    $email = $this->getEmail();
    $subject = $this->getSubject();
    $body = $this->getBody();

    $sendEmailCommand = new SendEmailCommand($this->messenger);
    $sendEmailCommand->setEmail($email);
    $sendEmailCommand->setSubject($subject);
    $sendEmailCommand->setBody($body);
    $sendEmailCommand->execute();
  }
}

I know it is not ideal to instantiate a class inside another class, it creates coupling, but how would you solve it?

I was thinking about setCommand(SendEmailCommand $sendEmailCommand) instead of the easier setCommand(Command $command) but it adds more complexity on the client code than benefits IMO.

mercredi 13 décembre 2023

How to set fields for an object based the object circumstances, without relying on boolean flags?

We have a huge object which sets one by one a lot of fields. However, we've come to a point where we set 3 flags in order to create it based on what we need, which break clean code rules. Basically it looks something like this:

method(boolean flag1, boolean flag2, boolean flag3){
    if (flag1){
        field1 = customValue1;
    }
    if (flag2){
        field2 = customValue2;
    }
    if (flag3){
        field3 = customValue3;
    }

How can I refactor this so it follows the standard (get rid of all the flags)?

Making a separate method for each case wouldn't be alright I think because I would have a LOT of code duplicates (this method has over 200 lines of code due to the number of fields and the way the business logic works in general). Then I thought of creating some sort of Supplier object for each possible case, but... just no. What are my options?

mercredi 6 décembre 2023

how to make logic for pattern "*" question in python

Make the pattern

*
**
***
****
*****

using loops in python

There is some problem in the logic of this for loop can u check and please tell

for i in range(0, 5):
     
        for j in range(0, i+1):
         
            print("* ",end=""
)
      
        print("\r")

mardi 5 décembre 2023

Dynamic BLoC Implementation Switching in Flutter Using Bloc Pattern and Custom Class Loader

I'm facing a challenge in designing a Flutter application with the BLoC state management pattern. The app is intended to be generic but used by multiple clients, some of whom have specific needs requiring customized versions of the main app.

To achieve this, I've implemented a custom class loader that dynamically loads either the default class or an overridden specific class. This applies not only to the app's main classes but also to BLoC implementations. For example, I have a StockBloc and an overridden version called SpeStockBloc. The registration of overridden classes happens at the beginning of the app using MyClassLoader()[StockBloc] = SpeStockBloc.new.

The issue arises when I attempt to consume the StockBloc in a view using context.watch<StockBloc>. Instead of recognizing the overridden SpeStockBloc, it looks for the exact StockBloc type in the widget tree. I understand that it's the correct behavior of Bloc and Provider.

I'm seeking advice or alternative approaches on how to dynamically switch between BLoC implementations at runtime while utilizing context.watch or a similar mechanism, ensuring it takes overridden types into account.

Any insights or suggestions on how to handle this scenario efficiently would be greatly appreciated.

Custom class loader :

/// Class to provide (if registered) a construction function that overrides
/// the initial construction for the [Type] used as a parameter
class DynamicClassLoader {
  final Map<Type, Function> _mappedClasses = <Type, Function>{};

  static final DynamicClassLoader _instance = DynamicClassLoader._internal();

  /// Singleton factory
  factory DynamicClassLoader() {
    return _instance;
  }

  DynamicClassLoader._internal();

  /// Checks if a specific class is registered
  bool hasOverride(Type type) =>
      _mappedClasses.containsKey(type) && _mappedClasses[type] != null;

  /// Access operator for a construction function of an instance of type [type]
  Function? operator [](Type type) {
    return _mappedClasses[type];
  }

  /// Obtains an instantiation function for the overridden class
  Function newInstantiation(Type type, Function fallback) =>
      hasOverride(type) ? this[type]! : fallback;

  /// Assignment operator for a construction method for a type [type]
  void operator []=(Type type, Function func) {
    _mappedClasses.update(
      type,
      (
        Function value,
      ) =>
          func,
      ifAbsent: () => func,
    );
  }
}

/// Access function to the method [DynamicClassLoader.newInstantiation]
Function newInstantiation<Class>(Function fallback) =>
    _newInstantiation(Class, fallback);

Function _newInstantiation(Type type, Function fallback) =>
    DynamicClassLoader().newInstantiation(type, fallback);

Stock bloc :

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:meta/meta.dart';
import 'package:test_bloc/class_loader.dart';

class StockBloc extends Bloc<StockEvent, StockState> {
  /// factory
  factory StockBloc({required int myCustomParam}) =>
      newInstantiation<StockBloc>(StockBloc.std)(myCustomParam: myCustomParam);

  StockBloc.std() : super(StockInitial()) {
    on<StockEvent>((event, emit) {
      // TODO: implement event handler
    });
  }
}

@immutable
class StockEvent {}

@immutable
sealed class StockState {}

final class StockInitial extends StockState {}

spe stock bloc :

import '../stock_bloc.dart';

class SpeStockBloc extends StockBloc {
  SpeStockBloc() : super.std() {
    on<StockEvent>((event, emit) {
      // TODO: implement event handler
    });
  }
}

sub_cmp :

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:test_bloc/bloc/bloc/stock_bloc.dart';

class SubCmp extends StatelessWidget {
  const SubCmp({super.key});

  @override
  Widget build(BuildContext context) {
    StockState bloc = context.watch<StockBloc>().state;

    return const Text("Sub cmp");
  }
}

main :

import 'package:flutter/material.dart';
import 'package:test_bloc/bloc/bloc/bloc/spe_stock_bloc.dart';
import 'package:test_bloc/bloc/bloc/stock_bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:test_bloc/class_loader.dart';
import 'package:test_bloc/sub_cmp.dart';

void main() {
  runApp(
    const MyApp(),
  );
}

void registerSpe() {
  DynamicClassLoader()[StockBloc] = SpeStockBloc.new;
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: BlocProvider(
        create: (context) => StockBloc(myCustomParam: 10),
        child: const Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SubCmp(),
            ],
          ),
        ),
      ),
    );
  }
}


Modelling Gof Observer patterns in UML

I am modeling my project, which I will subsequently implement in Java, using UML. My project involves managing a gym. More specifically, I am currently modeling my GoF Observer diagram. By what I've understood, I can't allow my Graphic Controller, with the models (entity), correct me if I'm wrong. On the other hand, if I let my application controller to implement the Observer, how can I notify the graphic controller that an exercise changed his status? Here I put my two ideas: enter image description here enter image description here

lundi 4 décembre 2023

How do I create a pattern using an array? [closed]

I have to create a pattern using an array, but I have no idea what to do. Class videos aren't helpful, if someone could please help me with this i'd appreciate it.

The pattern I need to make looks like this: Xs patterned to look like C++ logo

I honestly don't know what I'm supposed to do to make this work, we didn't go over arrays in depth and it has to be an array for me to recieve the grade. There's a few more patterns I have to make but I think if i figure this out I'll be able to do those on my own. A visual example of how the code should look would be incredibly helpful.

DB calls in FluentValidator class in DDD implemetation

We are implementing DDD in our project and we are using fluent for data validation.

FluentDataValidation class has some service calls(like diff db calls and AD call) for validating data.

Is this valid in DDD design to have service layer called from Validator class?

        public PublicValidator(IMetadataService metadataService)
    {
        this.When(status => status.IsStatusInComplete(), () =>
        {
            this.RulesWhenStatusIsInComplete(metadataService);
        })
        .Otherwise(() =>
        {
            this.RulesWhenStatusIsOtherThanIncomplete(metadataService);
        });

        this.RuleFor(s => s.Employers)
        .Must((r, p) => !r.people())
        .WithMessage(PeopleMessages.Dates);

        this.When(s => s.Employers != null && s.Employers.Count > 0 && !s.HasDefault, () =>
        {
            this.RuleForEach(s => s.Employers).ChildRules(a =>
            {
                a.RuleFor(s => s.Einperp)
                .NotEmpty()
                .Must(o => (metadataService.GetEmployerByEinperp(o) != null))
                .WithMessage(Constants.IncorrectMetadata);}

Security flow diagram to protect confidential information for external user

I am working on a POC to create flow diagram to secure protected data for external user. We are planning to work on market place where external user will login via external application and paired with a group they belong to. Once pairing is completed between external user and group then as a next step external user can call an api to see all the information associated with the paired group. We needs to impose an security that external user is calling api using same external application once pairing happen. External user can be associated with multiple external application and raise pairing request with same group using market place.

  1. There are application to application interaction.
  2. External user login on market place through external system. It’s a user interface where all the user can login if they have credential.
  3. After successfully login user can see list of group associated with logged in user.
  4. User can select group using market place ui and raise a pairing request.
  5. Once pairing is done then user is authorized to call group api to see detail of that group.
  6. All the external user will call these api using a external application.
  7. As a security we need to validate external user is calling group api using same external system once they raised pairing request on market place.

dimanche 3 décembre 2023

Composability: Iterator vs Lambda

I am having trouble understanding the concept of 'good' functional composability. Assume the following approaches for deleting files with a specific extension:

Using Lambda functions:

def traverse_tree(
        temp_storage: Local, extensions: List[str], is_raw: bool, operation: Callable
):
    for folder_path, subfolders, filenames in os.walk(temp_storage.root_path(is_raw)):
        for filename in filenames:
            base, ext = os.path.splitext(filename)
            if ext in extensions:
                file_path = os.path.join(folder_path, filename)
                operation(file_path)

def clear_temp(
        temp_storage, extensions: List[str], is_raw
):
    traverse_tree(temp_storage=temp_storage, extensions=extensions, is_raw=True, operation=lambda x: os.remove(x))

Using an iterator:

def traverse_tree(
        temp_storage, extensions: List[str], is_raw
):
    for folder_path, subfolders, filenames in os.walk(temp_storage.root_path(is_raw)):
        for filename in filenames:
            base, ext = os.path.split(filename)
            if ext in extensions:
                file_path = os.path.join(folder_path, filename)
                yield file_path


def clear_temp(
        temp_storage: Local, extensions: List[str], is_raw: bool
):
    for path in traverse_tree(temp_storage, extensions, is_raw):
        os.remove(path)

Is one approach favored over the other in terms of modularity and ease of debugging? If so, can you give an example where one approach objectively results in less flexibility?

Thanks,

samedi 2 décembre 2023

Design Method for Separating Retry Logic from Transaction Scope

I encountered an 'org.hibernate.AssertionFailure' error in my test for a specific logic.
ERROR 56862 --- [pool-3-thread-9] org.hibernate.AssertionFailure : HHH000099: an assertion failure occurred (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in ... entry (don't flush the Session after an exception occurs)

The issue arises when a data race condition leads to a Constraint Violation Exception due to the 'longUrl' being a unique column. In this scenario

  1. the first committed transaction context returns its 'shortUrl'
  2. while the other failing contexts should find and return the committed entity.
@Transactional
public String
getShortUrl(String longUrl) {
    UrlEntity   url;
    try {
        // Create Entity For Id
        url = this.db.findUrlEntityByLongUrl(longUrl).orElseGet(
                () -> this.db.save(new UrlEntity(longUrl)));
        
        String shortUrl = this.generator.encode(url.getId());
        url.setShortUrl(shortUrl);
        this.db.save(url);
    } catch (DataIntegrityViolationException e) {
        //  if Conflict return after find
        url = this.db.findUrlEntityByLongUrl(longUrl).get();
        if (url.getShortUrl() != null) return url.getShortUrl();
        url.setShortUrl(this.generator.encode(url.getId()));
    }

    return url.getShortUrl();
}

Based on my understanding, exceptions occurring within the scope of a transaction trigger a rollback, rendering the session unstable. In this context, I am attempting to perform entity retrieval using this unstable session :(

How should I approach the design? I am concerned that managing try-catch blocks at the controller level might shift part of the business logic to the controller, which seems inappropriate.

Is there a suitable design pattern for this situation?

What the way for transferring data to the factory classes?

I want to understand how best to pass data to factory classes

Hello!

Situation:

1)I have a class with records for orders. For example, class Order

2)Separately, I create a factory (simple factory) and different classes for conducting transactions, depending on the type of orders. Orders has 3 types and the realization of the transaction is different for each type:

$transactionFactory = new TransactionFactory();
$transaction = $transactionFactory::create($typeOrder); //creating Class FirstType, Class SecondType{} etc...

And in the end I have 2 classes for types of order: Class FirstType{}, SecondType{} implements some interface and etc...

Question: best way to pass 3-4 order's parameters (like type of transaction, amount...)

$transaction->setAmount(343);
$transaction->setBlahBlah(qwq);

or to constructor

$transactionFactory = new TransactionFactory();
$transaction = $transactionFactory::create($typeOrder, $amount, $blahblah, $foo, $bar); 

or

$transactionFactory = new TransactionFactory();
$transaction = $transactionFactory::create($orderID); 

to the factory's class constructor or pass the order id and make a select to db for get information about order in the Class FirstType, SecondType again?

What is the best way to pass parameters - pass all the necessary data from outside into the parameters or pass $orderId and re-receive the data in factory methods (this is an additional query to the database)?

vendredi 1 décembre 2023

C++: Pointer vs. Reference Design Question

Background

I constantly struggle with when to use pointers versus references in good software design. I'm hoping an example taken from the code I'm writing will help me solidify best practices through peoples' answers.

I have the following classes. Assume public getters for all fields that return the same type as the fields are declared with. For reasons I'd rather not get into, know that I also cannot easily combine the geometry and node classes. Also, ignore the fact that pointers are raw pointers. That's just for simplicity in the example.

// A 2D point
class Point {
private:
    double _x;
    double _y;
};

// A 2D edge. Edges refer to any trapezoids above and below themselves.
class Edge {
private:
    Point* _point1;
    Point* _point2;
    Trapezoid* _above;
    Trapezoid* _below;
};

// A 2d Trapezoid. Trapezoids refer to their place in the tree structure
class Trapezoid {
private:
    Point* _left;
    Point* _right;
    Edge* _top;
    Edge* _bottom;
    TrapezoidNode* _graphNode;
};

// Abstract Node
class Node {
protected:
    Node* _leftChild;
    Node* _rightChild;
};

// Node representing a point
class PointNode : public Node {
private:
    Point* _point;
};

// Node representing an edge
class EdgeNode : public Node {
private:
    Edge* _edge;
};

// Node representing a trapezoid
class TrapezoidNode : public Node {
private:
    Trapezoid* _trap;
};

The algorithm I'm writing takes in a starting Trapezoid and initializes a tree structure with a single TrapezoidNode representing that trapezoid. It also stores that Trapezoid in an unordered_set so that I can easily know what trapezoids exist in the tree at any point in time. From there, I begin breaking down nodes in the tree, replacing them with smaller subtrees consisting of PointNodes, EdgeNodes, and TrapezoidNodes. This process involves the creation of new Points, Edges, and Trapezoids that those nodes refer to. I also keep the unordered_set up-to-date with any new trapezoids that get created.

Key Questions

  1. For the Edge and Trapezoid classes, would it make more sense to use references to Points and Edges (respectively) instead of pointers?

    • The main problem is the lifetime of some of these objects. There are some edges whose life extends beyond that of the trapezoids they become a part of. This suggests the use of pointers, since the trapezoid does not own those edges. Other edges, however, are created for the sole purpose of creating a new trapezoid with limited lifetime. This suggests the use of references, since the lifetime of these edges are tied to the trapezoid that contains them.
  2. For my set of trapezoids, it better design to:

    • A) Use an unordered_set<Trapezoid> and make sure when I create TrapezoidNodes, that I am pointing to the heap memory managed by that set... or

    • B) Manually allocate heap memory for new Trapezoids and use an unordered_set<Trapezoid*> (which requires me to write a hashing function for Trapezoid* instead of Trapezoid

As shown above, my current implementation is to use pointers everywhere.

Move the logic to separate handlers

I have the helper class which translate list TreeField structures to some generic type, and I have a problem with initializing the fields. More precisely, I want to put the logic for each type into separate handlers so that I can add them without changing the logic of ExpressionHelper itself.

What exactly i wanna separate.

var propertyType = property.PropertyType;

if (propertyType.IsPrimitive || propertyType == typeof(string))
{
    var memberExpression = Expression.Property(parameter, property.Name);

    var bind = Expression.Bind(property, memberExpression);

    bindings.Add(bind);
}
else if (type.IsClass)
{
    var memberExpression = Expression.Property(parameter, property.Name);

    var subFieldsInit = GetMemberInitExpression(property.PropertyType, memberExpression, field.Children);

    var bind = Expression.Bind(property, subFieldsInit);

    bindings.Add(bind);
}
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
    var elementType = property.PropertyType
        .GetGenericArguments()
        .FirstOrDefault() ?? throw new InvalidOperationException($"Generic type for collection {property.Name} not founded.");

    var selectMethod = typeof(Enumerable).GetMethods()
        .Where(m => m.Name == nameof(Enumerable.Select))
        .First(m => m.GetParameters().Length == 2)
        .MakeGenericMethod(elementType, elementType);

    var lambdaParameter = Expression.Parameter(elementType);

    var lambdaBody = GetMemberInitExpression(elementType, lambdaParameter, field.Children);

    var selectLambda = Expression.Lambda(lambdaBody, lambdaParameter);

    var memberAccess = Expression.Property(parameter, property);

    var call = Expression.Call(selectMethod, memberAccess, selectLambda);

    var bind = Expression.Bind(property, call);

    bindings.Add(bind);
}

Is there any pattern that fits my situation or should I structure the code differently? All other code.

public readonly struct TreeField(string name, IEnumerable<TreeField> children)
{
    public required string Name { get; init; } = name ?? string.Empty;

    public IEnumerable<TreeField> Children { get; init; } = children ?? Enumerable.Empty<TreeField>();
}

public sealed class ExpressionHelper
{
    public Expression<Func<TEntity, TEntity>> GetLambdaExpression<TEntity>(IEnumerable<TreeField> fields)
    {
        var parameter = Expression.Parameter(typeof(TEntity));

        var result = GetMemberInitExpression(typeof(TEntity), parameter, fields);

        return Expression.Lambda<Func<TEntity, TEntity>>(result, parameter);
    }

    private MemberInitExpression GetMemberInitExpression(Type type, Expression parameter, IEnumerable<TreeField> fields)
    {
        var bindings = new List<MemberBinding>();

        foreach (var field in fields)
        {
            var property = type.GetProperty(field.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

            if (property is not null)
            {
                var propertyType = property.PropertyType;

                if (propertyType.IsPrimitive || propertyType == typeof(string))
                {
                    var memberExpression = Expression.Property(parameter, property.Name);

                    var bind = Expression.Bind(property, memberExpression);

                    bindings.Add(bind);
                }
                else if (type.IsClass)
                {
                    var memberExpression = Expression.Property(parameter, property.Name);

                    var subFieldsInit = GetMemberInitExpression(property.PropertyType, memberExpression, field.Children);

                    var bind = Expression.Bind(property, subFieldsInit);

                    bindings.Add(bind);
                }
                else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
                {
                    var elementType = property.PropertyType
                        .GetGenericArguments()
                        .FirstOrDefault() ?? throw new InvalidOperationException($"Generic type for collection {property.Name} not founded.");

                    var selectMethod = typeof(Enumerable).GetMethods()
                        .Where(m => m.Name == nameof(Enumerable.Select))
                        .First(m => m.GetParameters().Length == 2)
                        .MakeGenericMethod(elementType, elementType);

                    var lambdaParameter = Expression.Parameter(elementType);

                    var lambdaBody = GetMemberInitExpression(elementType, lambdaParameter, field.Children);

                    var selectLambda = Expression.Lambda(lambdaBody, lambdaParameter);

                    var memberAccess = Expression.Property(parameter, property);

                    var call = Expression.Call(selectMethod, memberAccess, selectLambda);

                    var bind = Expression.Bind(property, call);

                    bindings.Add(bind);
                }
            }
        }

        return Expression.MemberInit(Expression.New(type), bindings);
    }
}

I tried to do this with something like a strategy pattern. But I had a problem with passing

Func<Type, Expression, IEnumerable<TreeField>, MemberInitExpression> memberInit 

into the strategy.

public sealed class BindingContext : IBindingContext
{
    private readonly IEnumerable<IBindingStrategy> strategies;

    public BindingContext(IEnumerable<IBindingStrategy> strategies)
    {
        this.strategies = strategies;
    }

    public MemberBinding Bind(PropertyInfo property, Expression parameter, TreeField field, Func<Type, Expression, IEnumerable<TreeField>, MemberInitExpression> memberInit)
    {
        var strategy = strategies.FirstOrDefault(s => s.AppliesTo(property.PropertyType))
            ?? throw new NullReferenceException($"Binding startegy for {property.PropertyType} not registered.");

        return strategy.Bind(property, parameter, field, memberInit);
    }
}
public sealed class EntityStrategy : IBindingStrategy
{
    public bool AppliesTo(Type type) => type.IsClass && type != typeof(string);

    public MemberBinding Bind(PropertyInfo property, Expression parameter, TreeField field, Func<Type, Expression, IEnumerable<TreeField>, MemberInitExpression> memberInit)
    {
        var memberExpression = Expression.Property(parameter, property.Name);

        var subFieldsInit = memberInit(property.PropertyType, memberExpression, field.Children);

        return Expression.Bind(property, subFieldsInit);
    }
}

What are the Best Practices for Managing Height in Mobile Web with CSS [closed]

What are the CSS standards and best practices for ensuring a mobile web page occupies the entire screen without requiring scrolling? How do these guidelines differ in the context of a PWA application where the presence of an address bar is not anticipated?

Typically, I employ 'height: 100vh' in the body or the main div of my Vue.js components to fill the entire viewport. However, I am unsure if this is the correct practice, as various sources provide differents solutions when I seek answers.