Първи стъпки в OOP

Jorko

Registered
Тъи като незнам какво ме прихвана тая вече викам чакай и аз да опитам

та написах си един прост клас за събиране на 2 числа от нулата даже и не съм гледал в интернет като ми вадеше малко грешки от общи познания и проба грешка...

и въпросът ми тук е да ме насочите ако подхождам грешно към някой неща да ги оправя и така нататък някъкви съвети :)

PHP:
<?php
	class A{
		public $a;
		public $b;
		public $v;
		public $error=array();
		
		public function __construct() {}
		
		public function smetni($argument1,$argument2){
			$this->a = $argument1;
			$this->b = $argument2;
			if(!is_numeric($this->a)){
				$this->error['1'] = "Chislo_a trqbwa da e cifra";
			}
			if(!is_numeric($this->b)){
				$this->error['2'] = "Chislo_b trqbwa da e cifra";
			}
			$this->v = $this->a+$this->b;
		}
		public function output(){
			if(count($this->error) == 0){
				echo $this->v;
			}else{
				print_r($this->error);
			}
		}
	
	}
	
	$aha = new A();
	if(isset($_POST['smetni'])){
		$aha->smetni($_POST['chislo_a'],$_POST['chislo_b']);
	}
?>
<form action="" method="post" >
<input type="text" name="chislo_a" size="1" />
+
<input type="text" name="chislo_b" size="1" />

<input type="submit" name="smetni" value="smetni" />
</form>
=<?php if(isset($_POST['smetni'])){
	$aha->output();
}?>
 
Jorko каза:
не съм гледал в интернет като ми вадеше малко грешки от общи познания и проба грешка...

Учиш нещо ново без да гледаш от никъде. Лоша идея. Иначе сам си си отговорил. Гледай в интернет, не казвам, че всичките уроци са перфектни, но има какво да се научи от тях.

Разгледй принципите на ОО като цяло и разбери за какво се ползваа и кога. Това са моите насоки. : )))

Cheers,
Ив'
 
Сега когато създаваш свойства във класа и не смяташ тези свойства да се променят извън рамките на класа им задавай private или protected - ако ще ги ползваш и във клас, който ще го extend - ваш, това важи и за методите.

Имам предвид това:

PHP:
                public $a;

		public $b;

		public $v;

		public $error = array();

Става на:

PHP:
                private $a;

		private $b;

		private $v;

		private $error = array();


Следва констуктора, попринцип не е задължително да го викаш, той се вика автоматично при инстанциране на класа, както и де-конструктора (по - същата логика). Него може да го ползваш като директно "инжектираш" във класа информацията, вместо да ползваш set/get методите за да прехвъряш информация, също така се ползва и за автоматично стартиране на методи или общо взето казано за съставянето на централната логика, как ще работи класа, каква ще е неговата цел.



PHP:
$Class = new test();
$Class -> SetParams('something');

Може да го напишеш:

PHP:
new test('something');

А ето какво ще ти представлява класа:

PHP:
class test {

public function __construct($param) {
       $this->SetParams($param);
}

}

По този начин тъй като конструктора се вика първи, ти му предаваш параметри и зареждаш метода SetParams() със информацията която му е предадена.

Следва:

PHP:
$this->a = $argument1;
$this->b = $argument2;

От това няма смисъл в случая ти ги ползваш само във един метод, няма смисъл да ги прехвъряш тези променливи, работи си със тях във метода и след това резултата ги прехвърли на едно свойство и във метода за показване го зареди. Ако ги ползваш и във друг метод, това ги прехвърляш.

------------

Как би изглеждал твоя код:

PHP:
<?php

class A {

    private $param = null;
    private $param2 = null;
    private $Result = null;
    private $Error = array();

    public function __construct($num = '', $num2 = '') {
        $this->param = $num;
        $this->param2 = $num2;

        if($this->_CheckParam() == true) {
                $this->_SetParam();
          }
    }

    private function _SetParam() {

        $this->Result = $this->param + $this->param2;
    }

    private function _CheckParam() {


        if ($this->param == '' || !is_numeric($this->param)) {
            $this->Error[] = 'This is <b>' . $this->param . '</b> is not numeric, or is empty';
        }


        if ($this->param2 == '' || !is_numeric($this->param2)) {
            $this->Error[] = 'The is <b>' . $this->param2 . '</b> is not numeric, or is empty';
        }

        if (count($this->Error) > 0) {
            return false;
        }


        return true;
    }

    public function Output() {
        if (count($this->Error) > 0) {

            foreach ($this->Error as $Error) {
                echo $Error . '<br />';
            }

            return false;
        }

        echo $this->Result;
        return true;
    }

}

