分類
發燒車訊

談一談依賴倒置原則

為獲得良好的閱讀體驗,請訪問原文:

一、概念

依賴倒置原則(Dependence Inversion Principle,DIP)是指設計代碼結構時,高層模塊不應該依賴低層模塊,二者都應該依賴其抽象。

抽象不應該依賴細節,細節應該依賴抽象。通過依賴倒置,可以減少類與類之間的耦合性,提高系統的穩定性,提高代碼的可讀性和可維護性,並且能夠降低修改程序所造成的風險。

二、為什麼

先來看一個例子

可是依賴倒置原則是怎麼做到的呢?我們先來看一個例子:一個愛學習的「我沒有三顆心臟」同學現在正在學習「設計模式」和「Java」的課程,偽代碼如下:

public class Wmyskxz {

    public void studyJavaCourse() {
        System.out.println("「我沒有三顆心臟」同學正在學習「Java」課程");
    }

    public void studyDesignPatternCourse() {
        System.out.println("「我沒有三顆心臟」同學正在學習「設計模式」課程");
    }
}

我們來模擬上層調用一下:

public static void main(String[] args) {
    Wmyskxz wmyskxz = new Wmyskxz();
    wmyskxz.studyJavaCourse();
    wmyskxz.studyDesignPatternCourse();
}

原因一:有效控制影響範圍

由於「我沒有三顆心臟」同學熱愛學習,隨着學習興趣的 “暴增”,可能會繼續學習 AI(人工智能)的課程。這個時候,因為「業務的擴展」,要從底層實現到高層調用依次地修改代碼。

我們需要在 Wmyskxz 類中新增 studyAICourse() 方法,也需要在高層調用中增加調用,這樣一來,系統發布后,其實是非常不穩定的。顯然在這個簡單的例子中,我們還可以自信地認為,我們能 Hold 住這一次的修改帶來的影響,因為都是新增的代碼,我們回歸的時候也可以很好地 cover 住,但實際的情況和實際的軟件環境要複雜得多。

最理想的情況就是,我們已經編寫好的代碼可以 “萬年不變”,這就意味着已經覆蓋的單元測試可以不用修改,已經存在的行為可以保證保持不變,這就意味着「穩定」。任何代碼上的修改帶來的影響都是有未知風險的,不論看上去多麼簡單。

原因二:增強代碼可讀性和可維護性

另外一點,你有沒有發現其實加上新增的 AI 課程的學習,他們三節課本質上行為都是一樣的,如果我們任由這樣行為近乎一樣的代碼在我們的類裏面肆意擴展的話,很快我們的類就會變得臃腫不堪,等到我們意識到不得不重構這個類以緩解這樣的情況的時候,或許成本已經變得高得可怕了。

原因三:降低耦合

《資本論》中有這樣一段描述:

在商品經濟的萌芽時期,出現了物物交換。假設你要買一個 iPhone,賣 iPhone 的老闆讓你拿一頭豬跟他換,可是你並沒有養豬,你只會編程。所以你找到一位養豬戶,說給他做一個養豬的 APP 來換他一頭豬,他說換豬可以,但是得用一條金項鏈來換…

所以這裏就出現了一連串的對象依賴,從而造成了嚴重的耦合災難。解決這個問題的最好的辦法就是,買賣雙發都依賴於抽象——也就是貨幣——來進行交換,這樣一來耦合度就大為降低了。

三、怎麼做

我們現在的代碼是上層直接依賴低層實現,現在我們需要定義一個抽象的 ICourse 接口,來對這種強依賴進行解耦(就像上面《資本論》中的例子那樣):

接下來我們可以參考一下偽代碼,先定一個課程的抽象 ICourse 接口:

public interface ICourse {
    void study();
}

然後編寫分別為 JavaCourseDesignPatternCourse 編寫一個類:

public class JavaCourse implements ICourse {

    @Override
    public void study() {
        System.out.println("「我沒有三顆心臟」同學正在學習「Java」課程");
    }
}

public class DesignPatternCourse implements ICourse {

    @Override
    public void study() {
        System.out.println("「我沒有三顆心臟」同學正在學習「設計模式」課程");
    }
}

然後把 Wmyskxz 類改造成如下的樣子:

public class Wmyskxz {

    public void study(ICourse course) {
        course.study();
    }
}

再來是我們的調用:

public static void main(String[] args) {
    Wmyskxz wmyskxz = new Wmyskxz();
    wmyskxz.study(new JavaCourse());
    wmyskxz.study(new DesignPatternCourse());
}

