spO0q
Posted on October 13, 2022
Here are data structures or programming tricks beginners usually have difficulties to understand or that remain quite misknown by devs.
Disclaimer
This is not exhaustive and only a personal selection.
What are exclusive OR conditions?
xor
is a logical operator implemented in programming languages like PHP to handle a specific case.
It remains quite unused/misknown, though, but, in simple English, xor
means "either that or that, but not both."
In PHP, you can do the following:
if ($distance > 8 xor $time_spent > 30) {
// some code
}
The condition is TRUE
only if one of the operands evaluates to TRUE
, but not both.
What is Bitwise XOR?
Another common use of XOR is for bitwise operations, with the ^
symbol.
In Python, you can use it this way:
a = 19
b = 3
x = a ^ b
print(x) # 16
Why the heck do we get 16?
a = 19 => 10011
b = 3 => 11
a ^ b => 10000 => 16
^
performs the operation on the binary representation of the numbers.
Besides, we get an integer because we provided two integers as input. If you compare booleans, XOR returns a boolean value.
What is the Decorator pattern?
You can modify objects' behavior by wrapping them with decorators that implement specific behaviors.
It's helpful to prevent bloat in original code, but also in other structures that rely on the same code (e.g., clients).
Decorators usually implement the same interface:
<?php
interface Product
{
public function price();
}
class Laptop implements Product
{
public function price () {
return 700;
}
}
class Sticker implements Product
{
private $unit;
public function __construct (Product $unit) {
$this->unit = $unit;
}
public function price () {
return $this->unit->price() + 42;
}
}
class StickerDev implements Product
{
private $unit;
public function __construct (Product $unit) {
$this->unit = $unit;
}
public function price () {
return $this->unit->price() + 50;
}
}
$laptop = new Laptop();
$sticker = new Sticker($laptop);
$stickerDev = new StickerDev($sticker);
echo $stickerDev->price(); // 792
Singleton or not?
You get access to a unique instance globally.
It's often used in code to "protect" the access to a shared resource (e.g., a database connection).
It might be also convenient to get it everywhere without using global variables that can be overwritten by any part of the code.
The constructor must be private to prevent additional instances with the new
keyword.
Another method is created to save the object into a static attribute that will be returned.
Here's a typical example:
<?php
class MySingleton {
private static $instance = null;
private function __construct() {}
public static function getInstance()
{
if (self::$instance == null) {
self::$instance = new MySingleton();
}
return self::$instance;
}
public function __clone() {
throw new Exception("Don't even try to clone me!");
}
}
$sin = MySingleton::getInstance();
print_r($sin);
Note that we prevent anyone from cloning our Singleton by using the magic method __clone()
.
It should be noted that many devs consider the Singleton as an anti-pattern that does not respect the single Responsibility principle and is harder to test.
Use it carefully and discuss it with your teammates, if you're not sure.
Why do people say composition is better than inheritance?
Inheritance is probably the most intuitive technique when it comes to reuse code.
The big caveat is that it can become hard to maintain quickly, as you will likely have to overwrite elements in child classes.
Besides, as parent properties and methods are accessible in child classes, it's easy to break the encapsulation principle.
In the worst-case scenario, you might end up modifying the "super mother class" (~ the one at the top of the inheritance chain) to add features, which could break many other areas that depend on the same base.
It does not mean any code that use inheritance is bad, but you can't use it everywhere, as not everything can be represented as a parent-child relationship.
In Go, for example, you can't even use inheritance and extend elements directly. You have to compose them, for example, using structs:
package main
import (
"fmt"
)
type RST interface {
Test()
}
type UVW interface {
RST
}
type Compo struct{}
func (z Compo) Test() {
fmt.Println("Test Compo")
}
func Demo(x UVW) {
x.Test()
}
type XYZ struct {
Compo
}
func main() {
test := XYZ{}
Demo(test)
}
Composition allows combining objects and other types at will, and modify behaviors at runtime.
Wrap up
I hope you learned a couple of things with these practical examples.
Posted on October 13, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.