PHP接口允许在接口中定义常量,例如

interface FooBar

{

const FOO = 1;

const BAR = 2;

}

echo FooBar::FOO; // 1

任何实现类都会自动提供这些常量,例如

class MyFooBar implement FooBar

{

}

echo MyFooBar::FOO; // 1

我个人认为,全球都是邪恶的。但是我想知道接口常数是否也一样。鉴于一般认为对接口进行编码是一种好习惯,使用接口常量是否是在类上下文之外可以接受的唯一常量?

尽管我很好奇您的个人意见以及是否使用接口常量,但我主要是在寻找答案的客观原因。我不希望这成为投票类型的问题。我对使用接口常量对可维护性有什么影响很感兴趣。耦合。或单元测试。它与SOLID PHP有何关系?它违反任何被认为是PHP良好实践的编码原则吗?你明白了...

注意:Java也有一个类似的问题,其中列出了一些非常好的理由来说明它们是"不良实践"的原因,但是由于Java不是PHP,因此我有理由再次在PHP标签中提出问题。

嗯,我以前从未遇到过在接口中定义常量的需求。 值得一提的是,实现该接口的类不能覆盖常量,而仅相互扩展的类可以覆盖常量。

我相信常数也不错,因为即使我们关注单元可测试性,它们也具有可预测的值。 全局变量是邪恶的,因为任何人都可以更改它,因为它是一个变量并且所有内容都具有作用域,但常量永远不会更改其值,因此,术语"常量"。

好吧,我认为这归结为好与好之间的区别。

虽然在大多数情况下,可以通过实现其他模式(策略或轻量级)来避免使用常量,但是可以说不需要用其他六类来表示一个概念。我认为其归结为需要其他常量的可能性。换句话说,需要扩展接口上的常量所提供的ENUM。如果可以预见需要扩展它,那么可以使用更正式的模式。如果不是,那么就足够了(足够好了,因此编写和测试的代码更少了)。这是一个足够好和不好使用的示例:

坏:

interface User {

const TYPE_ADMINISTRATOR = 1;

const TYPE_USER          = 2;

const TYPE_GUEST         = 3;

}

够好了:

interface HTTPRequest_1_1 {

const TYPE_CONNECT = 'connect';

const TYPE_DELETE  = 'delete';

const TYPE_GET     = 'get';

const TYPE_HEAD    = 'head';

const TYPE_OPTIONS = 'options';

const TYPE_POST    = 'post';

const TYPE_PUT     = 'put';

public function getType();

}

现在,我选择这些示例的原因很简单。 User接口正在定义用户类型的枚举。随着时间的流逝,这很可能会扩展,并且更适合于其他模式。但是HTTPRequest_1_1是一个不错的用例,因为枚举是由RFC2616定义的,并且在类的生存期内不会更改。

总的来说,我不认为常量和类常量的问题是一个全局问题。我将其视为依赖性问题。这是一个狭窄的区别,但却是一个明确的区别。我认为全局问题就像未强制执行的全局变量一样,因此会产生软的全局依赖关系。但是硬编码的类会创建强制的依赖关系,因此会创建硬的全局依赖关系。因此,两者都是依赖关系。但是我认为全局会更糟糕,因为它没有被强制执行。这就是为什么我不喜欢将类依赖与全局依赖放在一起。

如果编写MyClass::FOO,则将硬编码到MyClass的实现细节。这会产生硬耦合,从而使代码的灵活性降低,因此应避免使用。但是,存在接口以完全允许这种类型的耦合。因此MyInterface::FOO不会引入任何具体的耦合。话虽如此,我不会仅仅为了向接口添加常量而引入接口。

因此,如果您正在使用接口,并且非常确定自己(或其他任何人)不需要其他值,那么我就不会真正看到接口常数有什么大问题了……最好设计将不包含任何常量或条件,幻数,幻弦或硬编码的任何内容。但是,这会增加开发时间,因为您必须考虑其用途。我的观点是,多数时候绝对值得花额外的时间来构建出色的实体设计。但是有时候确实足够好是可以接受的(需要有经验的开发人员来了解差异),在那种情况下就可以了。

再次,那只是我的看法...

在这种情况下,您会建议用户采取什么其他模式?

