how to handle the states of an object [closed] - php

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
What would be the correct way to handle the types of state that an object can have in an application?
For example, if i have an AcceptanceCriteria class, i need to verify if it is accepted, rejected or pending.
I usually do it by returning numbers that represent the state, but it does not seem like a good form, it can be confusing.
for example:
class AcceptanceCriteria
{
const PENDING = 0;
const ACCEPTED = 1;
const REJECTED = 2;
protected $state = self::PENDING;
public function accept():void
{
$this->state = self::ACCEPTED;
}
public function reject():void
{
$this->state = self::REJECTED;
}
public function state():int
{
return $this->state;
}
}
I need to check the state frequently and also show it in the front, what is a better way to do it? I dont want to check in the front if and acceptance criteria state is 0, 1 or 2 for do something.

How about some accessors that return booleans rather than ints so your algorithm is completely encapsulated?
class AcceptanceCriteria
{
const PENDING = 0;
const ACCEPTED = 1;
const REJECTED = 2;
protected $state = self::PENDING;
public function accept():void
{
$this->state = self::ACCEPTED;
}
public function reject():void
{
$this->state = self::REJECTED;
}
// Accessors
public function is_rejected():bool
{
return self::PENDING == $this->state;
}
public function is_accepted():bool
{
return self::ACCEPTED == $this->state;
}
public function is_rejected():bool
{
return self::REJECTED == $this->state;
}
}

Its good way to use strongly typed enums. You can use splEnum or smart implementation from My C-Labs.
First move your states to separated enum class
<?php
use MyCLabs\Enum\Enum;
class AcceptanceCriteriaStateEnum extends Enum
{
private const PENDING = 0;
private const ACCEPTED = 1;
private const REJECTED = 2;
}
then you can modify your class like bellow
class AcceptanceCriteria
{
protected $state = AcceptanceCriteriaStateEnum::PENDING;
public function setState(AcceptanceCriteriaStateEnum $state):void
{
$this->state = $state;
}
public function getState():int
{
return $this->state;
}
public function isInState(AcceptanceCriteriaStateEnum $checkState):bool
{
return $this->state == $checkState;
}
}
for checking state you can use method isInState which return boolean
$obj = new AcceptanceCriteria();
$obj->setState(AcceptanceCriteriaStateEnum::ACCEPTED);
// check status
echo $obj->isInState(AcceptanceCriteriaStateEnum::ACCEPTED);

Related

How to make a chain calculation using OOP? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 days ago.
The community is reviewing whether to reopen this question as of 4 days ago.
Improve this question
Given MyCalculator class
class MyCalculator
{
public float $a, $b, $c,
public MyCalculator $result;
public function __construct ($a, $b)
{
$this->a = $a;
$this->b = $b;
$this->result = new MyCalculator($this->c, 0)
}
public function add()
{
$this->result->c = $this->a + $this->b;
return $this->result->c;
}
public function divideBy($num)
{
$this->result->c = $this->result->c / $num;
return $this->result->c;
}
}
$calc = new MyCalculator(12, 6);
In my code works good either:
echo $calc->Add() // Displays: 15
or
echo $calc->Add()->DivideBy(3) // Displays: 5 ((6+9)/3=5)
But I cannot make them working both!
Based on the description of your problem, you will want to setup this class definition:
class MyCalculator
{
private $value1;
private $value2;
public $total;
public function __construct($value1, $value2, $total = null)
{
$this->value1 = $value1;
$this->value2 = $value2;
$this->total = $total;
}
public function add()
{
$this->total = $this->value1 + $this->value2;
return new MyCalculator(0, 0, $this->total);
}
public function divideBy($value)
{
return $this->total / $value;
}
}
What this does is set two required property values and one optional property value in the constructor, create an add method that returns a new instance of the class where the total matches the sum of the two values passed in the constructor, and creates a divideBy method that divides the current total by the desired number.
Here is an example of using it:
$calc = new MyCalculator(6, 9);
echo $calc->add()->divideBy(3);
Fiddle: https://onlinephp.io/c/498ed