這時候我們再來看代碼,無論「我沒有三顆心臟」的興趣怎麼暴漲,對於新的課程,都只需要新建一個類,通過參數傳遞的方式告訴它,而不需要修改底層的代碼。實際上這有點像大家熟悉的依賴注入的方式了。

總之,切記:以抽象為基準比以細節為基準搭建起來的架構要穩定得多,因此在拿到需求后,要面相接口編程,先頂層設計再細節地設計代碼結構。

參考資料

  1. – 那些年搞不懂的高深術語——依賴倒置•控制反轉•依賴注入•面向接口編程
  2. 《Spring 5 核心原理 與 30 個類手寫實戰》 – 譚勇德 著

按照慣例黏一個尾巴:

歡迎轉載,轉載請註明出處!
獨立域名博客:wmyskxz.com
簡書ID:
github:
歡迎關注公眾微信號:wmyskxz
分享自己的學習 & 學習資料 & 生活
想要交流的朋友也可以加qq群:3382693

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

分類
發燒車訊

Spring Cloud gateway 七 Sentinel 註解方式使用

Sentinel 註解支持

@SentinelResource 用於定義資源,並提供可選的異常處理和 fallback 配置項。 @SentinelResource 註解包含以下屬性:

  • value:資源名稱,必需項(不能為空)
  • entryType:entry 類型,可選項(默認為 EntryType.OUT)
  • blockHandler / blockHandlerClass: blockHandler 對應處理 BlockException 的函數名稱,可選項。blockHandler 函數訪問範圍需要是 public,返回類型需要與原方法相匹配,參數類型需要和原方法相匹配並且最後加一個額外的參數,類型為 BlockException。blockHandler 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 blockHandlerClass 為對應的類的 Class 對象,注意對應的函數必需為 static 函數,否則無法解析。
  • fallback:fallback 函數名稱,可選項,用於在拋出異常的時候提供 fallback 處理邏輯。fallback 函數可以針對所有類型的異常(除了 – exceptionsToIgnore 裏面排除掉的異常類型)進行處理。fallback 函數簽名和位置要求:
    • 返回值類型必須與原函數返回值類型一致;
    • 方法參數列表需要和原函數一致,或者可以額外多一個 Throwable 類型的參數用於接收對應的異常。
    • fallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 fallbackClass 為對應的類的 Class 對象,注意對應的函數必需為 static 函數,否則無法解析。
  • defaultFallback(since 1.6.0):默認的 fallback 函數名稱,可選項,通常用於通用的 fallback 邏輯(即可以用於很多服務或方法)。默認 fallback 函數可以針對所有類型的異常(除了 exceptionsToIgnore 裏面排除掉的異常類型)進行處理。若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。defaultFallback 函數簽名要求:
    • 返回值類型必須與原函數返回值類型一致;
    • 方法參數列表需要為空,或者可以額外多一個 Throwable 類型的參數用於接收對應的異常。
    • defaultFallback 函數默認需要和原方法在同一個類中。若希望使用其他類的函數,則可以指定 fallbackClass 為對應的類的 Class 對象,注意對應的函數必需為 static 函數,否則無法解析。
  • exceptionsToIgnore(since 1.6.0):用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣拋出。

注:1.6.0 之前的版本 fallback 函數只針對降級異常(DegradeException)進行處理,不能針對業務異常進行處理。

特別地,若 blockHandler 和 fallback 都進行了配置,則被限流降級而拋出 BlockException 時只會進入 blockHandler 處理邏輯。若未配置 blockHandler、fallback 和 defaultFallback,則被限流降級時會將 BlockException 直接拋出。

使用注意點采坑日記

@SentinelResource 註解不單單用於controller的接口流控。同時也可以用於方法上面。如果看過實現方式代碼。可以知道他底層是基於cglib動態代理實現的。進行切面處理。注意點:

  • 不能修飾在接口上面。只能修飾在實現類的方法上
  • 不能修飾在靜態的方法上面。
  • 同一個bean方法A調用方法B,假設方法A和B都進行了註解。B方法註解失效,請參考@Transactional 失效。
    • @Transactional 加於private方法, 無效
    • @Transactional 加於未加入接口的public方法, 再通過普通接口方法調用, 無效
    • @Transactional 加於接口方法, 無論下面調用的是private或public方法, 都有效
    • @Transactional 加於接口方法后, 被本類普通接口方法直接調用, 無效
    • @Transactional 加於接口方法后, 被本類普通接口方法通過接口調用, 有效
    • @Transactional 加於接口方法后, 被它類的接口方法調用, 有效
    • @Transactional 加於接口方法后, 被它類的私有方法調用后, 有效

