设计模式六大原则(一)

单一职责原则(Single Responsibility Principle,缩写SRP)

  • 定义:应该有且仅有一个原因引起类的变更(There should never be more than one reason for a class to change),一个类应该是一组高度相关的函数、数据的封装

实例

<?php


namespace DesignModel;


/**
 * Class TestClass
 * @package DesignModel
 */
class TestSimpleCalculateClass
{
    /**
     * 计算面积
     * @param $param
     * @return int
     */
    public function calculateArea(int $param)
    {
        if (empty($param)) {
            return 0;
        }

        // 计算过程暴露,如果计算方式复杂则代码量很多,容易影响其他类型面积计算
        $roundnessArea = ceil($param * 2 * pi());
        $squareArea = $param * $param;

        // 返回圆形和正方形的面积
        return compact('roundnessArea', 'squareArea');
    }
}

/**
 * Class TestClass
 * @package DesignModel
 */
class TestCalculateClass
{
    /**
     * 计算面积
     * @param $param
     * @return int
     */
    public function calculateArea(int $param)
    {
        if (empty($param)) {
            return 0;
        }

        $roundnessArea = round($param * 2 * pi());
        $squareArea = $param * $param;

        // 返回圆形和正方形的面积
        return compact('roundnessArea', 'squareArea');
    }
}

/**
 * Interface IDealNumeric
 * @package DesignModel
 */
interface IDealNumeric
{
    /**
     * @param int $param
     * @return mixed
     */
    public function calculateArea(int $param);
}

/**
 * 计算圆形面积
 * Class SingleNumericClass
 * @package DesignModel
 */
class SingleRoundnessClass implements IDealNumeric
{
    /**
     * @param int $param
     * @return int
     */
    public function calculateArea(int $param)
    {
        // TODO: Implement dealNumeric() method.
    }
}

/**
 * 计算正方形面积
 * Class SingleStringClass
 * @package DesignModel
 */
class SingleSquareClass implements IDealNumeric
{
    /**
     * @param int $param
     * @return string
     */
    public function calculateArea(int $param)
    {
        // TODO: Implement dealString() method.
    }
}

/**
 * Class SingleTestClass
 * @package DesignModel
 */
class SingleTestClass
{
    public function calculateArea(int $param)
    {
        $roundnessArea = (new SingleRoundnessClass())->calculateArea($param);
        $squareArea = (new SingleSquareClass())->calculateArea($param);

        // 返回圆形和正方形的面积,不关心内部实现逻辑
        return compact('roundnessArea', 'squareArea');
    }
}

开闭原则(Open Close Principle,缩写OCP)

设计模式的总纲

<?php


namespace Factory\SimpleFactory;


/**
 * Class ModelToCalculatePrice
 * @package Factory\SimpleFactory
 */
class ModelToCalculatePrice
{
    /**
     * 这种方式写的时候很简单,但是如果以后增加类型或者计算逻辑变更,代码量会很多,并且容易混乱
     * 比如计算价格时需要根据会员等级计算折扣,就需要方法中增加参数
     * @param string $type
     * @param int $count
     * @return float|int
     */
    public function calculatePrice(string $type, int $count)
    {
        if ($type === 'vip') {
            $price = $count * 10;
        } else {
            $price = $count * 20;
        }

        return $price;
    }
}

/* ==================== 以下为优化后代码 ==================== */

/**
 * Class CalculatePrice
 * @package Factory\SimpleFactory
 */
abstract class CalculatePrice
{
    /**
     * 定义实现方法
     * @param $count
     * @return mixed
     */
    abstract function calculate($count);
}

/**
 * Class User
 * @package Factory\SimpleFactory
 */
abstract class User
{

}

/**
 * Class VipUser
 * @package Factory\SimpleFactory
 */
class VipUser extends User
{
    /**
     * @var
     */
    protected $integral;

    /**
     * @return mixed
     */
    public function getIntegral()
    {
        return $this->integral;
    }
}

/**
 * Class VipCalculatePrice
 * @package Factory\SimpleFactory
 */
class VipCalculatePrice extends CalculatePrice
{
    /**
     * @var VipUser
     */
    protected $vipUser;

    /**
     * VipCalculatePrice constructor.
     * @param VipUser $vipUser
     */
    public function __construct(VipUser $vipUser)
    {
        $this->vipUser = $vipUser;
    }

    /**
     * 实现计算
     * @param $count
     * @return float|int|mixed
     */
    function calculate($count)
    {
        if ($this->vipUser->getIntegral() > 0 && $this->vipUser->getIntegral() < 40) {
            return $count * 10;
        } else {
            return $count * 8;
        }
    }
}

/**
 * Class SvipCalculatePrice
 * @package Factory\SimpleFactory
 */
class SvipCalculatePrice extends CalculatePrice
{
    /**
     * 可以看到,不同子类都需要实现计算方法,但是内部实现逻辑可以不同,且没有耦合
     * @param $count
     * @return float|int|mixed
     */
    function calculate($count)
    {
        return $count * 5;
    }
}

/**
 * Class commonCalculatePrice
 * @package Factory\SimpleFactory
 */
class commonCalculatePrice extends CalculatePrice
{
    /**
     * @param $count
     * @return float|int|mixed
     */
    function calculate($count)
    {
        return $count * 20;
    }
}

里氏替换原则(Liskov Substitution Principle,缩写LSP)

<?php


namespace Factory\ReplaceModel;


/**
 * Class User
 * @package Factory\SimpleFactory
 */
abstract class User
{

}


/**
 * Class VipUser
 * @package Factory\SimpleFactory
 */
class VipUser extends User
{
    /**
     * @var
     */
    protected $integral;

    /**
     * @return mixed
     */
    public function getIntegral()
    {
        return $this->integral;
    }
}

/**
 * Class CalculatePrice
 * @package Factory\SimpleFactory
 */
abstract class CalculatePrice
{
    /**
     * @var User
     */
    protected $user;

    /**
     * CalculatePrice constructor.
     * @param User $user
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * 定义实现方法
     * @param $count
     * @return mixed
     */
    abstract function calculate($count);
}


/**
 * Class VipCalculatePrice
 * @package Factory\SimpleFactory
 */
class VipCalculatePrice extends CalculatePrice
{
    /**
     * 实现计算
     * @param $count
     * @return float|int|mixed
     */
    function calculate($count)
    {
        // 有子类出现的地方父类未必就可以出现
        if ($this->user->getIntegral() > 0 && $this->user->getIntegral() < 40) {
            return $count * 10;
        } else {
            return $count * 8;
        }
    }
}

// 任何父类出现的地方,子类都能实现
$vipCalculatePrice = new VipCalculatePrice(new VipUser());
$vipCalculatePrice->calculate(12);
posted @ 2019-09-17 08:20  itabel  阅读(514)  评论(0编辑  收藏  举报