成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

The Coding Kata: FizzBuzzWhizz in Java8

張率功 / 928人閱讀

摘要:匹配器是一個(gè)一元函數(shù),入?yún)?,返回值為,是一種典型的謂詞。執(zhí)行器也是一個(gè)一元函數(shù),入?yún)?,返回值為,其本質(zhì)就是定制常見的操作,將定義域映射到值域。為一個(gè)工廠類,用于生產(chǎn)各種。其中,使用了的。

Functional programming leads to deep insights into the nature of computation. -- Martin Odersky

形式化

FizzBuzzWhizz詳細(xì)描述請(qǐng)自行查閱相關(guān)資料。此處以3, 5, 7為例,形式化地描述一下問題。

r1
- times(3) -> Fizz
- times(5) -> Buzz
- times(7) -> Whizz
r2
- times(3) && times(5) && times(7) -> FizzBuzzWhizz
- times(3) && times(5) -> FizzBuzz
- times(3) && times(7) -> FizzWhizz
- times(5) && times(7) -> BuzzWhizz
r3
- contains(3) -> Fizz
- the priority of contains(3) is highest
rd
- others -> others

接下來我將使用Scala嘗試FizzBuzzWhizz問題的設(shè)計(jì)和實(shí)現(xiàn)。

語義模型

從上面的形式化描述,可以很容易地得到FizzBuzzWhizz問題的語義模型。

Rule: (Int) -> String
Matcher: (Int) -> Boolean
Action: (Int) -> String

其中,Rule存在三種基本的類型:

Rule ::= atom | allof | anyof

三者之間構(gòu)成了「樹型」結(jié)構(gòu)。

atom: (Matcher, Action) -> String
allof(rule1, rule2, ...): rule1 && rule2 && ... 
anyof(rule1, rule2, ...): rule1 || rule2 || ... 
測(cè)試用例

借助Java8增強(qiáng)了的「函數(shù)式」能力,可拋棄掉很多重復(fù)的「樣板代碼」,使得設(shè)計(jì)更加簡單、漂亮。此外,Java8構(gòu)造DSL的能力也相當(dāng)值得稱贊,非常直接,簡單。測(cè)試用例此處選擇Spock(基于Groovy語言),可提高用例的可讀性和可維護(hù)性。

class RuleSpec extends Specification {
  private static def spec() {
    Rule r1_3 = atom(times(3), to("Fizz"))
    Rule r1_5 = atom(times(5), to("Buzz"))
    Rule r1_7 = atom(times(7), to("Whizz"))

    Rule r1 = anyof(r1_3, r1_5, r1_7)

    Rule r2 = anyof(allof(r1_3, r1_5, r1_7),
        allof(r1_3, r1_5),
        allof(r1_3, r1_7),
        allof(r1_5, r1_7))

    Rule r3 = atom(contains(3), to("Fizz"))
    Rule rd = atom(always(true), nop())

    anyof(r3, r2, r1, rd)
  }

  def "fizz buzz whizz"() {
    expect:
    spec().apply(n) == expect

    where:
    n            | expect
    3            | "Fizz"
    5            | "Buzz"
    7            | "Whizz"
    3 * 5 * 7    | "FizzBuzzWhizz"
    3 * 5        | "FizzBuzz"
    3 * 7        | "FizzWhizz"
    (5 * 7) * 2  | "BuzzWhizz"
    13           | "Fizz"
    35 /* 5*7 */ | "Fizz"  /* not "BuzzWhizz" */
    2            | "2"
  }
}
匹配器:Matcher

Matcher是一個(gè)「一元函數(shù)」,入?yún)?b>Int,返回值為Boolean,是一種典型的「謂詞」。從OO的角度看,always是一種典型的Null Object。

import static java.lang.String.valueOf;

@FunctionalInterface
public interface Matcher {
  boolean matches(int n);

  static Matcher times(int n) {
    return x -> x % n == 0;
  }

  static Matcher contains(int n) {
    return x -> valueOf(x).contains(valueOf(n));
  }

  static Matcher always(boolean bool) {
    return n -> bool;
  }
}
執(zhí)行器:Action

Action也是一個(gè)「一元函數(shù)」,入?yún)?b>Int,返回值為String,其本質(zhì)就是定制常見的map操作,將定義域映射到值域。

@FunctionalInterface
public interface Action {
  String to(int n);

  static Action to(String str) {
    return n -> str;
  }

  static Action nop() {
    return n -> String.valueOf(n);
  }
}
規(guī)則:Rule

Composition Everywhere