blockHandler 和 blockHandlerClass 的使用

blockHandler 是可選的。如果使用blockHandlerClass,必須搭配blockHandler使用, blockHandler指定blockHandlerClass類中對應的方法名稱。方法名稱、參數、返回值、static 必須按照上述文檔描述一樣。官方文檔沒有強調要必須要搭配使用。

同理 fallback 和 fallbackClass也是上面講述的注意點。

改造client 服務

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

bootstrap.yml 配置文件

spring:
    cloud:
        sentinel:
                filter:
                    # sentienl 默認生效,本地調試false
                    enabled: true
                transport:
                    dashboard: localhost:8890
                    port: 8719
                # 飢餓加載
                eager: true
                datasource:
                    # Sentinel基於nacos存儲獲取配置信息
                    na:
                        nacos:
                            server-addr: 47.99.209.72:8848
                            groupId: DEFAULT_GROUP
                            dataId: ${spring.application.name}-${spring.profiles.active}-sentinel
                            # 類型
    #            FLOW("flow", FlowRule.class),
    #            DEGRADE("degrade", DegradeRule.class),
    #            PARAM_FLOW("param-flow", ParamFlowRule.class),
    #            SYSTEM("system", SystemRule.class),
    #            AUTHORITY("authority", AuthorityRule.class),
    #            GW_FLOW("gw-flow", "com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"),
    #            GW_API_GROUP("gw-api-group", "com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition");
                            rule-type: flow

nacos 創建 cloud-discovery-client-dev-sentinel 配置文件

