replace

Replace Parameter with Explicit Methods (以明确函数取代参数

人盡茶涼 提交于 2020-03-02 03:08:57
Summary : 你有一个函数,其中完全取决于参数值而采取不同行为。 针对该参数的每一个可能值,建立一个独立函数。 动机: Replace Parameter with Explicit Methods 恰恰相反于 Parameterize Method 。如果某个参数有很多种可能的值,而函数内又以条件表达式检查这些参数值,并根据不同参数值做出不同的行为,那么就应该使用本项重构。调用者原本必须赋予参数适当的值,以决定该函数做出何种响应。现在既然你提供了不同的函数给调用者私用,就可以避免出现条件表达式。此外你还可以获得编译期检查的好处,而且接口也更清楚。如果以参数值决定函数行为,那么函数用户不但需要观察该函数,而且还要判断参数值是否合法,而“合法的参数值”往往很少在文档中被清楚地提出。 就算不考虑编译器检查的好处,只是为了 获得一个清晰的接口,也值得你执行本项重构。哪怕只是给一个内部的布尔变量赋值,相较之下, Witch.beOn() 也比 Switch.setState(true) 要清晰得多。 但是,如果参数值不会对函数行为有太多影响,你就不应该使用 Replace Parameter with Explicit Methods 。如果情况真这样,而你也只需要通过参数为一个字段赋值,那么直接使用设值函数就行了。如果的确需要条件判断的行为,可考虑使用 Replace

Replace Type Code with Class (以类取代类型码)

╄→尐↘猪︶ㄣ 提交于 2020-03-02 03:08:29
Summary : 类之中有一个数值类型码,但它并不影响类的行为。 以一个新的类替换该数值类型码。 动机: 在以 C 为基础的变成语言中,类型码或枚举值很常见。如果带着一个有意义的符号名,类型码的可读性还是不错的。问题在于,符号名终究是个别名,编译器所看见的、进行类型校验的,还是背后那个数值。任何接受类型码作为参数的函数所期望的实际上是一个数值,无法强制使用符号名。这会大大降低代码的可读性,从而成为 bug 之源。 如果把那样的数值换成一个类,编译器就可以对这个类进行类型校验。只要为这个类提供工厂函数,你就额可以始终保证只有合法的实例才会被创建出来,而且它们都会被传递给正确的宿主对象。 但是在使用 Replace Type Code with Class 之前,你应该先考虑类型码的其他替换方式。只有当类型码是纯数据时(也就是类型码不会在 switch 语句中引起行为变化时),你才能以类来取代它。 Java 只能以整数作为 switch 语句的判断依据,不能使用任意类,因此在那种情况下不能够以类替换类型码。更重要的是:任何 switch 语句都应该运用 Replace Conditional with Polymorphism 去掉。为了进行那样的重构,你首先运用 Replace Type Code with Subclasses 或 Replace Type Code with

Replace Constructor with Factory Method (以工厂函数取...

匆匆过客 提交于 2020-03-02 02:42:48
Summary: 你希望在创建对象时不仅仅是做简单的建构动作。将构造函数替换为工厂函数。 Motivation: 使用该手法最显而易见的动机是在派生子类的过程中以工厂函数取代类型码。你可能常常需要根据类型码创建相应的对象,现在,创建名单上还得加上子类,那些子类也是根据类型码来创建。然而由于构造函数只能返回单一类型的对象,因此需要将构造函数替换为工厂函数。 此外,如果构造函数的功能不能满足需要,也可以使用工厂函数来代替它。工厂函数也是Change Value to Reference的基础。可以令工厂函数根据参数的个数和类型,选择不同的创建行为。 Mechanics: 1.新建一个工厂函数,让它调用现有的构造函数。 2.将调用构造函数的代码改为调用工厂函数。 3.每次替换后编译并测试 4.将构造函数声明为private 5.编译 范例1. 根据整数(实际是类型码)创建对象 以员工薪资系统为例,“Employee”表示“员工”: class Employee{ private int type; static final int ENGINEER = 0; static final int SALESMAN = 1; static final int MANAGER = 2; Employee(int type){ this.type = type; } }

Replace Conditional with Polymorphism (以多态取代条件表达式)

落花浮王杯 提交于 2020-03-02 02:42:33
Summary : 你手上有个条件表达式,它根据对象类型的不同而选择不同的行为。 将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将原始函数声明为抽象函数。 Motivation: 在面向对象术语中,听上去最高贵的词非“多态”莫属。多态最根本的好处就是:如果你需要根据对象的不同类型而采取不同的行为,多态使你不必编写明显的条件表达式。 正因为有了多态,所以你会发现:“类型码的 switch 语句”以及“基于类型名称的 if-then-else 语句”在面向对象程序中很少出现。 多态能够给你带来很多好处。如果同一组条件表达式在程序许多地点出现,那么使用多态的收益是最大的。使用条件表达式时,如果你想添加一种新类型,就必须查找并更新所有条件表达式。但如果改用多态,只需建立一个新的子类,并在其中提供适当的函数就行了。类的用户不需要了解这个子类,这就大大降低了系统各部分之间的依赖,使系统升级更加容易。 Mechanics: 使用 Replace Conditional with Polymorphism 之前,首先必须由一个继承结构。你可能已经通过先前的重构得到了这一结构。如果还没有,现在就需要建立它。 要建立继承结构,有两种选择: Replace Type Code with Subclasses 和 Replace Type Code with State/Strategy

Replace Type Code with State/Strategy

半城伤御伤魂 提交于 2020-03-02 02:42:13
Summary : 你有一个类型码,它会影响类的行为,但你无法通过继承手法消除它。 以状态对象取代类型码。 动机: 本项重构和 Replace Type Code with Subclasses 很相似,但如果“类型码的值在对象生命期中发生变化”或“其他原因使得宿主类不能被继承”,你也可以使用本重构。本重构使用 State 模式或 Strategy 模式。 State 模式和 Strategy 模式非常相似,因此无论你选择其中哪一种,重构过程都是相同的。“选择哪一个模式”并非问题关键所在,你只需要选择更适合特定情境的模式就行了。如果你打算在本项重构完成之后再以 Replace Conditional with Polymorphism 简化一个算法,那么选择 Strategy 模式比较合适;如果你打算搬移与状态相关的数据,而且你把新建对象视为一种变迁状态,就应该选择使用 State 模式。 做法: 1. 使用 Self Encapsulate Field 将类型码自我封装起来。 2. 新建一个类,根据类型码的用途为它命名。这就是一个状态对象。 3. 为这个新类添加子类,每个子类对应一种类型码。 à 比起逐一添加,一次性加入所有必要的子类可能更简单些。 4. 在超类中建立一个抽象的查询函数,用以返回类型码。在每个子类中覆写该函数,返回确切的类型码。 5. 编译。 6.

excel vba replace函数的使用方法

天涯浪子 提交于 2020-03-01 20:15:37
Repalace函数是vba中常用的字符替换函数,本文介绍了replace的基本使用方法,6个参数的意思。 Sub replacetest ( ) Dim str As String Dim str2 As String str = "ababab" 'vba.Replace("在哪儿找","找什么(需要被替换掉的部分)","换成什么","从第几个字符开始找","替换几次","匹配方式") '一共六个参数 '例1 str2 = Replace ( str , "a" , 1 ) '把str中的全部替换为1 'str2 会被替换成1b1b1b '例2 str2 = Replace ( str , "a" , 1 , 3 ) '第四个参数说明从第3个字符开始替换,替换结果会舍掉前两个字符。 'str2会被替换成1b1b '例3 str2 = Replace ( str , "a" , 1 , 3 , 1 ) '第五个参数是替换次数,默认是替换全部,设置为1的话,就只替换第一次出现的a; '这句代码的意思是从第3个开始的第1个a 'str2会被替换为1bab '例4 str2 = Replace ( str , "A" , 1 , , , vbBinaryCompare ) '第六个参数为二进制匹配时,区分大小写;结果为ababab str2 = Replace ( str , "A"

Replace Nested Conditional with Guard Clauses

流过昼夜 提交于 2020-03-01 13:28:24
Summary : 函数中的条件逻辑使人难以看清正常的执行路径。 使用卫语句表现所有特殊情况。 动机: 条件表达式通常有两种表现形式。第一种形式是:所有分支都属于正常行为。第二种形式则是:条件表达式提供的答案中只有一种是正常行为,其他都是不常见的情况。 这两类条件表达式有不同的用途,这一点应该通过代码表现出来。如果两条分支都是正常行为,就应该使用如 if…else… 的条件表达式;如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。这样的单独检查常常被称为“卫语句”( guard clauses ) Replace Nested Conditional with Guard Clauses 的精髓就是:给某一条分支以特别的重视。如果使用 if-then-else 结构,你对 if 分支的重视是同等的。这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。卫语句就不同了,它告诉阅读者:“这种情况很罕见,如果它真地发生了,请做一些必要的整理工作,然后退出。” “每个函数只能有一个入口和一个出口”的观念,根深蒂固于某些程序员的脑海里。当我们处理他们编写的代码时,经常需要使用 Replace Nested Conditional with Guard Clauses 。现金的编程语言都会强制保证每个函数只有一个入口,至于“单一出口”规则,其实不是那么有用

MYSQL插入数据时忽略重复数据

佐手、 提交于 2020-03-01 05:49:39
当程序中insert时,已存在的数据不插入,不存在的数据insert。在网上搜了下, 可以使用存储过程或者是用NOT EXISTS 来判断是否存在。 使用下以两种方法时必须把字段设为”主键(PRIMARY KEY”或”唯一约束(UNIQUE)”。 1:使用REPLACE INTO (此种方法是利用替换的方法,有点似类于先删除再插入) REPLACE INTO Syntax REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] {VALUES | VALUE} ({expr | DEFAULT},…),(…),… Or: REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name={expr | DEFAULT}, … Or: REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] SELECT … 2:使用INSERT [IGNORE] INTO (此种方法效率比较高,判断是否存在,存在不插入,否则插入) INSERT [IGNORE] INTO Syntax INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY]

Suggestion: add 'tools:replace="android:icon"' to

青春壹個敷衍的年華 提交于 2020-03-01 01:14:36
Suggestion: add 'tools:replace="android:icon"' to element 背景: 今天在用Android Studio开发时,遇到一个问题,建了一个项目,依赖了一个自己写的库,在编译时报了这个错误,大致的原因是资源与库在清单文件里引用了相同的资源文件,Gradle插件默认会启用Manifest Merger Tool,就会发生冲突。 错误提示: Error:Execution failed for task ':loggertest:processDebugManifest'. Manifest merger failed : Attribute application@icon value=(@mipmap/iclauncher) from AndroidManifest.xml:7:9-43 is also present at [TuringOSLoggerAPI:app:unspecified] AndroidManifest.xml:16:9-45 value=(@drawable/iclauncher). Suggestion: add 'tools:replace="android:icon"' to element at AndroidManifest.xml:5:5-18:19 to override. 解决方法

如何添加或更新查询字符串参数?

谁说胖子不能爱 提交于 2020-02-29 22:16:58
使用javascript,如何将查询字符串参数添加到url(如果不存在)或如果存在,则更新当前值? 我正在使用jquery进行客户端开发。 #1楼 我已经扩展了该解决方案,并将其与我发现的另一个解决方案结合在一起,可以根据用户输入并考虑url锚点来替换/更新/删除querystring参数。 不提供值将删除该参数,提供一个将添加/更新该参数。 如果没有提供URL,它将从window.location中获取。 function UpdateQueryString(key, value, url) { if (!url) url = window.location.href; var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"), hash; if (re.test(url)) { if (typeof value !== 'undefined' && value !== null) { return url.replace(re, '$1' + key + "=" + value + '$2$3'); } else { hash = url.split('#'); url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); if (typeof hash[1]