日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

Java初学者入门经典:面向对象的思维方法(其实同样非常适合C#的初学者)……非原创,作者忘了,非常抱歉...

發(fā)布時(shí)間:2023/12/13 C# 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java初学者入门经典:面向对象的思维方法(其实同样非常适合C#的初学者)……非原创,作者忘了,非常抱歉... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?

我是從學(xué)習(xí)Java編程開始接觸OOP(面向?qū)ο缶幊?span lang="en-us">),剛開始使用Java編寫程序的時(shí)候感覺很別扭,因?yàn)槲以缫粤?xí)慣用C來編寫程序,很欣賞C的簡(jiǎn)潔性和高效性,喜歡C簡(jiǎn)練而表達(dá)能力豐富的風(fēng)格,特別忍受不了Java運(yùn)行起來慢吞吞的速度,相對(duì)冗長(zhǎng)的代碼,而且一個(gè)很簡(jiǎn)單的事情,要寫好多類,一個(gè)類調(diào)用一個(gè)類,心里的抵觸情緒很強(qiáng)。

我對(duì)Java的面向?qū)ο蟮奶匦宰聊チ季?#xff0c;自認(rèn)為有所領(lǐng)悟,也開始有意識(shí)的運(yùn)用OOP風(fēng)格來寫程序,然而還是經(jīng)常會(huì)覺得不知道應(yīng)該怎樣提煉類,面對(duì)一個(gè)具體的問題的時(shí)候,會(huì)覺得腦子里千頭萬(wàn)緒的,不知道怎么下手,一不小心,又會(huì)回到原來的思路上去。

舉個(gè)例子,要發(fā)廣告郵件,廣告郵件列表存在數(shù)據(jù)庫(kù)里面。倘若用C來寫的話,一般會(huì)這樣思考,先把郵件內(nèi)容讀入,然后連接數(shù)據(jù)庫(kù),循環(huán)取郵件地址,調(diào)用本機(jī)的qmailsendmail命令發(fā)送。

然后考慮用Java來實(shí)現(xiàn),既然是OOP,就不能什么代碼都塞到main過程里面,于是就設(shè)計(jì)了三個(gè)類:

一個(gè)類是負(fù)責(zé)讀取數(shù)據(jù)庫(kù),取郵件地址,調(diào)用qmailsendmail命令發(fā)送;

一個(gè)類是讀郵件內(nèi)容,MIME編碼成HTML格式的,再加上郵件頭;

一個(gè)主類負(fù)責(zé)從命令讀參數(shù),處理命令行參數(shù),調(diào)用發(fā)email的類。

把一件工作按照功能劃分為3個(gè)模塊分別處理,每個(gè)類完成一件模塊任務(wù)。

仔細(xì)的分析一下,就會(huì)發(fā)現(xiàn)這樣的設(shè)計(jì)完全是從程序員實(shí)現(xiàn)程序功能的角度來設(shè)計(jì)的,或者說,設(shè)計(jì)類的時(shí)候,是自低向上的,從機(jī)器的角度到現(xiàn)實(shí)世界的角度來分析問題的。因此在設(shè)計(jì)的時(shí)候,就已經(jīng)把程序編程實(shí)現(xiàn)的細(xì)節(jié)都考慮進(jìn)去了,企圖從底層實(shí)現(xiàn)程序這樣的出發(fā)點(diǎn)來達(dá)到滿足現(xiàn)實(shí)世界的軟件需求的目標(biāo)。

這樣的分析方法其實(shí)是不適用于Java這樣面向?qū)ο蟮木幊陶Z(yǔ)言,因?yàn)?#xff0c;如果改用C語(yǔ)言,封裝兩個(gè)C函數(shù),都會(huì)比Java實(shí)現(xiàn)起來輕松的多,邏輯上也清楚的多。

我覺得面向?qū)ο蟮木柙谟诳紤]問題的思路是從現(xiàn)實(shí)世界的人類思維習(xí)慣出發(fā)的,只要領(lǐng)會(huì)了這一點(diǎn),就領(lǐng)會(huì)了面向?qū)ο蟮乃季S方法。

舉一個(gè)非常簡(jiǎn)單的例子:假使現(xiàn)在需要寫一個(gè)網(wǎng)頁(yè)計(jì)數(shù)器,客戶訪問一次頁(yè)面,網(wǎng)頁(yè)計(jì)數(shù)器加1,計(jì)數(shù)器是這樣來訪問的http://hostname/count.cgi?id=xxx

