Sequencer handle as part of virtual sequence or virtual sequencer?

I am seeing two ways of implementing virtual sequences:

Method 1: sequencer handle inside virtual sequencer

  class v_sqr extends uvm_sequencer;
    sqrA aSqr;
    sqrB bSqr;
  endclass

  class v_seq extends uvm_sequence;
    `uvm_object_utils (v_seq)
    `uvm_declare_p_sequencer (v_sqr)
 
    function new (string name = "v_seq");
      super.new (name);
    endfunction
 
    seqA   aSeq;
    seqB   bSeq;
 
    task body();
      aSeq = seqA::type_id::create ("aSeq");
      bSeq = seqB::type_id::create ("bSeq");
      ...
      fork
        aSeq.start (p_sequencer.aSqr);
        bSeq.start (p_sequencer.bSqr);
      join 
      ...
    endtask
  endclass

  class myEnv extends uvm_env
  ..
  myAg1 ag1;
  myAg2 ag2;
  v_sqr sqrV;
  ..
  sqrV.aSqr = ag1.m_sequencer;
  sqrV.bSqr = ag2.m_sequencer;
  ..
  endclass

  class myTest extends uvm_test;
    `uvm_component_utils (myTest)
 
    myEnv   env;
     ...
     task run_phase (uvm_phase phase);
      v_seq seq = v_seq::type_id::create ("seq");
      phase.raise_objection (this);
      seq.start (env.sqrV);
      phase.drop_objection (this);
    endtask
  endclass

Method 2: sequencer handle inside virtual sequence and thus NO virtual sequencer required

 class v_seq extends uvm_sequence;
    `uvm_object_utils (v_seq)
    // no virtual sequencer
    // instead handle to sqr
    sqrA aSqr;
    sqrB bSqr;
 
    function new (string name = "v_seq");
      super.new (name);
    endfunction
 
    seqA   aSeq;
    seqB   bSeq;
 
    task body();
      aSeq = seqA::type_id::create ("aSeq");
      bSeq = seqB::type_id::create ("bSeq");
      ...
      fork
        aSeq.start (aSqr);
        bSeq.start (bSqr);
      join 
      ...
    endtask
  endclass

// env won't have virtual sequencer

  class myTest extends uvm_test;
    `uvm_component_utils (myTest)
 
    myEnv   env;
     ...
     task run_phase (uvm_phase phase);
      v_seq seq = v_seq::type_id::create ("seq");
      phase.raise_objection (this);
      // before starting seq assign sqr handles
      seq.aSqr = env.ag1.m_sequencer;
      seq.bSqr = env.ag2.m_sequencer;

      // start seq
      seq.start (null);
      phase.drop_objection (this);
    endtask
  endclass

Which is the suggested way and why?
As on immediate to me Method-1 looks okay as tests can be written by others who might not be aware of agents available in environment. It can simply call “seq.start (env.sqrV);” to make sequence run.

In reply to bhupesh.paliwal:

Both ways are possible. There is no benefit or disadvantage. Finally it is a question of your coding guidelines. You should follow one approach and do not mix both.

In reply to bhupesh.paliwal:

I prefer method 2 as it eliminates the need to create a virtual sequencer, and also gives greater flexibility when you run the sequence.

For example, if you have multiple agents that the virtual sequence can run sub-sequences on, it is easier to change the sequencer handle in the virtual sequence then create multiple virtual sequencers.