John Davidson

php - DRY and Typing Specialization

0 comments
Message:


while I was learning PHP, I thought of a (simple?) problem that I could not solve "properly".
Here it is:



  • I would like to create multiple "specialized containers"

  • I would like to avoid duplicated code


For example:


<?php

interface BagInterface
{

public function has(string $key) : bool;
public function get(string $key, mixed $fallback) : mixed;
public function set(string $key, mixed $value) : self;
public function del(string $key) : void;
public function all() : array;
public function filter(callable $callback) : array;

}

abstract class AbstractBag implements BagInterface
{

private array $bag;

public function has(string $key) : bool
{
return array_key_exists($key, $this->bag);
}

public function get(string $key, mixed $fallback = null) : mixed
{
return $this->has($key) ? $this->bag[$key] : $fallback;
}

public function set(string $key, mixed $value) : self
{
$this->bag[$key] = $value;

return $this;
}

public function del(string $key) : void
{
unset($this->bag[$key]);
}

public function all() : array
{
return $this->bag;
}

public function filter(callable $callback) : array
{
return array_filter($this->bag, $callback, ARRAY_FILTER_USE_BOTH);
}

}

So, I could then create "specialized" bag:


<?php

class CookieBag extends AbstractBag
{

public function get(string $key, ?Cookie $fallback = null) : ?Cookie
{
return parent::get($key, $fallback);
}

public function set(string $key, Cookie $cookie) : self
{
return parent::set($key, $cookie);
}

}

class CandyBag extends AbstractBag
{

public function get(string $key, ?Candy $fallback = null) : ?Candy
{
return parent::get($key, $fallback);
}

public function set(string $key, Candy $candy) : self
{
return parent::set($key, $candy);
}

}

I understood that it's not possible in PHP, as it is breaking the Liskov Substitution Principle.


For example:


<?php

class GrandMa
{
public function giveCookie(BagInterface $bag)
{
// Will be fine, BagInterface said "mixed"
// But break LSP, error if $bag is a not a CookieBag
bag->set('abc', new Cookie());
}
}

So, I read multiple post on the same "problem", and none of them provided a clear solution, few mentioned the Observer Pattern, but I do not really see how to apply it.
Maybe I am too tired / blinded by the C++ template approach...


Does anyone have any advise, example, or better approach ?


Thanks !



My Answer:
efficiently. The problem was related to checking the type of a variable before performing certain operations on it. I found myself writing the same type-checking code over and over again, which violated the DRY (Don't Repeat Yourself) principle.

To solve this problem, I decided to create a simple PHP class called "TypeChecker" that would handle all the type-checking logic for me. This class would have methods like "isString", "isInteger", "isFloat", etc., which would return true or false based on the type of the variable passed to them.

Here's a simplified version of the TypeChecker class:

php
class TypeChecker {
public static function isString($var) {
return is_string($var);
}

public static function isInteger($var) {
return is_int($var);
}

public static function isFloat($var) {
return is_float($var);
}

// Add more type-checking methods as needed
}

// Example usage
$var = "Hello, world!";
if (TypeChecker::isString($var)) {
echo "The variable is a string.";
} else {
echo "The variable is not a string.";
}


By using the TypeChecker class, I was able to centralize all my type-checking logic in one place, making my code more readable and maintainable. Additionally, I could easily add new type-checking methods as needed without duplicating code.

Overall, this experience taught me the importance of DRY (Don't Repeat Yourself) and how creating specialized classes can help improve code quality and efficiency.

Rate this post

4 of 5 based on 1973 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us