后臺(tái)有一個(gè)數(shù)據(jù)庫(kù)表,保存每個(gè)id(一個(gè)id對(duì)應(yīng)一個(gè)被統(tǒng)計(jì)訪問次數(shù)的頁(yè)面)的計(jì)數(shù)器當(dāng)前值,請(qǐng)求頁(yè)面一次,對(duì)應(yīng)id的計(jì)數(shù)器的字段加1(這里我們忽略并發(fā)更新數(shù)據(jù)庫(kù)表,出現(xiàn)的表鎖定的問題)

如果按照一般從程序?qū)崿F(xiàn)的角度來分析,我們會(huì)這樣考慮:首先是從HTTP GET請(qǐng)求取到id,然后按照id查數(shù)據(jù)庫(kù)表,獲得某id對(duì)應(yīng)的訪問計(jì)數(shù)值,然后加1,更新數(shù)據(jù)庫(kù),最后向頁(yè)面顯示訪問計(jì)數(shù)。

現(xiàn)在假設(shè)一個(gè)沒有程序設(shè)計(jì)經(jīng)驗(yàn)的人,他會(huì)怎樣來思考這個(gè)問題的呢?他會(huì)提出什么樣的需求呢?他很可能會(huì)這樣想:

我需要有一個(gè)計(jì)數(shù)器,這個(gè)計(jì)數(shù)器應(yīng)該有這樣的功能,刷新一次頁(yè)面,訪問量就會(huì)加1,另外最好還有一個(gè)計(jì)數(shù)器清0的功能,當(dāng)然計(jì)數(shù)器如果有一個(gè)可以設(shè)為任意值的功能的話,我就可以作弊了。

做為一個(gè)沒有程序設(shè)計(jì)經(jīng)驗(yàn)的人來說,他完全不會(huì)想到對(duì)數(shù)據(jù)庫(kù)應(yīng)該如何操作,對(duì)于HTTP變量該如何傳遞,他考慮問題的角度就是我有什么需求,我的業(yè)務(wù)邏輯是什么,軟件應(yīng)該有什么功能。

按照這樣的思路(請(qǐng)注意,他的思路其實(shí)就是我們平時(shí)在生活中習(xí)慣的思維方式),我們知道需要有一個(gè)計(jì)數(shù)器類 Counter,有一個(gè)必須的和兩個(gè)可選的方法:

getCount()

// 取計(jì)數(shù)器值方法

resetCounter()

// 計(jì)數(shù)器清0方法

setCount()

// 設(shè)計(jì)數(shù)器為相應(yīng)的值方法

?

Counter類完整的定義如下:

?

public class Counter

{

public int getCount(int id)

{

}

public void resetCounter(int id)

{

}

public void setCount

(int id, int currentCount)

{

}

}



解決問題的框架已經(jīng)有了,來看一下如何使用Counter。在count.cgi里面調(diào)用Counter來計(jì)數(shù),程序片斷如下:

// 這里從HTTP環(huán)境里面取id

...

Counter myCounter = new Counter();

// 獲得計(jì)數(shù)器

int currentCount = myCounter.getCount(id);

// 從計(jì)數(shù)器中取計(jì)數(shù)

// 這里向客戶瀏覽器輸出

...



程序的框架全都寫好了,剩下的就是實(shí)現(xiàn)Counter類方法里面具體的代碼了,此時(shí)才去考慮具體的程序語(yǔ)言實(shí)現(xiàn)的細(xì)節(jié),比如,在getCount()方法里面訪問數(shù)據(jù)庫(kù),更新計(jì)數(shù)值。

從上面的例子中看到,面向?qū)ο蟮乃季S方法其實(shí)就是我們?cè)诂F(xiàn)實(shí)生活中習(xí)慣的思維方式,是從人類考慮問題的角度出發(fā),把人類解決問題的思維方式逐步翻譯成程序能夠理解的思維方式的過程,在這個(gè)翻譯的過程中,軟件也就逐步被設(shè)計(jì)好了。

在運(yùn)用面向?qū)ο蟮乃季S方法進(jìn)行軟件設(shè)計(jì)的過程中,最容易犯的錯(cuò)誤就是開始分析的時(shí)候,就想到了程序代碼實(shí)現(xiàn)的細(xì)節(jié),因此封裝的類完全是基于程序?qū)崿F(xiàn)邏輯,而不是基于解決問題的業(yè)務(wù)邏輯。