[
    {
        "resource": "client:log:save",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    },
    {
        "resource": "client:fegin:test",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    },
     {
        "resource": "user:service:saveTx",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    },
    {
        "resource": "user:service:save:test",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

創建 BackHandlerClass DiscoveryClientControllerBackHandler

package com.xian.cloud.common.handler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.xian.cloud.entity.UserEntity;
import lombok.extern.slf4j.Slf4j;

/**
 *  對應處理 BlockException 的函數名稱 服務限流
 * @Author: xlr
 * @Date: Created in 9:08 PM 2019/11/16
 */
@Slf4j
public class DiscoveryClientControllerBackHandler {

    public static String defaultMessage(BlockException e){
        
        log.warn( "DiscoveryClientControllerBackHandler  defaultMessage BlockException : {}",e );
        return "defaultMessage 服務限流,請稍後嘗試";
    }

    public static String saveTx(UserEntity entity,BlockException e) {

        log.warn( "DiscoveryClientControllerBackHandler  saveTx BlockException : {}",e );
        return "saveTx 服務限流,請稍後嘗試";
    }
}

創建 FallBackHandlerClass

package com.xian.cloud.common.handler;

import com.xian.cloud.entity.UserEntity;
import lombok.extern.slf4j.Slf4j;

/**
 * 僅針對降級功能生效(DegradeException)
 * @Author: xlr
 * @Date: Created in 9:13 PM 2019/11/16
 */
@Slf4j
public class DiscoveryClientControllerFallBackHandler {

    public static String defaultMessage(Throwable t){
        
        log.warn( "DiscoveryClientControllerFallBackHandler defaultMessage Throwable : {}",t );
        return "defaultMessage 服務降級,請稍後嘗試";
    }

    public static String saveTx(UserEntity entity,Throwable t) {

        log.warn( "DiscoveryClientControllerFallBackHandler saveTx Throwable : {}",t );
        return "saveTx 服務降級,請稍後嘗試";
    }
}

對外接口DiscoveryClientController 添加接口


@SentinelResource(
            value = "client:fegin:test",
            blockHandler = "defaultMessage",
            fallback = "defaultMessage",
            blockHandlerClass = DiscoveryClientControllerBackHandler.class,
            fallbackClass = DiscoveryClientControllerFallBackHandler.class
    )
    @RequestMapping(value = "fegin/test",method = RequestMethod.GET)
    public String feginTest() {
        String result = serverService.hello( "fegin" );
        return  " 返回 : " + result;
    }
        
        
 @GetMapping("/log/save")
    @SentinelResource(
            value = "client/log/save",
            blockHandler = "defaultMessage",
            fallback = "defaultMessage",
            blockHandlerClass = DiscoveryClientControllerBackHandler.class,
            fallbackClass = DiscoveryClientControllerFallBackHandler.class
    )
    public String save(){
        UserEntity entity = new UserEntity();
        entity.setUsername("tom");
        entity.setPassWord("1232131");
        entity.setEmail("222@qq.com");
        userService.saveTx(entity);
        return "success";
    }
        
    @GetMapping("user/service/save")
    public String userServiceSaveTx(){
        UserEntity entity = new UserEntity();
        String result = userService.saveTx( entity );
        return result;
    }

UserServiceImpl 方法

  @Override
    @Transactional
    @SentinelResource(
            value = "user:service:saveTx",
            blockHandler = "saveTx",
            fallback = "saveTx",
            blockHandlerClass = DiscoveryClientControllerBackHandler.class,
            fallbackClass = DiscoveryClientControllerFallBackHandler.class
    )
    public String saveTx(UserEntity entity) {

        return "success";
    }

以上就配置完畢。然後進行測試在頁面瘋狂刷新

http://localhost:9011/client/user/service/save

http://localhost:9011/client/fegin/test

停止 server服務 再次調用 fegin、test

服務降級和服務限流來回切換提示在前端頁面。blockHandlerClass、fallbackClass。

如何喜歡可以關注分享本公眾號。

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。轉載請附帶公眾號二維碼

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

分類
發燒車訊

戶外空污使全球人類平均減壽三年 比吸菸、愛滋和傳染病還慘

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

分類
發燒車訊

肯亞護蝶計畫 婦女成保育尖兵兼顧家計

摘錄自2020年3月6日公視報導

肯亞為防止居民砍伐國家公園內的樹木,從1993年開始推出了蝴蝶養殖計畫,讓照顧家庭而無法外出工作的婦女能夠保護森林,有助於蝴蝶養殖,還能將森林公園中的罕見熱帶蝴蝶出口到歐美國家。

肯亞的「阿拉布科索科凱國家公園」是特殊熱帶蝴蝶的生長天堂,這裡的蝴蝶約有230個種類,依靠熱帶森林中不同的樹木生長。為了防範森林持續遭到破壞,影響環境生態,肯亞政府推出了「護蝶計畫」,讓參加者協助保育森林,同時蒐集特殊蝴蝶,用以出口到歐美國家,並將賺取的金額,分發給參加婦女們,兼顧居民的生計。

護蝶計畫的蝶蛹出口旺季,在每年的4月到9月,平均200隻蝶蛹可以賣出130美元,約台幣3900元。由於出口的對象,包括全球各地的蝴蝶公園、教育機構和科學研究機構,也讓這項計畫目前的年收入達到了10萬美元。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

大陸寄台灣空運注意事項

大陸海運台灣交貨時間多久?

分類
發燒車訊

標緻新能源車最晚將於2019年推出

據外媒報導,標緻產品總監Jerome Micheron日前透露,由於歐洲的排放法規日益嚴格,公司計畫在這個十年結束前(2020年前)開展綠色行動,其中標緻將在2019年推出一款插電式混動車型,新車將搭載由小型汽油發動機和電動機組成的混動系統,純電動續航里程為50km。

此外,外媒稱,標緻的新能源計畫中還有一款純電動車型,這款車型將基於EMP2平臺打造,而該平臺正是現款標緻308(國內稱308S)所採用的平臺,這款車型也將在2019年正式亮相。

標緻目前在新能源車方面還比較空白,相比其它品牌來說,似乎起步較晚,但標緻產品總監卻不這麼認為,中國有句古話叫好飯不怕晚,也許就是標緻產品總監想表達的意思吧。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

分類
發燒車訊

蘋果電動車傳2021年問世、定價7.5萬美元

蘋果跨足電動車市場傳言甚囂塵上,投資機構Piper Jaffray資深分析師Gene Munster預測,蘋果將循設計、代工模式開發電動車,預計五年後也就是2021年上路。

蘋果電動車專案代號傳為「Titan」,Munster估計該電動車每輛定價約7.5萬美元,雖然全由蘋果設計,但生產製造有八成都將委外代工。

年初有報導指出,蘋果電動車計畫的幕後推手薩德斯基(Steve Zadesky)可能離職,即便如此,Munster仍舊看好蘋果電動車成功的機率超過五成,畢竟蘋果有錢、有人還有廣大粉絲做後盾。

據AppleInsider報導,蘋果電動車員工人數今年已膨脹至逾1千人,但可能也就是因為擴編速度太快,造成薩德斯基飯碗不保。

基本上,Munster認為電動車幾乎是營收成長動能的保證,因此蘋果不太可能放棄,最快2019、2020年應該會有初步產品展出。

(本文內容由授權提供)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

大陸寄台灣空運注意事項

大陸海運台灣交貨時間多久?

※避免吃悶虧無故遭抬價!台中搬家公司免費估價,有契約讓您安心有保障!

分類
發燒車訊

Windows下編譯最新版ChezScheme

    據說ChezScheme是最快的神級編譯器,一秒鐘幾百萬行,王垠說的2秒內編譯自身絕不是誇張(看這裏《》,Scheme中文社區)。ChezScheme由美國印第安納大學的Kent Dybvig博士發明,後來賣給了思科CISCO,作為內部絕密的編譯器工具來運行苛刻的計算任務,現在已經開源,倉庫地址是。有關如何開始使用Chez Scheme,請看官方的文檔:,有關Scheme的使用入門,這裏推薦一本中文翻譯的《》,這是一本面向初學者的溫和且循序漸進的Scheme教程。目標讀者是僅有些許編程經驗的PC用戶。

    下面來介紹下截止到2019.11.19日的最新版如何在Windows下編譯一個ChezScheme,其它環境下如何編譯請看源碼下的文件BUILDING的介紹:Building Chez Scheme Version 9.5.3。請注意這個版本號,之前的版本編譯方法可能與本文介紹的不同,本人也為此踩坑了不少時間。

1,首先,安裝Visual Studio 2015/2017,注意必須選擇按照Visual C++ 桌面開發組件,否則你在最後一步無法編譯Scheme。

2,安裝msys2,這是一個Windows下的Linux Shell環境,可以讓你在Windows上使用Linux命令,並且它還自帶包管理功能。安裝完後按照官網提示更新下msys2,會給你安裝一堆組件,默認都安裝。

3,打開Visual Studio命令提示符,選擇“vs2015 x64 native tools command prompt”,vs2017類似,中文名稱是“適用於VS2017的本機命令工具提示”。

4,在上面的Visual Studio命令提示工具裏面,輸入c:\msys64\msys2_shell.cmd,打開msys2的命令提示窗口。

5,在msys2裏面安裝GCC編譯工具和Git工具,如果Git已經安裝跳過。

pacman -S gcc base- devel
pacman -S git

 

6,下載Chez Scheme源碼,然後進行編譯前配置,最後編譯。如果源碼已經下載跳過。

git clone https: // github.com/cisco/ChezScheme.git 
cd ChezScheme
cd wininstall
make workareas
 make

 

7,最後等make完成,我們在ChezScheme目錄a6nt\bin\a6nt 下可以看到scheme.exe,雙擊它即可運行。

8,將a6nt目類下的bin目錄和boot目錄都複製到一個新建的build目錄下,然後創建一個run.bat 文件,文件內容如下:

@ECHO  off 
ECHO Chez Scheme for Windows. make by bluedoctor. 2019.11.18 
bin \a6nt\scheme.exe

build目錄的文件結構如下:

E:\ChezScheme\build\ChezScheme>dir /s
 驅動器E 中的捲是LENOVO
 卷的序列號是E2D7-2E41

 E:\ChezScheme\build\ChezScheme 的目錄

2019/11/18 23:23 <DIR> .
2019/11/18 23:23 <DIR> ..
2019/11/18 23:23 <DIR> bin
2019/11/18 23:19 <DIR> boot
2019/11/19 10:38 94 run.bat
               1 個文件94 字節

 E:\ChezScheme\build\ChezScheme\bin 的目錄

2019/11/18 23:23 <DIR> .
2019/11/18 23:23 <DIR> ..
2019/11/18 23:19 <DIR> a6nt
               0 個文件0 字節

 E:\ChezScheme\build\ChezScheme\bin\a6nt 的目錄

2019/11/18 23:19 <DIR> .
2019/11/18 23:19 <DIR> ..
2019/11/18 20:25 764,928 csv953.dll
2019/11/18 20:25 7,102 csv953.exp
2019/11/18 20:25 1,581,688 csv953.ilk
2019/11/18 20:25 12,368 csv953.lib
2019/11/18 20:25 2,084,864 csv953.pdb
2019/11/18 20:25 112,640 scheme.exe
2019/11/18 20:25 430,080 scheme.pdb
               7 個文件4,993,670 字節

 E:\ChezScheme\build\ChezScheme\boot 的目錄

2019/11/18 23:19 <DIR> .
2019/11/18 23:19 <DIR> ..
2019/11/18 23:19 <DIR> a6nt
               0 個文件0 字節

 E:\ChezScheme\build\ChezScheme\boot\a6nt 的目錄

2019/11/18 23:19 <DIR> .
2019/11/18 23:19 <DIR> ..
2019/11/18 20:25 2,751,464 csv953md.lib
2019/11/18 20:25 2,564,910 csv953mt.lib
2019/11/18 17:14 36,556 equates.h
2019/11/18 20:24 27,609 mainmd.obj
2019/11/18 20:25 25,538 mainmt.obj
2019/11/18 17:14 1,624,450 petite.boot
2019/11/18 17:14 982,321 scheme.boot
2019/11/18 17:14 8,675 scheme.h
2019/11/18 20:24 92,444 scheme.res
               9 個文件8,113,967 字節

     所列文件總數:
              17 個文件13,107,731 字節
              14 個目錄514,061,447,168 可用字節

9,最後運行run.bat文件,就可以看到期待已久的Chez Scheme了:

Chez Scheme for Windows. make by bluedoctor. 2019.11.18
Chez Scheme Version 9.5.3
Copyright 1984-2019 Cisco Systems, Inc.

> (+ 1 2 3 4 5 6 7 8 9 10)
55
> (/ 1 3)
1/3
>

 

10,上面是在Chez Scheme運行的簡單Scheme程序,第一行代碼運行的是一個累加多個自然數的程序,如果用C#,需要一個List<int>變量來存儲列表數據,然後循環處理,代碼量要多好幾行。第二行Scheme代碼,它的結果直接以分數表示了,很高級。

有關Scheme更多的程序介紹,請看本文推薦的學習鏈接。如果你不想這麼麻煩的自己來編譯,也可以考慮直接使用給予.NET DLR的IronScheme,具體請看我原來的文章:《》。

如果你不想編譯或者安裝任何一個Scheme程序,但又想看看Scheme是什麼樣子,推薦訪問下面的網址,它提供了一個Web版本的Scheme編譯運行環境:

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

分類
發燒車訊

起站福島 東奧聖火傳遞路線輻射量仍超標

整理:鄒敏惠(環境資訊中心記者)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?

分類
發燒車訊

塞席爾特產 全球最大堅果海椰子瀕危

摘錄自2020年3月12日公視報導

來自印度洋群島國家塞席爾的特殊植物「海椰子」,擁有全世界最大的種子,果實又酷似女子的骨盆,而被人津津樂道,有些地區文化還將它視為愛情靈藥,但也因為濫採而面臨絕種危機。

海椰子的果肉每公斤價值可達約100美元,一個完整的空殼則可以賣出兩倍的價格。然而幾個世紀以來的過度開採,海椰子幾乎快要從世上消失。2011年,國際自然保護聯盟將海椰子列為「瀕危物種」。

海椰子的果實是全世界最大的堅果,塞席爾政府採取強硬措施保護,規定一年最多只能採收2000顆,並禁止整顆出口,嚴格管控限制買賣,希望藉此保護這項獨特的植物避免滅絕。

自然資源管理
永續發展
國際新聞
東非
印度洋
多群島國家
椰子

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

大陸寄台灣空運注意事項

大陸海運台灣交貨時間多久?

※避免吃悶虧無故遭抬價!台中搬家公司免費估價,有契約讓您安心有保障!

分類
發燒車訊

再生能源將取代石油、電動車將讓油價再次崩跌?從技術觀點分析其可能性

彭博(Bloomberg)於 2015 年 10 月報導稱,替代能源與節能科技發威,全球將步入電力富足年代;2016 年 2 月更進一步報導稱,電動車將造成下個石油崩跌危機,甚至指出石化燃料會愈來愈不重要、再生能源價格會持續下降、人類的能源不再是問題?但這些可能成真嗎?

原文中有許多樂觀的預測,包括:石化燃料生產成本低,原油價格將為每桶 50 美元而非 90 美元、10 年內太陽能的價格就能和石化燃料競爭、電動車將讓石油走上末路。最後的結論是:科技不斷創新,未來有望步入「電力富足年代」,電動車會造成下一次油價崩跌。   不過真會如此順利嗎?就現實的技術面來考量,可能未必。因為再生能源發展最大的困難在於成本太高、穩定度太低,目前都必須依靠政策補貼,否則難在市場中競爭,依照目前的技術發展現況,恐怕未來 10 年仍然難以改變,以下分別從技術觀點把目前市場上最被看好的幾種再生能源做簡單的介紹分析,並簡述其取代傳統能源的困難點。  
太陽電池與模組:價格已經接近成本價,難有大幅下降空間   太陽電池是目前最成熟的再生能源,上中下游已經形成完整的產業鏈,其中單晶矽晶圓能量轉換效率較高,但是長單晶的成本也高;多晶矽薄片能量轉換效率有待提升,成本仍然不夠低;非晶矽薄膜能量轉換效率太低,許多廠商開發多年仍然沒有進展,甚至有的已經倒閉。   因此說「10 年之內,太陽能的價格就能和石化燃料競爭」恐怕是不可能的事,目前的太陽電池與模組價格已經接近成本價,再降就得虧錢賣,即使廠商願意流血殺價競爭,一個虧錢賣的產業能支持多久呢?未來太陽能價格的確有機會和石化燃料競爭,但原因不是太陽能價格下跌,而是石化燃料價格上漲。  
生質能:成本過高,更會影響糧食供應   「生質能(Biomass energy)」是指利用生物所產生的有機物質,來轉換成可以利用的電能或熱能,目前主要是以動物或植物所提煉出來的油脂,經由轉脂化反應產生的「生質柴油(Biodiesel)」,麻瘋樹果實提煉的生質柴油是目前被業界認為最可行的方法之一。   此外,以植物(醣類)經由微生物發酵反應產生的「生質酒精(Bioethanol)」,玉米與甘蔗提煉的生質酒精是目前被業界認為最可行的方法之一,但是這些生質能的價格仍然遠高於石化燃料,而且一旦大量使用一定會影響到糧食供應,所以有人說:生質能是搶窮人的糧食做為富人的燃料(對生質能的原理有興趣的人可以參考這裡)。  
鋰電池:成熟商品,但充電是個大問題   可移動的能源除了生質能,使用鋰電池是目前被認為最可行的方法,由於鋰電池的能量密度夠高,因此才有美國 Tesla 公司設計與製造的電動汽車與台灣 Gogoro 公司設計與製造的電動機車。   鋰電池如何充電是個大問題,因為電動汽車的電池重達 200 公斤,很難由使用者如 Gogoro 機車那樣自行更換充電,只能以定點充電的方式進行,即使目前的規格要求在 1 小時內完成充電,使用者是否能在加「電」站等 1 小時卻是個問題。   如果必須把車開回家在停車場充電,最大的問題是目前的電力基礎建設不足,假設大樓停車場有 100 個停車位,每個都設置插座,當 100 輛電動車同時充電時,大樓的變壓器無法承受如此巨大的電流,整個電力基礎建設,包括變壓器、變電所、高壓電塔都必須重新設計才能達成,聽起來就不是短期內可以做到的事,就更別說這些電還是來自發電廠,結局還是要用火力、核能、水力發電來提供電力的。  
氫能與燃料電池:終極環保的再生能源?氫氣來源是個大問題   傳統電池直接使用化學反應產生能量,優點是能量轉換效率很高(80% 以上),但充電需要比較長的時間;而使用燃料以內燃機(汽車引擊)進行燃燒反應產生能量,優點是可以直接補充燃料,但使用內燃機的能量轉換效率很低(30% 以下),科學家開始思考,有沒有一種方法同時具有「電池」與「燃料」的優點呢?於是燃料電池就此誕生了。   燃料電池和傳統電池的原理相同,都是將活性物質的化學能轉換成電能,但是傳統電池的電極本身是活性物質,會參與化學反應;而燃料電池的電極本身只是儲存容器而已,並不會參與化學反應(觸媒只用來引發化學反應),必須將活性物質(氫氣或含氫原子的化合物)加入電池內(就好像我們的汽車補充燃料一樣),才能產生化學反應形成電能,是一種要補充燃料的電池,故稱為「燃料電池(Fuel cell)」。   燃料電池使用氫氣與氧氣反應產生水,反應後排放的氮化物或硫化物極少,幾乎沒有任何污染,因此被視為終極環保的再生能源,但是燃料電池必須使用氫氣做為燃料,卻成為最大的問題。   高壓儲氫技術如何把又大又重又危險的氫氣鋼瓶放在車上是個大問題;因此有國外公司開發出可以承受 700 大氣壓的航太複合材料儲氫瓶,能取代氫氣鋼瓶;Toyota 公司更在去年推出氫燃料電池車款 Mirai 創下單次加滿氫氣可行駛 500 公里的紀錄,已經是成功的商品了,那麼它的問題到底在那裡呢?  

▲ 複合材料儲氫瓶。(Source:)  

▲ 氫燃料電池車款 Mirai。(Source: CC BY 2.0)   首先車上放了一個壓力這麼大的儲氫瓶是否安全是個問題,氫氣的來源則是更大的問題,大家都知道電解水可以產生氫氣與氧氣,問題是電解水產生氫氣的成本很高,而且這些電來自發電廠,結局還是要用火力、核能、水力發電來提供電力,為了降於成本目前工業上主要是將碳氫化合物(石油)以「蒸氣重組(Steam reforming)」的方式分解生產氫氣,搞了半天還是要以石油做為原料,這樣石油的價格怎麼可能「崩跌」?   此外,低壓儲氫技術的平衡壓力低於 10 大氣壓,安全性比高壓儲氫技術高,但必須使用貴重或稀有金屬(例如鑭鎳合金)做為儲氫合金,因此成本偏高。如果使用甲醇取代氫氣做為燃料的轉換效率很低,觸媒通常含有貴重或稀有金屬,所以價格偏高,依照目前燃料電池發展的情況,還是以高壓複合材料儲氫瓶的可行性最高(對燃料電池的原理有興趣的人可以參考這裡;對燃料電池的儲氫技術原理有興趣的人可以參考這裡)。  
目前石化燃料低價在於市場競爭供過於求   每次原油價格大跌,市場往往會出現「石油不重要」的言論,2001 年知識經濟興起就有「實質資產價值將不再,能源對經濟的影響轉弱」的說法,沒想到接下來油價在人為炒作下一路走高到 2008 年每桶 148 美元,並且成為金融海嘯爆發的間接原因之一;如今油價跌到每桶 30 美元,立刻又有人提出了「石化燃料生產成本低,全球將步入電力富足年代」的說法。   目前油價偏低是人為操作所造成的,石油輸出國家組織(Organization of Petroleum Exporting Countries,OPEC)為了打擊美國業岩油產業,不惜殺價競爭,目的就是要以低油價迫使美國業岩油廠商破產倒閉以搶回石油產業的主導權。   若真的美國業岩油廠商倒光了,OPEC 還會讓石油維持在這麼低的價格嗎?因此低油價是短期的現象,或許就是這幾年的時間而已,未來太陽能的價格能和石化燃料競爭,不是因為太陽能價格下跌,而是因為石化燃料價格上漲。  
人類會繼續依賴石油,但程度可能緩慢降低   目前工程上還沒有出現終極的技術足以取代石油,因此未來人類仍然繼續依賴石油或其他可以燃燒的東西(天然氣、煤碳),但是依賴程度可能會隨著環保意識與新能源技術的發展而緩慢減低,要完全取代石油為時尚遠。  
結論   第一,石化燃料最近處於低價不是因為生產成本低,而是因為市場競爭供過於求,未來 OPEC 發動的價格戰結束,油價就會回到 50 美元以上,再長遠看未來可低價開採的石油儲存量枯竭,原油價格上漲是必然的趨勢,不要說 90 美元,超過 100 美元都是有可能的。   第二,2040 年再生能源市場蓬渤發展是很有可能的,但是要取代石化燃料主導電力供應的可能性不高,而且主要不是因為再生能源價格下跌,而是石化燃料價格上漲,當油價回到 100 美元以上,再生能原價格就會很有競爭力了。   第三,省電科技與各種節能技術減少了電力需求是確定的,但這樣就說未來有望步入「電力富足年代」是過於誇大了;電動車或燃料電池汽車的發展確實可以減少空氣污染與石化燃料的消耗,但是要完全取代石化燃料是不可能的。   目前最大的問題在於:電價太便宜造成使用者沒有節約用電的習慣,各種價格較高的家庭能源管理系統(Home Energy Management System,HEMS)乏人問津;而電價如果真的大漲又會造成物價波動,受限於選舉與政治因素,要讓電價上漲也是困難重重,「電力富足年代」之說恐怕倍受考驗。   (首圖來源: CC BY 2.0)   (本文授權轉載自《》─〈〉

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※專營大陸快遞台灣服務

台灣快遞大陸的貨運公司有哪些呢?