軟件開發1-IOC控制反轉

設計準則中的開閉原則,即無需修改任何一行程序代碼,將功能加入至原先的應用程序中,也可以在不修改任何程序的情況下移除。

某地區有各種不同的商店,每家商店都賣四種水果:蘋果十元一個、香蕉二十元一個、橘子三十元一個、西瓜四十元一個,顧客可以在任意商店進行購買,每家商店需要可以隨時向稅務局提供總銷售額。

    class Shop
    {
        // 商店的名字
        private $name;

        // 商店的總銷售額
        private $turnover = 0;

        public function __construct($name){
            $this->name = $name;
        }

        // 售賣商品
        public function sell($commodity){
            switch ($commodity){
                case 'apple':
                    $this->turnover += 10;
                    echo "賣出一個蘋果<br/>";
                    break;
                case 'banana':
                    $this->turnover += 20;
                    echo "賣出一個香蕉<br/>";
                    break;
                case 'orange':
                    $this->turnover += 30;
                    echo "賣出一個橘子<br/>";
                    break;
                case 'watermelon':
                    $this->turnover += 40;
                    echo "賣出一個西瓜<br/>";
                    break;
            }
        }
        // 顯示商店目前的總銷售額
        public function getTurnover(){
            echo $this->name.'目前爲止的銷售額爲:'.$this->turnover;
        }
    }

    // 顧客類
    class Human
    {
        //從商店購買商品
        public function buy(Shop $shop,$commodity){
            $shop->sell($commodity);
        }
    }

    // new一個名爲kfc的商店
    $kfc = new Shop('kfc');
    // new一個名爲mike的顧客
    $mike = new Human();

    // mike從kfc買了一個蘋果
    $mike->buy($kfc,'apple');
    // mike從kfc買了一個香蕉
    $mike->buy($kfc,'banana');

    // 輸出kfc的總營業額
    echo $kfc->getTurnover();

可以看到,雖然代碼完成了對目前需求的實現,但是此時的 shell() 方法依賴於具體的實踐並且擁有絕對的控制權。一旦我們需要在商店加入一個新的商品,比如芒果mango,那我們不得不去修改商店類的 sell() 方法,違反了 OCP 原則,即對擴展開放,對修改關閉

    abstract class Fruit
    {
        public $name;
        public $price;
    }
    class Shop
    {
        //商店的名字
        private $name;

        //商店的總銷售額
        private $turnover = 0;

        public function __construct($name){
            $this->name = $name;
        }

        //售賣商品
        public function sell(Fruit $commodity){
            $this->turnover += $commodity->price;
            echo '賣出一個'.$commodity->name.',收入'.$commodity->price."元<br/>";
        }

        //顯示商店目前的總銷售額
        public function getTurnover(){
            echo $this->name.'目前爲止的銷售額爲:'.$this->turnover;
        }
    }

    //顧客類
    class Human
    {
        //從商店購買商品
        public function buy(Shop $shop,$commodity){
            $shop->sell($commodity);
        }
    }

    class Apple extends Fruit
    {
        public $name = 'apple';
        public $price = 10;
    }
    class Bananae extends Fruit
    {
        public $name = 'banana';
        public $price = 20;
    }
    class Orange extends Fruit
    {
        public $name = 'orange';
        public $price = 30;
    }
    class Watermelon extends Fruit
    {
        public $name = 'watermelon';
        public $price = 40;
    }

    //new一個名爲kfc的商店
    $kfc = new Shop('kfc');
    //new一個名爲mike的顧客
    $mike = new Human();

    //mike從kfc買了一個蘋果
    $mike->buy($kfc,new Apple());
    //mike從kfc買了一個香蕉
    $mike->buy($kfc,new Bananae());

    //輸出kfc的總營業額
    echo $kfc->getTurnover();

採用依賴注入可以快速進行代碼擴展,

    class Lemon extends Fruit
    {
        public $name = 'Lemon';
        public $price = 50;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章