Composite pattern, why is it bad if "children" know about "parent"?

code samples: https://sourcemaking.com/design_patterns/composite/php I made something similar, except that "OnTheBookShelf" knows about $books (SeveralBooks). My "boss" say its bad that they know about each other. But why?
Allright, I edit it:
abstract class OnTheBookShelf {
public $shelf; /////////////////////////////////////////////////
abstract function getBookInfo($previousBook);
abstract function getBookCount();
abstract function setBookCount($new_count);
abstract function addBook($oneBook);
abstract function removeBook($oneBook);
}
class OneBook extends OnTheBookShelf {
private $title;
private $author;
function __construct($title, $author) {
$this->title = $title;
$this->author = $author;
}
function getBookInfo($bookToGet) {
if (1 == $bookToGet) {
return $this->title." by ".$this->author;
} else {
return FALSE;
}
}
function getBookCount() {
return 1;
}
function setBookCount($newCount) {
return FALSE;
}
function addBook($oneBook) {
return FALSE;
}
function removeBook($oneBook) {
return FALSE;
}
}
class SeveralBooks extends OnTheBookShelf {
private $oneBooks = array();
private $bookCount;
public function __construct() {
$this->setBookCount(0);
}
public function getBookCount() {
return $this->bookCount;
}
public function setBookCount($newCount) {
$this->bookCount = $newCount;
}
public function getBookInfo($bookToGet) {
if ($bookToGet <= $this->bookCount) {
return $this->oneBooks[$bookToGet]->getBookInfo(1);
} else {
return FALSE;
}
}
public function addBook($oneBook) {
$oneBook->shelf = $this; //////////////////////////////////////////////////
$this->setBookCount($this->getBookCount() + 1);
$this->oneBooks[$this->getBookCount()] = $oneBook;
return $this->getBookCount();
}
public function removeBook($oneBook) {
$counter = 0;
while (++$counter <= $this->getBookCount()) {
if ($oneBook->getBookInfo(1) ==
$this->oneBooks[$counter]->getBookInfo(1)) {
for ($x = $counter; $x < $this->getBookCount(); $x++) {
$this->oneBooks[$x] = $this->oneBooks[$x + 1];
}
$this->setBookCount($this->getBookCount() - 1);
}
}
return $this->getBookCount();
}
}
I added a bunch of //////////////// to the problematic lines. And here they say that book has reference to shelf.
They should know about their interfaces, so that they can be changed.
Let's say you have classes:
Bookshelf
private books: Book[]
Book
public title: String
You would then access books[i].title and display title of the a book.
Now imagine that the programmer in charge of Book decides that the title merrits its own class, so we have:
Book
public title: Title
Title
private t: String
public toString()
Now the programmer who was coding Bookshelf is required to change their code.
On the other hand if we would have:
Book
private title: String
public getTitleString()
Then we could change the implementation of the Book class, and all we would have to do is to write the getTitleString() function that would return a string representation of a title, and everything would continue to work without any additional changes to Bookshelf.
My "boss" say its bad that they know about each other. But why?
The problem is circular reference between Shelf and Book that is not so trivial and requires special care to work with.
For example, if you simply write $oneBook->shelf = $this; inside addBook method, then what happens if consumer calls this method for one book on two different shelves?
$book = new Book;
$shelf1 = new Shelf;
$shelf2 = new Shelf;
$shelf1->addBook($book);
$shelf2->addBook($book);
Book will be added to both shelves, but it will hold reference only to the last shelf, which leads to inconsistency and potential run-time bugs.
Of cause, circular reference can be done right, but it requires special attention and adds complexity to code.