@Jacob:我会把它抽象化。根据您的需求,Id可能会构建一个Access类,该类将从数据库表中获取其数据。这样,添加新级别就像插入新行一样容易。另一种选择是建立一个ENUM类集(每个权限角色都有一个类)。然后,您可以在必要时扩展类以提供适当的权限。但是还有其他方法也可以使用

非常扎实和明确的答案! +1

具有公共常量的类不应具有任何方法。它应该只是数据结构或对象,而不是两者。

@OZ_:好吧,这取决于使用情况。如果您要构建ENUM样式类,则应具有与强制执行约束有关的方法(例如SPLEnum)。如果您不这样做,而您只是表示一个可能改变的值的域(以消除幻数和字符串),那么无论是否仅是类,它都将悬而未决。它实际上取决于类和常量的原因。所以不,我不同意带有公共常量的类不应该有方法。我通常会把它们放在一个接口上,但这取决于

"最好的设计不会包含任何常数或条件,幻数或幻弦或硬编码的任何东西。" - 这听起来很不错。您如何避免有条件的决定,这是任何决策过程的核心?

@FrederikKrautwald:您可以避免多态的条件(在大多数情况下):查看此答案以及观看此清洁代码讲座...

@ircmaxell,感谢您的链接。我同意通过重构条件,在大多数情况下可以消除条件。但是,我看不到如何完全避免它们,但这也许只是我缺乏逻辑。

@FrederikKrautwald,您无法完全避免它们。您可以在业务逻辑中完全避免它们。在工厂,制造商和配置逻辑中,它们仍然是必需的,但是实际的"业务工作"可以是完全有条件的……我不是说应该是完全免费的,但是可以。

@ircmaxell,很好。这也是我得出的结论,我不会再为解决如何删除所有和一个问题而费劲。

@ircmaxell我有两个问题:1."最好的设计不会包含任何常量..."那么当拥有10个具有相同字符串的文件时,您将如何管理,您是否要进行单点更改? 2."实际的"业务工作"可以是完全无条件的.."您是否将核心域称为业务工作(实体/价值对象等)。如果是这样,您是否建议使用数组等?如果是这样,我们如何实现规格和验证器?

我认为通常最好将常量(特别是枚举常量)作为接口中的单独类型("类")来处理:

define(TYPE_CONNECT, 'connect');

define(TYPE_DELETE , 'delete');

define(TYPE_GET    , 'get');

define(TYPE_HEAD   , 'head');

define(TYPE_OPTIONS, 'options');

define(TYPE_POST   , 'post');

define(TYPE_PUT    , 'put');

interface IFoo

{

function /* int */ readSomething();

function /* void */ ExecuteSomething(/* int */ param);

}

class CBar implements IFoo

{

function /* int */ readSomething() { ...}

function /* void */ ExecuteSomething(/* int */ param) { ... }

}

或者,如果您想使用一个类作为名称空间:

class TypeHTTP_Enums

{

const TYPE_CONNECT = 'connect';

const TYPE_DELETE  = 'delete';

const TYPE_GET     = 'get';

const TYPE_HEAD    = 'head';

const TYPE_OPTIONS = 'options';

const TYPE_POST    = 'post';

const TYPE_PUT     = 'put';

}

interface IFoo

{

function /* int */ readSomething();

function /* void */ ExecuteSomething(/* int */ param);

}

class CBar implements IFoo

{

function /* int */ readSomething() { ...}

function /* void */ ExecuteSomething(/* int */ param) { ... }

}

并不是说您仅使用常量,而是使用枚举值或枚举的概念,这些枚举值或枚举被认为是具有特定用法("域"?)的特定类型。