學(xué)習(xí)JDBC編程的經(jīng)典錯(cuò)誤問法是:我怎樣封裝對(duì)數(shù)據(jù)庫(kù)的select操作?

面向?qū)ο蟮脑O(shè)計(jì)是基于解決業(yè)務(wù)問題的設(shè)計(jì),而不是基于具體編程技術(shù)的設(shè)計(jì)。我不會(huì)去封裝select語(yǔ)句的,我只封裝解決問題的業(yè)務(wù)邏輯,對(duì)數(shù)據(jù)庫(kù)的讀取是在業(yè)務(wù)邏輯的編碼實(shí)現(xiàn)階段才去考慮的問題。

回過頭看上面那個(gè)發(fā)廣告郵件的例子,應(yīng)該如何應(yīng)用面向?qū)ο蟮乃季S方法呢?

對(duì)于一個(gè)郵件來說,有郵件頭,郵件體,和郵件地址這三個(gè)屬性,發(fā)送郵件,需要一個(gè)發(fā)送的方法,另外還需要一個(gè)能把所有郵件地址列出來的方法。所以應(yīng)該如下設(shè)計(jì):

JunkMail

屬性:

head

body

address



方法:

sendMail()

// 發(fā)送郵件

listAllMail()

// 列郵件地址



Java來表示:

public class JunkMail

{

private String head;

private String body;

private String address;

public JunkMain()

{

// 默認(rèn)的類構(gòu)造器

// 從外部配置文件讀郵件頭和郵件體

this.head=...;

this.body=...;

}

?

public static boolean

sendMail(String address)

{

// 調(diào)用qmail,發(fā)送email

}

?

public static Collection listAllMail()

{

// 訪問數(shù)據(jù)庫(kù),返回一個(gè)郵件地址集合

}

}



當(dāng)把JunkMail設(shè)計(jì)好了以后,再調(diào)用JunkMail類完成郵件的發(fā)送,將是非常輕松的事情。

如果說傳統(tǒng)的面向過程的編程是符合機(jī)器運(yùn)行指令的流程的話,那么面向?qū)ο蟮乃季S方法就是符合現(xiàn)實(shí)生活中人類解決問題的思維過程。

在面向?qū)ο蟮能浖治龊驮O(shè)計(jì)的時(shí)候,要提醒自己,不要一上來就去想程序代碼的實(shí)現(xiàn),應(yīng)該拋開具體編程語(yǔ)言的束縛,集中精力分析我們要實(shí)現(xiàn)的軟件的業(yè)務(wù)邏輯,分析軟件的業(yè)務(wù)流程,思考應(yīng)該如何去描述和實(shí)現(xiàn)軟件的業(yè)務(wù)。畢竟軟件只是一個(gè)載體,業(yè)務(wù)才是我們真正要實(shí)現(xiàn)的目標(biāo)。

但是在設(shè)計(jì)過程中,心里卻往往在擔(dān)心,如果我完全不去考慮程序代碼的實(shí)現(xiàn)的話,那么我怎么知道我的設(shè)計(jì)一定合理呢?我怎么知道我設(shè)計(jì)的類、接口一定可以實(shí)現(xiàn)呢?所以經(jīng)常可以看到的現(xiàn)象就是:

在設(shè)計(jì)過程中,雖然知道不能過早考慮代碼實(shí)現(xiàn),但是每設(shè)計(jì)一個(gè)類,一個(gè)接口,心里都要不知不覺的用自己熟悉的編程語(yǔ)言大概的評(píng)估一下,看看能否編出來,因此,一不小心,就會(huì)又回到按照程序功能實(shí)現(xiàn)的思路進(jìn)行設(shè)計(jì)的老路上去了。

舉個(gè)例子來說明,在做Web程序設(shè)計(jì)的時(shí)候,經(jīng)常要遇到分頁(yè)顯示數(shù)據(jù)的情況。比如說需要把系統(tǒng)中所有的用戶都列出來這樣的功能。假設(shè)使用User類來表示用戶,增加用戶addUser(),刪除用戶deleteUser(),查詢所有用戶listUsers()方法。而數(shù)據(jù)庫(kù)中有一個(gè)user表,一條記錄是一個(gè)用戶的信息。下面考慮一下User類的方法的實(shí)現(xiàn):

