Structural QA: Difference between revisions

From A Technological Wiki
Jump to navigation Jump to search
imported>Unknown user
No edit summary
No edit summary
 
(2 intermediate revisions by one other user not shown)
Line 16: Line 16:
A common structural problem in PHP is deeply nested code, which makes it difficult to read and maintain.
A common structural problem in PHP is deeply nested code, which makes it difficult to read and maintain.


<syntaxhighlight>// Bad practice:
<syntaxhighlight lang="php">// Bad practice:
if (condition1) {
if (condition1) {
     if (condition2) {
     if (condition2) {
Line 36: Line 36:
Rather than including or requiring files manually, use autoloaders to load classes automatically. This is a structural improvement that makes code more maintainable.
Rather than including or requiring files manually, use autoloaders to load classes automatically. This is a structural improvement that makes code more maintainable.


<syntaxhighlight>// Instead of this:
<syntaxhighlight lang="php">// Instead of this:
require 'User.php';
require 'User.php';
require 'Order.php';
require 'Order.php';
Line 49: Line 49:
Global variables can make code unpredictable and harder to maintain. Encapsulate your data and use dependency injection or pass them as arguments.
Global variables can make code unpredictable and harder to maintain. Encapsulate your data and use dependency injection or pass them as arguments.


<syntaxhighlight>// Avoid this:
<syntaxhighlight lang="php">// Avoid this:
global $database;
global $database;


Line 61: Line 61:
Coupling refers to the degree to which one class knows about another class. If classes are too dependent on each other, it results in tight coupling, making the system harder to modify.
Coupling refers to the degree to which one class knows about another class. If classes are too dependent on each other, it results in tight coupling, making the system harder to modify.


<syntaxhighlight>// bad
<syntaxhighlight lang="php">// bad
class Order {
class Order {
     public function calculateTotal() {
     public function calculateTotal() {
         $shipping = new Shipping();
         $shipping = new Shipping();
         return $this-&gt;subtotal + $shipping-&gt;calculate();
         return $this->subtotal + $shipping->calculate();
     }
     }
}
}
Line 74: Line 74:


     public function __construct(Shipping $shipping) {
     public function __construct(Shipping $shipping) {
         $this-&gt;shipping = $shipping;
         $this->shipping = $shipping;
     }
     }


     public function calculateTotal() {
     public function calculateTotal() {
         return $this-&gt;subtotal + $this-&gt;shipping-&gt;calculate();
         return $this->subtotal + $this->shipping->calculate();
     }
     }
}</syntaxhighlight>
}</syntaxhighlight>
Line 86: Line 86:
These are objects that know too much or do too much, essentially violating the Single Responsibility Principle (SRP). Breaking them down helps in making the system modular and maintainable.
These are objects that know too much or do too much, essentially violating the Single Responsibility Principle (SRP). Breaking them down helps in making the system modular and maintainable.


<syntaxhighlight>// Bad
<syntaxhighlight lang="php">// Bad
class System {
class System {
     public function authenticateUser() { /*...*/ }
     public function authenticateUser() { /*...*/ }
Line 114: Line 114:
Rather than hardcoding values, it's better to use configuration files or constants.
Rather than hardcoding values, it's better to use configuration files or constants.


<syntaxhighlight>// Bad
<syntaxhighlight lang="php">// Bad
function getConnection() {
function getConnection() {
     return new DatabaseConnection(&quot;localhost&quot;, &quot;root&quot;, &quot;password123&quot;);
     return new DatabaseConnection("localhost", "root", "password123");
}
}
// Better
// Better
Line 125: Line 125:
Not handling potential errors can lead to unexpected system crashes or bugs.
Not handling potential errors can lead to unexpected system crashes or bugs.


<syntaxhighlight>// Bad
<syntaxhighlight lang="php">// Bad
function divide($a, $b) {
function divide($a, $b) {
     return $a / $b;
     return $a / $b;
Line 132: Line 132:
function divide($a, $b) {
function divide($a, $b) {
     if ($b == 0) {
     if ($b == 0) {
         throw new DivisionByZeroException(&quot;Cannot divide by zero&quot;);
         throw new DivisionByZeroException("Cannot divide by zero");
     }
     }
     return $a / $b;
     return $a / $b;
Line 155: Line 155:


By focusing on structural quality assurance developers can ensure that their codebase remains maintainable, scalable, and less prone to bugs.
By focusing on structural quality assurance developers can ensure that their codebase remains maintainable, scalable, and less prone to bugs.
<!-- From bodyContent 1543044.mraw -->


[[Category:Quality Assurance definitions]]

Latest revision as of 17:25, 22 October 2025

Structural Quality Assurance is the process of evaluating the non-functional attributes of a software system, particularly focusing on how well it is structured internally. Unlike external quality (which deals with factors like usability, functionality, and reliability perceived by users), structural quality looks into the architecture, code, and components of the software.

Structural quality assurance aims to ensure that the software:

  • Is maintainable.
  • Can be efficiently scaled.
  • Is robust and does not have vulnerabilities.
  • Has an architecture that is both coherent and cohesive. To understand it better, think of a building: if the foundation, materials, and architectural design are sound, the building will be more durable and safe.

Examples of structural QA

Avoiding Deep Nesting

A common structural problem in PHP is deeply nested code, which makes it difficult to read and maintain.

// Bad practice:
if (condition1) {
    if (condition2) {
        if (condition3) {
            // Do something
        }
    }
}

// Improved practice:
if (!condition1) return;
if (!condition2) return;
if (condition3) {
    // Do something
}

Using Autoloaders

Rather than including or requiring files manually, use autoloaders to load classes automatically. This is a structural improvement that makes code more maintainable.

// Instead of this:
require 'User.php';
require 'Order.php';

// Use autoloading:
spl_autoload_register(function ($class_name) {
    include $class_name . '.php';
});

Avoiding Global Variables

Global variables can make code unpredictable and harder to maintain. Encapsulate your data and use dependency injection or pass them as arguments.

// Avoid this:
global $database;

// Instead, inject it:
function doSomething($database) {
    // ...
}

Tight Coupling

Coupling refers to the degree to which one class knows about another class. If classes are too dependent on each other, it results in tight coupling, making the system harder to modify.

// bad
class Order {
    public function calculateTotal() {
        $shipping = new Shipping();
        return $this->subtotal + $shipping->calculate();
    }
}

// Better
class Order {
    private $shipping;

    public function __construct(Shipping $shipping) {
        $this->shipping = $shipping;
    }

    public function calculateTotal() {
        return $this->subtotal + $this->shipping->calculate();
    }
}

God Objects

These are objects that know too much or do too much, essentially violating the Single Responsibility Principle (SRP). Breaking them down helps in making the system modular and maintainable.

// Bad
class System {
    public function authenticateUser() { /*...*/ }
    public function logError() { /*...*/ }
    public function sendEmail() { /*...*/ }
    // ... and many more unrelated methods.
}

Better: Split into distinct classes: UserAuthentication, ErrorLogger, EmailService, etc.

Cyclic Dependencies

Cyclic dependencies occur when two or more modules depend on each other, which makes the system hard to maintain and understand. Module A depends on Module B, and Module B depends on Module A.

Refactoring and re-architecting the system can help eliminate such cycles.

Lack of Modularization

Not breaking down the system into modular parts makes it hard to manage and extend.

For a web application, rather than having a single massive script handling everything, it's better to break down functionality into controllers, services, repositories, etc.

Hardcoding Values

Rather than hardcoding values, it's better to use configuration files or constants.

// Bad
function getConnection() {
    return new DatabaseConnection("localhost", "root", "password123");
}
// Better
Use configuration files or environment variables to store such values.

Lack of Error Handling

Not handling potential errors can lead to unexpected system crashes or bugs.

// Bad
function divide($a, $b) {
    return $a / $b;
}
// Better
function divide($a, $b) {
    if ($b == 0) {
        throw new DivisionByZeroException("Cannot divide by zero");
    }
    return $a / $b;
}

Tools for Structural Quality Assurance in PHP

PHP_CodeSniffer (PHPCS)

This tool checks your PHP code against certain coding standards. It can be used to ensure that your code adheres to popular coding standards such as PSR-12 or custom ones.

PHPStan

A static analysis tool for PHP that focuses on discovering bugs in your code. It can help identify type errors, unused variables, and much more.

PHPUnit

While primarily a testing framework, good test coverage with PHPUnit can be seen as a structural quality metric, ensuring that your code behaves as expected.

By focusing on structural quality assurance developers can ensure that their codebase remains maintainable, scalable, and less prone to bugs.