<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    和風(fēng)細雨

    世上本無難事,心以為難,斯乃真難。茍不存一難之見于心,則運用之術(shù)自出。

    從薪水計算的例子看一段程序在不同環(huán)境中的變化

    本例完整程序下載: http://m.tkk7.com/Files/sitinspring/TaxCaculator20071025203159.rar

    世界天天在變,程序也一樣,唯一不變的只有變化二字.現(xiàn)代程序應(yīng)該隨著日新月異的環(huán)境而不斷變化,此之謂"物競天擇,適者生存",下面的例子就演示了這一變化過程.

    需求如下:(注:非真實稅率,僅僅是個例子)
        稅后薪水=月總收入×適用稅率-速算扣除數(shù)

    級 數(shù) 全月應(yīng)納稅所得額 稅率(%)  稅率      速算扣除數(shù)
      1     不超過500元的                                 5%
      2     超過500元至2000元的部分              10%          25
      3     超過2000元至5000元的部分            15%         125
      4     超過5000元至20000元的部分          20%         375
      5     超過20000元的部分                          25%         1375


    如果讓你來為下列需求書寫一段代碼,你將如何處理


    1.過程式方法:
    如果說需求(稅率和扣除數(shù))在較長一段時間內(nèi)不會變化,也就是說需求變化時,程序生命已經(jīng)結(jié)束,我們可以使用傳統(tǒng)的分支語句來編碼,程序?qū)懗鰜順O簡單.

    package com.sitinspring.processstyle;

    /**
     * Main函數(shù)所在的類
     * 
    @author sitinspring(junglesong@gmail.com)
     *
     
    */

    public class Main{
        
    public static void main(String[] args){        
            
    for(double total=100;total<30000;total+=1000){
                System.out.println(
    "稅前薪水="+total+" 稅后薪水="+getSalary(total));
            }
            
        }

        
        
    // 傳統(tǒng)的過程式計算方法
        public static double getSalary(double total){
            
    double retval;
            
            
    if(total < 500){
                retval
    =total*(1-0.05);
            }

            
    else if(total < 2000){
                retval
    =total*(1-0.1)-25;
            }

            
    else if(total < 5000){
                retval
    =total*(1-0.15)-125;
            }

            
    else if(total < 20000){
                retval
    =total *(1-0.20)-375;
            }

            
    else{
                retval
    =total *(1-0.25)-1375;
            }


            
    return retval;
        }

    }

    2.OO化的方法
    但是如果說需求(稅率和扣除數(shù))在軟件生命已經(jīng)結(jié)束前是有可能變化的,或者說變化不可預(yù)期,用戶一定程序上也希望自己修改,IF分支的結(jié)構(gòu)將不再適用,但程序可以停止,這時就應(yīng)該把分支語句OO化,將規(guī)則和數(shù)據(jù)分離開來可以了,至于數(shù)據(jù)是固化在程序中還是啟動時載入可以視情況確定,例子中采取了固化的方式,一般來說用XML文件記錄數(shù)據(jù)較好,改起來很方便.

    Main類:
    package com.sitinspring.oostyle;

    /**
     * Main函數(shù)所在的類
     * 
    @author sitinspring(junglesong@gmail.com)
     *
     
    */

    public class Main{
        
    public static void main(String[] args){    
            SalaryCaculator caculator
    =new SalaryCaculator();
            
            
    for(double total=100;total<30000;total+=1000){
                System.out.println(
    "稅前薪水="+total+" 稅后薪水="+caculator.getSalaryAfterTax(total));
            }
            
        }

    }

    SalaryCaculator類(其中99999999表示極大值,一般收入都小于這個值):
    package com.sitinspring.oostyle;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    /**
     * 工資計算類
     * 
    @author sitinspring(junglesong@gmail.com)
     *
     
    */

    public class SalaryCaculator{
        
    private List<SalaryGrade> grades;
        
        
        
    public SalaryCaculator(){
            grades
    =new ArrayList<SalaryGrade>();
            
            grades.add(
    new SalaryGrade(500,0.05,0));
            grades.add(
    new SalaryGrade(2000,0.1,25));
            grades.add(
    new SalaryGrade(5000,0.15,125));
            grades.add(
    new SalaryGrade(20000,0.20,375));
            grades.add(
    new SalaryGrade(99999999,0.25,1375));
        }

        
        
    // OO化的查詢方法
        public double getSalaryAfterTax(double total){
            SalaryGrade taxGrade
    =null;
            
            
    for(Iterator it=grades.iterator();it.hasNext();){
                taxGrade
    =(SalaryGrade)it.next();
                
                
    if(total>taxGrade.getGrade()){
                    
    continue;
                }

                
    else{
                    
    break;
                }

            }

            
            
    return total*(1-taxGrade.getRatio())-taxGrade.getDiscount();
        }

    }

    SalaryGrade類:
    package com.sitinspring.oostyle;

    /**
     * 工資等級類
     * 
    @author sitinspring(junglesong@gmail.com)
     *
     
    */

    public class SalaryGrade {
        
    // 月薪界限
        private double grade;

        
    // 稅率
        private double ratio;

        
    // 折扣
        private double discount;

        
    public SalaryGrade(double grade, double ratio, double discount) {
            
    this.grade = grade;
            
    this.ratio = ratio;
            
    this.discount = discount;
        }


        
    public SalaryGrade() {
            
    this(0.0f0.0f0.0f);
        }


        
    public double getDiscount() {
            
    return discount;
        }


        
    public double getGrade() {
            
    return grade;
        }


        
    public double getRatio() {
            
    return ratio;
        }

    }

    3.線程安全的OO方法
    如果說需求(稅率和扣除數(shù))是人為動態(tài)指定的,且整個系統(tǒng)是7*24小時的系統(tǒng),一般不允許停機.這樣的情況下要求程序具有熱插拔的能力,這時,我們必須加上一個讀寫鎖才能解決問題.

    Main類:
    package com.sitinspring.dynamicoostyle;

    import java.util.ArrayList;
    import java.util.List;

    import com.sitinspring.oostyle.SalaryGrade;

    /**
     * Main函數(shù)所在的類
     * 
     * 
    @author sitinspring(junglesong@gmail.com)
     * 
     
    */

    public class Main {
        
    public static void main(String[] args) {
            SalaryCaculator caculator 
    = new SalaryCaculator();
            
            List
    <SalaryGrade> grades1 = new ArrayList<SalaryGrade>();
            grades1.add(
    new SalaryGrade(5000.050));
            grades1.add(
    new SalaryGrade(20000.125));
            grades1.add(
    new SalaryGrade(50000.15125));
            grades1.add(
    new SalaryGrade(200000.20375));
            grades1.add(
    new SalaryGrade(999999990.251375));        
            Writer writer1
    =new Writer(caculator,grades1);
            
            List
    <SalaryGrade> grades2 = new ArrayList<SalaryGrade>();
            grades2.add(
    new SalaryGrade(50000.5125));
            grades2.add(
    new SalaryGrade(999999990.91375));        
            
            Writer writer2
    =new Writer(caculator,grades2);

            
    while (true{            
                
    for (double total = 100; total < 30000; total += 1000{
                    sleep(
    1);
                    System.out.println(
    "稅前薪水=" + total + " 稅后薪水="
                            
    + caculator.getSalaryAfterTax(total));
                }

            }

        }

        
        
    // 用于延時
        public static void sleep(int sleepSecond){
            
    try{
                Thread.sleep(sleepSecond
    *1000);
            }

            
    catch(Exception ex){
                ex.printStackTrace();
            }

        }

    }

    ReadWriteLock類:
    package com.sitinspring.dynamicoostyle;

    /**
     * 讀寫鎖,用于線程控制
     * 
    @author sitinspring(junglesong@gmail.com)
     *
     
    */

    public class ReadWriteLock{
        
    // 讀狀態(tài)
        private boolean isRead;
        
        
    // 寫狀態(tài)
        private boolean isWrite;
        
        
    public synchronized void readLock(){
            
    // 有寫入時讀取線程停止
            while(isWrite){
                
    try{    
                    System.out.println(
    "有線程在進行寫入,讀取線程停止,進入等待狀態(tài)");
                    wait();
                }

                
    catch(InterruptedException ex){
                    ex.printStackTrace();
                }

            }

            
            System.out.println(
    "設(shè)定鎖為讀取狀態(tài)");
            isRead
    =true;
        }

        
        
    public synchronized void readUnlock(){
            System.out.println(
    "解除讀取鎖");
            isRead
    =false;
            notifyAll();
        }

        
        
    public synchronized void writeLock(){
            
    // 有讀取時讀取線程停止
            while(isRead){
                
    try{    
                    System.out.println(
    "有線程在進行讀取,寫入線程停止,進入等待狀態(tài)");
                    wait();
                }

                
    catch(InterruptedException ex){
                    ex.printStackTrace();
                }

            }

            
            
    // 有寫入時寫入線程也一樣要停止
            while(isWrite){
                
    try{    
                    System.out.println(
    "有線程在進行寫入,寫入線程停止,進入等待狀態(tài)");
                    wait();
                }

                
    catch(InterruptedException ex){
                    ex.printStackTrace();
                }

            }

            
            System.out.println(
    "設(shè)定鎖為寫入狀態(tài)");
            isWrite
    =true;
        }

        
        
    public synchronized void writeUnlock(){
            System.out.println(
    "解除寫入鎖");
            isWrite
    =false;
            notifyAll();
        }

    }

    SalaryCaculator類:
    package com.sitinspring.dynamicoostyle;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    import com.sitinspring.oostyle.SalaryGrade;

    /**
     * 工資計算類
     * 
     * 
    @author sitinspring(junglesong@gmail.com)
     * 
     
    */

    public class SalaryCaculator {
        
    private List<SalaryGrade> grades;

        
    private ReadWriteLock readWriteLock;

        
    public SalaryCaculator() {
            readWriteLock 
    = new ReadWriteLock();

            grades 
    = new ArrayList<SalaryGrade>();

            grades.add(
    new SalaryGrade(5000.050));
            grades.add(
    new SalaryGrade(20000.125));
            grades.add(
    new SalaryGrade(50000.15125));
            grades.add(
    new SalaryGrade(200000.20375));
            grades.add(
    new SalaryGrade(999999990.251375));
        }


        
    // 線程安全的,OO化的查詢方法
        public double getSalaryAfterTax(double total) {
            
    try {
                readWriteLock.readLock();

                SalaryGrade taxGrade 
    = null;

                
    for (Iterator it = grades.iterator(); it.hasNext();) {
                    taxGrade 
    = (SalaryGrade) it.next();

                    
    if (total > taxGrade.getGrade()) {
                        
    continue;
                    }
     else {
                        
    break;
                    }

                }


                
    return total * (1 - taxGrade.getRatio()) - taxGrade.getDiscount();
            }
     finally {
                readWriteLock.readUnlock();
            }

        }


        
    public void setGrades(List<SalaryGrade> grades) {
            
    try {
                readWriteLock.writeLock();
                
    this.grades = grades;
            }
     finally {
                readWriteLock.writeUnlock();
            }

        }

    }

    Writer類(模擬人工寫入):
    package com.sitinspring.dynamicoostyle;

    import java.util.List;
    import java.util.Random;

    import com.sitinspring.oostyle.SalaryGrade;

    /**
     * 更新工資等級的線程
     * 
     * 
    @author sitinspring(junglesong@gmail.com)
     * 
     
    */

    public class Writer implements Runnable {
        
    private static final Random random = new Random();

        
    private SalaryCaculator caculator;

        
    private List<SalaryGrade> grades;

        
    public Writer(SalaryCaculator caculator, List<SalaryGrade> grades) {
            
    this.caculator = caculator;
            
    this.grades = grades;

            Thread thread 
    = new Thread(this);
            thread.start();
        }


        
    public void run() {
            
    while (true{
                
    try {
                    Thread.sleep(random.nextInt(
    3* 1000);
                }
     catch (Exception ex) {
                    ex.printStackTrace();
                }


                caculator.setGrades(grades);
            }

        }

    }

    雖然上述三段程序大小和復(fù)雜度各不一樣,但它們沒有優(yōu)劣之分,各自都是適應(yīng)環(huán)境的產(chǎn)物,沒有一種程序結(jié)構(gòu)能包打天下,但我們需要知道根據(jù)客觀情況選取不同的結(jié)構(gòu),這樣才能創(chuàng)造出優(yōu)秀的程序.

    以上

    posted on 2008-02-22 11:27 和風(fēng)細雨 閱讀(245) 評論(0)  編輯  收藏 所屬分類: OOP


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲另类少妇17p| 四虎永久在线精品免费观看地址| 99无码人妻一区二区三区免费| 手机看黄av免费网址| 午夜毛片不卡免费观看视频| 亚洲国产成人精品久久久国产成人一区二区三区综 | 337p日本欧洲亚洲大胆艺术| 亚洲国产中文在线二区三区免| 亚洲人成电影网站免费| 青娱乐在线免费观看视频| 丝瓜app免费下载网址进入ios| 99久久精品免费精品国产| 天天摸天天碰成人免费视频| 亚洲日本在线观看视频| 亚洲美女aⅴ久久久91| 亚洲AV香蕉一区区二区三区| 国产免费网站看v片在线| 黄瓜视频影院在线观看免费| 免费国产怡红院在线观看| 无码乱人伦一区二区亚洲| 亚洲日韩一区精品射精| 久久久精品视频免费观看| 国产福利视精品永久免费| 亚洲国产午夜福利在线播放 | 亚洲国产精久久久久久久| 亚洲精华国产精华精华液好用 | 免费的黄色的网站| 国产精成人品日日拍夜夜免费| 日韩吃奶摸下AA片免费观看| 亚洲综合色在线观看亚洲| 91亚洲性爱在线视频| 国产成人精品免费大全| 99国产精品永久免费视频| 国产成人毛片亚洲精品| 久久精品国产亚洲AV蜜臀色欲 | 韩国二级毛片免费播放| 亚洲精品乱码久久久久久中文字幕| 激情五月亚洲色图| 中文在线日本免费永久18近| 成人a视频片在线观看免费| 亚洲AV无码专区在线播放中文|