Php 接口能定义常量,关于php:接口常量的优点和缺点相关推荐

  1. C#高级编程——C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)——图文详解加源码

    C#高级编程--C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)--图文详解加源码 前言

  2. php 接口的定义与实现,PHP接口定义与用法示例

    使用接口(interface),你可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容.我们可以通过interface来定义一个接口,就像定义一个标准的类一样,但其中定义所有的方法都是空的. ...

  3. 天籁obd接口针脚定义_典藏 | OBD接口位置大全及部分常用手机型号语音播报设置流程...

    OBD接口的位置 OBD接口的位置一般都在方向盘下方的内饰板中,靠近驾驶员膝盖附近的地方,不同车型的位置稍有区别,但基本位置都差不多. OBD接口统一采用梯形的16针DLC形式接插件,梯形接口是防误插 ...

  4. 天籁obd接口针脚定义_汽车OBD接口定义

    ELM327 用到的引脚: 2: SAE-J1850 PWM 和 SAE-1850 VPW 总线 (+) 4. 车身地 5. 信号地 6. CAN high (ISO 15765-4 和 SAE-J2 ...

  5. 定义一个动物类java_Java问题利用接口继承完成对生物、动物、人三个接口的定义,其中生物接口定义呼吸抽象方法,动物接口定义了吃饭和睡觉两个抽...

    共回答了11个问题采纳率:100% Organisms.java; public interface Organisms { public abstract void breathe(); } --- ...

  6. Java接口的定义与实现

    普通类:只有具体实现 抽象类:具体实现和规范(抽象方法)都有! 接口:只有规范 接口就是规范,定义的是一组规则,体现了现实世界中"如果你是..你必须能.."的思想,如果你是汽车你必 ...

  7. java 接口 属性_浅谈java接口中定义属性

    package com.supan.reflact; public interface PersonObject { /** * 在接口中定义属性的知识点: * 1,属性默认的修饰词是:public ...

  8. 片上总线Wishbone 学习(四)接口信号定义

    片上总线Wishbone 学习(四)接口信号定义 所有的Wishbone接口信号都是高电平有效,设计成高电平有效的主要原因是由于低电平有效信号的书写问题,不同的设计者表达低电平有效信号的方式不同,拿最 ...

  9. rj45 千兆接口定义_RJ45接口针脚定义(各种接口针脚定义)

    下面是 [RJ45接口针脚定义(各种接口针脚定义)]的电路图 RJ45接口信号定义,以及网线连接头信号安排 以太网 10/100Base-T 接口: Pin Name Description 1 TX ...

  10. 硬件接口引脚定义(持续更新)

    英文各类硬件接口定义网站:https://pinouts.ru/conn/ 1.SATA接口引脚定义 2.mSATA接口引脚定义 3.各类USB接口引脚定义 引脚 功能 接线颜色 备注 1 VCC 红 ...

最新文章

  1. IT服务台的进化(3)--虚拟服务台
  2. java ruby脚本_Java 程序中直接执行 Ruby 脚本 (JRuby)
  3. Linux容器间共享内存,C++容器模板在共享内存中的使用
  4. C语言 指针与结构体
  5. Oracle数据库通过创建触发器实现自增功能
  6. uniapp canvas生成海报不显示问题
  7. react中定时器的应用_在离子React电容器应用中实施admob
  8. Ubuntu 远程控制(使用自带远程工具)
  9. 如何修改 SQL Server 中的实例名 ?
  10. [小白向]Python使用request库调用API并获取返回的JSON数据包中的内容
  11. Tensorflow 源码编译笔记(C++/C层)
  12. 垂直搜索引擎的关键技术
  13. iphone下拉菜单卡住了_苹果手机怎么下拉菜单 苹果x右上角下拉失灵怎么办
  14. Codeforces 1087 - 题集
  15. Codeforces: TMT Document
  16. Mac 系统option键的妙用
  17. Linux安装Docker并配置Docker镜像加速,daemon.json完整配置详解
  18. 学习WooCommerce跨境电商社交媒体营销
  19. POJ 1253:Dungeon Master
  20. G - Godsend CodeForces - 841B

热门文章

  1. 政务服务中心工作人员是公务员吗?
  2. Ansys-施加非法向表面载荷实例-转矩的施加学习收获
  3. 什么是缺陷清除率、缺陷率和缺陷密度
  4. 吴恩达-coursera-机器学习测试题第四周
  5. 虎课网计算机二级百度云资源,计算机二级Word篇-实操真题详解20
  6. Office365专业增强版安装步骤
  7. 7.Hive性能优化及Hive3新特性
  8. 1.5 二极管 Diode
  9. 微信小程序背景图片设置和图片自适应宽高
  10. 前端网址转二维码实现