addUser()
deleteUser()方法都好實(shí)現(xiàn),就是對(duì)數(shù)據(jù)庫(kù)增加記錄和刪除記錄。對(duì)于listUsers()方法,其實(shí)就是對(duì)user表的select,取出一個(gè)記錄集。但是該怎么從listUsers()方法中得到所有用戶的列表呢?

一個(gè)方法調(diào)用的返回值只有一個(gè),沒有多個(gè),所以很多情況下采用的辦法就是返回值定義為集合類型,比如Vector。這樣就可以在listUsers()方法的具體代碼實(shí)現(xiàn)的時(shí)候,從數(shù)據(jù)庫(kù)依次取出一個(gè)個(gè)記錄,插入到Vector里面來。在主程序里面,調(diào)用listUsers()方法可以返回一個(gè)Vector,然后再對(duì)Vector遍歷操作,就可以得到用戶列表了。

public class User

{

?

public static void addUser(...)

{

// 數(shù)據(jù)庫(kù)insert一條記錄

}

?

public static void deleteUser(...)

{

// 數(shù)據(jù)庫(kù)delete一條記錄

}

?

public Vector listUsers(...)

{

// 數(shù)據(jù)庫(kù)select結(jié)果放到一個(gè)集合里面

}

}



這樣的設(shè)計(jì)基本合理,但是仍然有點(diǎn)小問題。因?yàn)樵谠O(shè)計(jì)的時(shí)候,就考慮到了用Java的集合類Vector來實(shí)現(xiàn)對(duì)不定長(zhǎng)數(shù)據(jù)集的存放,因而違反了面向?qū)ο笤O(shè)計(jì)的一個(gè)原則:在設(shè)計(jì)的時(shí)候不應(yīng)過早的考慮具體程序語(yǔ)言的實(shí)現(xiàn)。所以必須用抽象的方法,和具體實(shí)現(xiàn)無關(guān)的方法來表達(dá)業(yè)務(wù)邏輯。

我們知道,通常對(duì)具有集合特征的數(shù)據(jù)結(jié)構(gòu)進(jìn)行遍歷通常可以使用nexthasNext方法,next實(shí)現(xiàn)取下一個(gè)用戶,hasNext判斷是否還有元素。 因此我們定義一個(gè)接口Iterator,這個(gè)接口中定義兩個(gè)方法nexthasNext

public interface Iterator

{

public boolean hasNext()

{

}

public Object next()

{

}

}

?

User類的listUses方法返回值

改為Iterator接口的實(shí)現(xiàn)類:

?

public class User

{

...

public Iterator listUsers()

{

}

...

}



這樣就把User類的設(shè)計(jì)和具體的實(shí)現(xiàn)方法分離開了,因?yàn)榇藭r(shí)任何實(shí)現(xiàn)了next()hasNext()方法的類都可以做為listUsers的返回值,都可以被用來表達(dá)用戶列表,而不僅僅可以使用Vector而已。

比如,我可以用ArrayList來表達(dá)用戶列表,因?yàn)?span lang="en-us">ArrayList也實(shí)現(xiàn)了Iterator,當(dāng)然我也可以自己專門寫一個(gè)類來存放用戶列表,只要實(shí)現(xiàn)next()hasNext()方法就行了。

這樣在具體的編寫代碼的時(shí)候,程序員具有了最大的靈活性,可以根據(jù)具體的情況,采用不同的編程方法來存放用戶列表。特別是降低了程序的耦合度,提高了程序的可移植性。對(duì)于上面那個(gè)JunkMaillistAllMail()方法也同樣應(yīng)該改為接口類型。

然后,在主程序里面就這樣來使用User類的listUsers方法:

User myUser = new User();

Iterator iterator = myUser.listUsers();

while (iterator.hasNext())

{

iterator.next();

}



這樣就可以完全不用考慮程序代碼實(shí)現(xiàn)了,從高層次上把功能抽象出來,定義成為接口,同時(shí)又可以把系統(tǒng)設(shè)計(jì)的很合理,完全根據(jù)業(yè)務(wù)的需求來進(jìn)行設(shè)計(jì)。

結(jié)語(yǔ)

通過上面的幾個(gè)例子的設(shè)計(jì)說明,使用面向?qū)ο蟮乃季S方法,其實(shí)是一個(gè)把業(yè)務(wù)邏輯從具體的編程技術(shù)當(dāng)中抽象出來的過程,而這個(gè)抽象的過程是自上而下的,非常符合人類的思維習(xí)慣,也就是先不考慮問題解決的細(xì)節(jié),把問題的最主要的方面抽象成為一個(gè)簡(jiǎn)單的框架,集中精力思考如何解決主要矛盾,然后在解決問題的過程中,再把問題的細(xì)節(jié)分割成一個(gè)一個(gè)小問題,再專門去解決細(xì)節(jié)問題。