if (isset($_POST['smetni'])) {

    $aha = new A($_POST['chislo_a'], $_POST['chislo_b']);
}
?>

<form action="" method="post" >

    <input type="text" name="chislo_a" size="1" />

    +

    <input type="text" name="chislo_b" size="1" />



    <input type="submit" name="smetni" value="smetni" />

</form>


<?php
if (isset($aha)) {
    $aha->Output();
}
?>

Виждаш как вкарваме информация през конструктора, така кода става по изчистен. Отделно във конструктора стартираме метода, който ще проверява дали въведените параметри са валидни, ако са валидни, се извиква метода, който ще ни ги събере, ако са невалидни ще ни върне false и всичко приключва.

После извикваме метода Output, той проверява дали има въведени грешки, ако има ги показва, ако няма ни показва резултата.

Сега този код може да се напише, като числата се предават през методите като обикновени параметри, а не като свойства на класа, не е грешка. Конкретно във този пример няма значение как ги предаваш, свойствата се ползват на места, където е възможно даден метод изобщо да няма връзка със друг метод за да се предат параметрите, тогава сетваме свойства и така предаваме.

Във твоя код, ти си писал във един метод няколко действия: валидация и смятане. Не е грешка, но е хубаво всеки метод да си знае за какво е създаден, така както всеки клас е с точно определена цел, така и методите трябва да са, така както и различните уеб страници във интернет са с точно определена целтака и методите трябва да са. Специално във този случай, не е проблем дали ще е във един метод или във 100 разделени, но след като почнеш да пишеш някой по сериозен клас, ще стигнеш до момента, че ще се налага дадено нещо, примерно някаква валидация да е ползваш 2 пъти във 2 различни метода, какво ще направиш тогава - copy / paste, тоест дублираш кода и окау, работи. Но това не е нужно .. избягвай дублирането на код. За да го избегнеш това създаваш един метод, който отговаря само на валидацията и нищо друго. И когато ти потрябва го извикваш от всякъде.
 
Разгледай за видео уроци. Там има хитринки който е трудно да ти ги опиша в писмен вид. Също се вижда на практика.

Започни с типове класове, как се разширяват, как се имплементират.
Клас данните какъв "обхват" имат / private, public protected ....

Без да гледаш уроци трудно.
Към кода ти по-горе съм сигурен 99% , че можеш да пропуснеш конструктора и да ползваш този който е поподразбиране в PHP
 
Така тоя клас беше пример но като го загледам можеше просто да си декларирам една функция която се пише на 4 реда благодаря на отзовали те се eddy93 +1 най добро обяснение
 
Виж сега, това може всякак да се напише, важното тук е правилно как да се структурират нещата, така че кода да стане по четлив, да се избегнат дублиращите неща, по лесен също така и за тестване на различните компоненти от код (ако се ползва DI, имам една пусната тема във форума може да е намериш, там за първи път се запознах със Dependency Injection, много полезно нещо) и друго също така от части кода става по - оптимизиран (примерно за singleton шаблона + db connection, някой array map, който ще носи някакви създадени обекти или резултати от тях, а не всеки път да ги извикваме и др. подобни примери, няма да ги разглеждам във детайли), шаблони има много.

OOP не е до това да напишеш един клас за смятане.

Има много различни мнения за това как правилно да се структура един код, тази тема може да продължи много дълго.
 
eddyy93 каза:
Виж сега, това може всякак да се напише, важното тук е правилно как да се структурират нещата, така че кода да стане по четлив, да се избегнат дублиращите неща, по лесен също така и за тестване на различните компоненти от код (ако се ползва DI, имам една пусната тема във форума може да е намериш, там за първи път се запознах със Dependency Injection, много полезно нещо) и друго също така от части кода става по - оптимизиран (примерно за singleton шаблона + db connection, някой array map, който ще носи някакви създадени обекти, а не всеки път да ги извикваме и др. подобни примери, няма да ги разглеждам във детайли).

OOP не е до това да напишеш един клас за смятане.

Има много различни мнения за това как правилно да се структура един код, тази тема може да продължи много дълго.
Одобрявам ! :)
+ Това си има общо приети стандарти.
1) Клас данните да се намират над всички методи.Реално можеш да ги бутнеш и в "дъното" на класа. Пак същата работа. Но няма да е прегледно.
2) Гърбицата на камилата за имена на променливи и методи.
Методите започват с главна буква, а променливите с малка.
Всяка дума в в името започва с главна буква :
CalcSumFromDb();
totalSumFromDb ;
3) Конструктора най-отгоре, де-конструктора и toString най-отдолу, заедно с магическите методи.
4) Името на класа да съвпада с името на файла ( изключения винаги има...)
 

Back
Горе