RuleFizzBuzzWhizz最核心的抽象,也是設(shè)計(jì)的靈魂所在。從語義上Rule分為2種基本類型,并且兩者之間形成了優(yōu)美的、隱式的「樹型」結(jié)構(gòu),體現(xiàn)了「組合式設(shè)計(jì)」的強(qiáng)大威力。

Atom

Compositions: anyof, allof

Rule是一個(gè)「二元函數(shù)」,入?yún)?b>(Int),返回值為String。

@FunctionalInterface
public interface Rule {
  String apply(int n);
}

Rules為一個(gè)工廠類,用于生產(chǎn)各種Rule。其中,allof, anyof使用了Java8 StreamAPI。

public final class Rules {
  public static Rule atom(Matcher matcher, Action action) {
    return n -> matcher.matches(n) ? action.to(n) : "";
  }

  public static Rule anyof(Rule... rules) {
    return n ->sstream(n, rules)
        .filter(s -> !s.isEmpty())
        .findFirst()
        .orElse("");
  }

  public static Rule allof(Rule... rules) {
    return n -> sstream(n, rules)
        .collect(joining());
  }

  private static Stream sstream(int n, Rule[] rules) {
    return Arrays.stream(rules)
        .map(r -> r.apply(n));
  }

  private Rules() {
  }
}
源代碼

Github: https://github.com/horance-liu/fizz-buzz...

C++11參考實(shí)現(xiàn): https://codingstyle.cn/topics/97

Scala參考實(shí)現(xiàn): https://codingstyle.cn/topics/99

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65591.html

相關(guān)文章

  • 一些做著玩的題

    摘要:這是我在平時(shí)有時(shí)間的時(shí)候做的一些算法上的題目想看更新請(qǐng)移步這里題目描述解法這個(gè)問題當(dāng)時(shí)拿到的時(shí)候是完全沒有思路的,后面上網(wǎng)查詢了一下這個(gè)題目,知道了使用斐波那契數(shù)列就能夠解這道題目,,,當(dāng)然百度作業(yè)幫上面也有相應(yīng)的解法,套路就是題目為一 這是我在平時(shí)有時(shí)間的時(shí)候做的一些算法上的題目 想看更新請(qǐng)移步這里 題目: Climbing Stairs 描述 You are climbing a ...

    cheukyin 評(píng)論0 收藏0
  • 【python】Human readable duration format 時(shí)間格式轉(zhuǎn)換

    摘要:背景上的一道原題,通過格式劃字符串精簡了代碼結(jié)構(gòu),省去了很多條件判斷語句。題目描述解題思路題目是很簡單的,關(guān)鍵是如何優(yōu)雅地完成是否在當(dāng)前時(shí)間單位后添加和或者,我的代碼里運(yùn)用了很多語句。代碼感想表達(dá)式真是一個(gè)神器。 背景 CodeWar上的一道原題,通過格式劃字符串精簡了代碼結(jié)構(gòu),省去了很多條件判斷語句。 題目描述 Your task in order to complete this ...

    liangzai_cool 評(píng)論0 收藏0
  • Kata: 從隨機(jī)的三字符列表組中恢復(fù)秘密字符串

    摘要:題目從給定字符串中隨機(jī)出的三字符列表的集合中,恢復(fù)原始字符串,并且三字符列表按字符在字符串中出現(xiàn)順序排列。作為簡化,假設(shè)秘密字符串中不會(huì)有重復(fù)字母。從原始集合中去掉找出的第一個(gè)字母,并在除去字母的該行末尾添加,以保持三元素列表。 題目:從給定字符串中隨機(jī)出的三字符列表的集合中,恢復(fù)原始字符串,并且三字符列表按字符在字符串中出現(xiàn)順序排列。作為簡化,假設(shè)秘密字符串中不會(huì)有重復(fù)字母。如下: ...

    zgbgx 評(píng)論0 收藏0
  • Kata: Sum of Pairs

    摘要:題目給出一個(gè)整型數(shù)列表和一個(gè)整數(shù),求列表中加起來等于的兩個(gè)數(shù),并且這一對(duì)是在列表中最先組成對(duì)的。因?yàn)轭}目要求是返回最先組對(duì)成功的兩個(gè)數(shù),所以要找到列表中符合要求的數(shù)對(duì)中,第二個(gè)數(shù)最先出現(xiàn)的數(shù)對(duì)。與擁有類似的結(jié)構(gòu)。 題目:給出一個(gè)整型數(shù)列表和一個(gè)整數(shù)sum,求列表中加起來等于sum的兩個(gè)數(shù),并且這一對(duì)是在列表中最先組成對(duì)的。 這道題并不難,使用兩個(gè)for循環(huán)很容易做出來。但提交答案時(shí)說出...

    Drummor 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<