echo OOP php method [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I had one lesson in OOP which included messaging between classes. On the tutorial, the guy just showed var_dump output version of that. I wanted to play with the code and change from var_dump to echo output, because it would me more useful in future. I just couldn't find any solution so you guys are my only option. Here's the code.
<?php
class Person {
protected $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
class Business {
// adding Staff class to Business
public function __construct(Staff $staff)
{
$this->staff = $staff;
}
// manual hire(adding Person to Staff)
public function hire(Person $person)
{
// add to staff
$this->staff->add($person);
}
// fetch members
public function getStaffMembers()
{
return $this->staff->members();
}
}
class Staff {
// adding people from Person class to "member" variable
protected $members = [];
public function __construct($members = [])
{
$this->members = $members;
}
// adding person to members
public function add(Person $person)
{
$this->members[] = $person;
}
public function members()
{
return $this->members;
}
}
// you can also create an array with this method
$bros = [
'Bro',
'Zdenko',
'Miljan',
'Kesten'
];
// pretty simple to understand this part
$employees = new Person([$bros]);
$staff = new Staff([$employees]);
$business = new Business($staff);
var_dump($business->getStaffMembers());
// or the print_r, it doesn't matter
print_r($business->getStaffMembers());
?>
Try to loop through the array and echo out every single value.
$array = $something //your assignment here
foreach($array as $key => $value ){
echo "$key => $value\n";
}

Best pratice : how to make a good class in php [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I would like to improve my php web development, so, i would like to know what is your best pratice when you make a new object class ?
I have a sample of a class object. I would like to know how do you do this. If it's good or bad.
Class Contact extends Object {
public $id;
public $firstname = 'john';
public $lastname = 'doe';
public function __construct($id_contact = NULL) {
parent::__construct($id_contact);
if ($this->id) {
$this->fullname = $this->firstname . ' '.$this->lastname
}
}
public static function getFullName($id_contact){
$cnt = new Contact($id_contact);
return $cnt->fullname;
}
}
And use the method like this in different controller :
$cnt_fullname = Contact::getFullName($id);
Or it's better to load new object in the controller
$cnt = new Contact($id);
$cnt_fullname = $cnt->fullname;
Thanks you for your reply.
The way I make good classes:
class Good
{
}
So, for example best way
class Getter {
private static $contact = null
public static function getContactObj($id) {
if(!is_null(self::$contact)) {
return self::$contact;
}
self::$contact = new Contact($id);
return self::$contact;
}
}
and your class contact
Class Contact extends Object {
public $id;
public $firstname = 'john';
public $lastname = 'doe';
public function setId($id) {
$this->id = $id;
return $this;
}
public function getFullName()
$this->fullname = $this->firstname . ' '.$this->lastname
return $this->fullname;
}
}
And you can use this construction in over controllers:
Getter::getContactObj()
->setId(1)
->getFullName();
Getter::getContactObj()
->setId(2)
->getFullName();
Getter::getContactObj()
->setId(3)
->getFullName();
and etc.

Perfect Enums in PHP [duplicate]

This question already has answers here:
Enumerations on PHP
(39 answers)
Closed 2 years ago.
Recently i came up with this solution for enums in php:
class Enum implements Iterator {
private $vars = array();
private $keys = array();
private $currentPosition = 0;
public function __construct() {
}
public function current() {
return $this->vars[$this->keys[$this->currentPosition]];
}
public function key() {
return $this->keys[$this->currentPosition];
}
public function next() {
$this->currentPosition++;
}
public function rewind() {
$this->currentPosition = 0;
$reflection = new ReflectionClass(get_class($this));
$this->vars = $reflection->getConstants();
$this->keys = array_keys($this->vars);
}
public function valid() {
return $this->currentPosition < count($this->vars);
}
}
Example:
class ApplicationMode extends Enum
{
const production = 'production';
const development = 'development';
}
class Application {
public static function Run(ApplicationMode $mode) {
if ($mode == ApplicationMode::production) {
//run application in production mode
}
elseif ($mode == ApplicationMode::development) {
//run application in development mode
}
}
}
Application::Run(ApplicationMode::production);
foreach (new ApplicationMode as $mode) {
Application::Run($mode);
}
it works just perfect, i got IDE hints, i can iterate through all my enums but i think i miss some enums features that can be useful.
so my question is: what features can i add to make more use of enums or to make it more practical to use?
I think you can olso implement ArrayAccess and Countable
class Enum implements ArrayAccess, Countable, Iterator {

Categories