2017-08-19 8 views
0

私はオブジェクト指向プログラミングと機能プログラミングを学んでいます。私はあなたに10分でOOPを説明する、この非常に良い簡単な例を見つけました(あなたが良い例を知っていれば示唆してください)。など機能プログラミングを使用してこのコードを書く方法

DEMO.PHP 
<?php 
Include_once(“player.php”); 

$p1 = new player(); 
$p1->name = “Brutus”; 
$p1->type = “Warrior”; 
$p1->hitpoints = 100; 

$p2 = new player(); 
$p2->name = “Mysterio”; 
$p2->type = “Sorcerer”; 
$p2->hitpoints = 100; 

$p1->meleeAttack($p2); 
$p2->meleeAttack($p1); 

Echo “<h1> Fight Results</h1>”; 
Echo “<h2>.$p1->name.” now has “.$p1->hitpoints.” hit points</h2>”; 
Echo “<h2>.$p2->name.” now has “.$p2->hitpoints.” hit points</h2>”; 
?> 


PLAYER.PHP 
<?php 
Class player { 

    public $name; 
    public $type; 
    public $hitpoints; 
    public function meleeAttack($target){ 
     $current_hp = $target->hitpoints; // hp is for hitpoints 
     $damage = rand(10,20); 
     if($this->type == “Warrior”) {  // condition logic 
      $damage += 10; 
     } 
     $target->hitpoints = $current_hp - $damage; 
    } 
} 

?> 

乾杯、 P.S.何のループ再帰ない、不変性を持つ - 今 https://www.youtube.com/watch?v=4c4nP7GLL1c

、私は機能的な方法でこのコードを書く方法を学びたいです私はPHPを知らないので、私はHaskellを使用して、関数型プログラミングを行う方法を説明しますPHPは関数型プログラミングのための選択の言語、それを思い出させる必要はありません:)

+2

それほど大きな違いはありません。あなたは交換するループがありません。基本的には、 'meleeAttack'を2人のプレーヤーを引数とし、プレーヤーを変更するメソッドではなく、ヒットポイントを減らした新しいPlayerを返す関数にします。ランダムなダメージをどのように処理するかは、純粋な関数型言語を使用しているかどうかによって異なります。 – chepner

+0

私は理解していません、 "...新しいプレーヤーを返します..."の部分。古いプレイヤーはどうなりますか?どのプレイヤーが最新のプレイヤーであるかをプログラムはどのように知っていますか?私はコードを参照する必要があります:( – user3013157

+0

ラップされた属性を更新する代わりに、ヒットポイントが少ない以外は、既存のプレイヤーを同一の新しいオブジェクトに置き換えます。 'meleeAttack'はコピーコンストラクターのようになりますプレイヤー1がプレイヤー2を攻撃した場合、あなたは '$ p2 = meleeAttack($ p1、$ p2)'のようなものを書くでしょう。 – chepner

答えて

4

はありませんが、知っている:

import System.Random (randomRIO) 

-- Data Declarations 

data Class = Warrior | Sorcerer deriving Eq 

data Player = Player { name  :: String 
        , archetype :: Class 
        , hitpoints :: Int 
        } 

-- Example Data 

p1 :: Player 
p1 = Player "Brutus" Warrior 100 

p2 :: Player 
p2 = Player "Mysterio" Sorcerer 100 

-- Code Section 

meleeAttack :: Player -> Player -> IO Player 
source `meleeAttack` target = do 
    damage <- randomRIO (10, 20) 
    let bonus = if archetype source == Warrior then 10 else 0 
    let newHP = hitpoints target - damage - bonus 
    return target { hitpoints = newHP } 

-- Main Function 

main :: IO() 
main = do 
    p2 <- p1 `meleeAttack` p2 
    p1 <- p2 `meleeAttack` p1 
    putStrLn "Fight Results" 
    putStrLn (name p1 ++ " now has " ++ show (hitpoints p1) ++ " hitpoints") 
    putStrLn (name p2 ++ " now has " ++ show (hitpoints p2) ++ " hitpoints") 
オブジェクト指向プログラミング・コード及びデータで

  1. が別々に保たれない:

    申し分なく、オブジェクト指向プログラミングと関数型プログラミングの最大の違いのように一つはコードとデータの分離です。あなた自身のPlayerクラスを見てください。それには3つのパブリックフィールドと、それらのフィールドで動作するパブリックメソッドがあります。

  2. 関数プログラミングでは、コードとデータは別々に保持されます。私たちのデータ宣言はプログラムの始めにあり、そのデータで動作する関数はその後に来ます。

別の大きな違いは、変更可能性です。オブジェクト指向プログラミングでは、オブジェクトは通常変更可能です。したがって、メソッドは通常、既存のオブジェクトを変更します。関数型プログラミングでは、突然変異は悪いとみなされます。したがって、関数は通常何も変更しません。代わりに、彼らは操作していたデータの更新されたコピーを返します。

たとえば、meleeAttackの機能を考えてみましょう。 2つの入力、sourcetarget、どちらもPlayerデータです。出力もPlayerデータです。更新されたtargetです。元のtargetは変更されません。

機能プログラミングを学びたい場合は、Learn You A Haskellを読んでください。

+0

このHaskelコードは、クラス、オブジェクトのプロパティ、メソッドを使用してOOP形式で記述できますか?私の謝罪、私は勉強しています。OOPの比較を見たいのですがfunc。 – user3013157

+0

関数プログラミングでは、OOPの意味でオブジェクトを*持っていません。'Player'データ型はPHPクラスが追跡する状態をカプセル化しますが、与えられたオブジェクトを更新するメソッドの代わりに、関数の引数の変更を反映する* new *オブジェクトを返す関数を記述します。 – chepner

関連する問題