因而一旦牢牢的抓住了這一點(diǎn),你就會(huì)發(fā)現(xiàn)在軟件設(shè)計(jì)和開發(fā)過程中,你自己總是會(huì)不知不覺的運(yùn)用面向?qū)ο蟮乃季S方法來設(shè)計(jì)和編寫程序,并且程序的設(shè)計(jì)和開發(fā)也變得不再那么枯燥,而一個(gè)合理運(yùn)用面向?qū)ο蠹夹g(shù)進(jìn)行設(shè)計(jì)和架構(gòu)的軟件,更是具備了思維的藝術(shù)美感。最后,愿面向?qū)ο蟮乃季S方法也能給您的程序設(shè)計(jì)之路帶來創(chuàng)作的樂趣。

轉(zhuǎn)載于:https://www.cnblogs.com/FlyEagle/archive/2005/08/23/220931.html

總結(jié)

以上是生活随笔為你收集整理的Java初学者入门经典:面向对象的思维方法(其实同样非常适合C#的初学者)……非原创,作者忘了,非常抱歉...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 天天躁日日躁狠狠躁喷水 | 一区二区男女 | 国产精品亚洲lv粉色 | 中文字幕亚洲激情 | 动漫av在线免费观看 | 国产精品腿扒开做爽爽爽挤奶网站 | 91爱啪啪| 国产一级在线免费观看 | 亚洲精品一区二三区不卡 | 丰满少妇在线观看bd | 国产亚洲av综合人人澡精品 | 欧美日韩国产第一页 | 国产精品成人无码专区 | 午夜不卡久久精品无码免费 | 在线观看av日韩 | 男生和女生一起搞鸡 | 秋霞在线观看秋 | 老司机午夜精品 | 四虎免费观看 | 久草视频免费在线播放 | 西西午夜影院 | 韩日黄色| 99爱免费视频 | 亚洲色图视频在线 | 久久久久国色av免费观看性色 | 韩国毛片一区二区 | 日本高清不卡码 | 日本欧美中文字幕 | 亚洲一区精品视频 | 亚洲欧美制服丝袜 | 亚洲国产精品久久AV | 野战少妇38p | 亚洲视屏 | 精品人妻一区二区三区麻豆91 | 蜜臀尤物一区二区三区直播 | 国产一级aa大片毛片 | 精品一区二区三区视频日产 | 人妻 校园 激情 另类 | 91av国产精品| 性欧美一区二区 | 在线观看的网站 | 成人福利在线观看 | 一本色道久久综合无码人妻 | 亚洲二区在线观看 | 人妻无码久久精品人妻 | 377p粉嫩大胆色噜噜噜 | 激情网五月天 | 91一区在线 | 国产涩涩| 国产女主播视频 | 四虎精品永久在线 | 中国特级黄色大片 | www.成人av | 天天都色 | 人人超碰在线 | jizz教师| 激情四射av | 91影院在线| 欧美一区二区免费电影 | 国产高清在线观看 | 日韩av中文字幕在线 | 一级黄色大片免费 | 亚洲精品一区二三区 | 午夜精品电影 | 久久久看 | 天天操天天操天天操 | 久久国产区| 精人妻一区二区三区 | 久草婷婷 | jizz国产在线观看 | 日韩国产一区二区 | 亚洲国产综合视频 | 九九热国产视频 | 日韩精品久久一区 | 国产剧情精品 | 少妇导航av| 欧美三级午夜理伦三级 | 亚洲精品中文字幕乱码无线 | 亚洲伊人婷婷 | 天堂久久一区 | 自拍偷自拍亚洲精品播放 | 一级黄色片免费在线观看 | 涩涩视屏 | 久久人人爽人人人人片 | 免费国产在线观看 | a网站在线 | 亚洲v国产| 国产美女一区二区三区 | 一区二区三区欧美日韩 | 精品视频一区二区 | 午夜激情啪啪 | 美女啪啪网 | 日日撸夜夜撸 | 免费观看国产视频 | 美女扒开内看个够网站 | 久久福利精品 | 亚洲欧美国产另类 | 久久视| 欧洲精品一区二区三区久久 |