一家反欺詐公司的面試經歷——1.java的設計模式
前言:
平常我們都在敲程式碼,為了要實現一些我們希望看到的功能,敲一大堆一大堆。往往就會忽略了這樣的一個問題。
你會問敲程式碼就讓我們老老實實的敲程式碼吧,為什麼要那麼麻煩的去考慮那麼多?當然了現在這樣一說你肯定會回答我們肯定不可能就一心只會死頭死腦的無腦敲程式碼啊。是吧?那麼我們還要考慮一些什麼事情呢?這麼跟大家說吧,我們現在敲程式碼做專案就像做房子,現在我們做的事情是,一塊一塊的不斷的壘磚塊,無腦壘。而不管他壘的好不好看美不美觀,也不管他消耗的磚塊是否太多。是不是?再打個比方,從小學起我們就開始拿著筆寫作文。剛剛開始那個時候,還記得自己是怎麼寫作文的麼?是不是照著課本寫?又或者就是寫一些流水賬似的東西?記得那個時候能夠記兩筆流水賬已經能夠讓自己激動不已了是吧?呵呵。那你還記得是從什麼時候開始,老師開始給你講文章的結構文章的排篇佈局,開始給你介紹各種諸如開門見山等等的文章寫法的?今天就讓我們回到那個時候。
接下來我們開始接觸一些比較常用的java設計模式。
單例模式:
單例就是:保證一個類僅有一個例項,僅提供一個訪問它的全域性訪問點。
他的適用性在於:
1.當類只能有一個例項而且客戶可以從一個眾所周知的訪問點訪問它時。
2.當這個唯一例項應該是通過子類化可擴充套件的,並且客戶應該無需更改程式碼就能使用一個擴充套件的例項時。
話不多說,請君看我程式碼示例:
Java程式碼
public class Singleton { private static Singleton sing; private Singleton() { } public static Singleton getInstance() { if (sing == null) { sing = new Singleton(); } return sing; } }
public class Test { public static void main(String[] args) { Singleton sing = Singleton.getInstance(); Singleton sing2 = Singleton.getInstance(); System.out.println(sing); System.out.println(sing2); } }
工廠模式:
你可以從網上找到許許多多關於這個(java設計模式)的文件與資料,如果你下載過看過不止四五份你就會發現,雖然他們的說法都有自己的一套,但是總是有千人一面的地方。而我要告訴你的是,這一面,就是你所需要的東西了。
對於工廠模式而言,每個人都會有自己的體會與看法。就比如有的人說他是將程式碼按照其功能模組化了,也有人說他就是一個分配機制,好比把不同的工作交給不同的人去做一樣,將物件的功能的實現交給一些特製的類去完成,等等等等。只要是接觸過的人,就可以說出一種他的立場上看到的工廠模式。
但是在這裡我要告訴你的是,工廠模式他的關鍵是:將建立物件和使用物件分開。在這樣的一個過程中不僅僅達到了理清編寫者自己思路的作用,也使得程式碼脈絡更加清晰明朗,簡潔易懂。不知道大家還記不記得曾經講哈夫曼樹的時候那棵充斥我們一個多禮拜的哈夫曼樹?我想說,現在這棵樹是沒了,但是重新出現了一座龐大的工廠……在這個工廠裡邊分工明確權責分明,他的每一個子工廠都只負責生產某一種特別的產品,而每一種產品也對應著每一個子工廠的生產線。現在只要想編寫一個程式,就不知道絕的先考慮將它“工廠化”,將它的每一個步驟每一個功能先大卸八塊的區分清楚,然後才開始程式碼的實際編寫工作……
好了,閒話就不多說了,下面我們就通過例項來講講什麼是建立物件和使用物件分開。
(例)
比如我想造一輛寶馬車並讓它跑起來,以前我們都是寫一個寶馬車的類然後直接在這個類裡邊例項化一個他的物件,完了以後緊接著在下邊寫寶馬車的跑的方法,是吧?但是工廠模式不這麼做,工廠模式怎麼做呢?請看下面的步驟:
1.寫一個車的介面,並在裡邊定義一個車的go()方法:
public interface Car {
public void go();
}
2.寫一個寶馬車的類,讓他去繼承上面這個車的總介面,並且實現裡邊的方法:
Java程式碼
public class BMW implements Car{
public void go() {
}
}
3.是不是少了什麼?呵呵你有車的介面和實現類了當然得有造車工廠咯,是吧?於是我們同樣給它定義一個造車工廠總介面以及一個繼承並且實現它的寶馬造車工廠:
public interface CarFactory {
public Car build(String name) ;
}
public class BMWFactory implements CarFactory{
private static BMWFactory ins;
public static BMWFactory getIns(){
if(null==ins){
ins=new BMWFactory();
}
return ins;
}
BMWFactory(){}
public Car build(String name) {
if(name.equals("BMW")){
return new BMW();
}
return null;
}
}
4.有的人就會有點牢騷了,我不想老是自己跑工廠去,那樣多麻煩!是吧?好,那麼我們就給他寫一個且車代理商:
public class AgentFactor {
private static AgentFactor ins;
public static AgentFactor getIns(){
if(ins==null){
ins=new AgentFactor();
}
return ins;
}
//取得制定品牌 的汽車
public CarFactory getCarFactor(String Name){
if(Name.equals("BMW")){
return new BMWFactory();
}
return null;
}
}
5.好了,車有了,造車工廠有了,連代理商都給你搞定了,那麼就讓我們來寫個主函式讓我們的寶馬車跑起來吧!
public class CarTest {
public void driver(){
CarFactory ic=AgentFactor.getIns().getCarFactor("BMW");
Car mini=ic.build("MINI");
mini.go();
}
}
當然了,也不是真的就讓上面的程式碼跑起來,細心如你,肯定會發現上面的這幾行程式碼是跑不起來的,是不是?具體是為什麼呢,哈哈就留給你咯!
雖然上面給大家的幾行程式碼不能夠直接跑起來,但是通過他們,我想大家對於工廠模式這個概念應該會有一個比較清晰的把握了吧。再次說一遍:工廠模式,就是將物件的建立與使用分開。這樣做的目的,自己開動腦經咯~
事件監聽模式:
相信大家接觸java以來就一直在跟滑鼠監聽器等等各種事件監聽器打交道,對於這些個零零總總的各式各樣的監聽器也並不陌生吧?但是對於這些滑鼠監聽器啊鍵盤監聽器啊什麼的,他的具體的實現方式是怎麼樣的你是否清楚呢?如果你是一個足夠細心而好學的人,那麼我接下來要說的東西對你來說可能是沒什麼必要的了,因為你肯定看過這些監聽器它的原始碼,也必然知道他的執行機制與原理了。
下面讓我們用程式碼例項來看一看這事件監聽的原型吧!
(例)在做通訊的時候我們曾經做過收到訊息並且讓他顯示在一個JTEXTAREA上面,但是若我想要讓他顯示在JLABEL上的話就得對程式碼進行一些聯動的改動,很是麻煩。我們且看事件監聽模式怎麼解決這個問題:
1.寫一個訊息的介面,在裡邊定義幾項訊息的基本屬性:
Java程式碼
//定義一個訊息介面,所有的訊息都是他的實現類
public interface Msg {
public byte getType();//返回訊息型別
public String getText();//返回訊息內容
}
2.寫一個具體的訊息類,繼承訊息介面:
Java程式碼
public class TextMsg implements Msg{
private String text;
//具體的訊息類,繼承訊息介面
public TextMsg(String text){
this.text=text;
}
public String getText() {
return this.text;
}
public byte getType() {
return 2;
}
}
3.第三布我們要做的是,編寫一個監聽器介面:
Java程式碼
//處理器介面定義
public interface MsgProcess {
//具體的處理器,所有的處理器實現類都必須實現這個方法
void processMsg(Msg msg);
}
4.編寫你需要的監聽器,比如你想讓訊息呈現在JLABEL上:
Java程式碼
import javax.swing.JLabel;
public class JLabelProcess extends JLabel implements MsgProcess{
public void processMsg(Msg msg) {
String t=msg.getText();
this.setText(t);
System.out.println(t);
}
}
如果你還想讓訊息顯示在其他地方,比如,JBUTTON上,你可以另外寫一個監聽器的類繼承上面的監聽器介面:
Java程式碼
import javax.swing.JButton;
public class JButtonProcess extends JButton implements MsgProcess{
public void processMsg(Msg msg) {
String t=msg.getText();
this.setText(t);
}
}
5.編寫一個執行緒,我們將模擬生成訊息(事件源)放在這個執行緒裡邊來做:
Java程式碼
public class NetConn extends Thread{
//儲存事件監聽器的佇列
ArrayList<MsgProcess> ips=new ArrayList<MsgProcess>();
public void addMsgProcess(MsgProcess p){
ips.add(p);
}
public void run(){
//模擬事件源
int i=0;
while(true){
Msg s=new TextMsg("我收到的訊息是:"+i);
i++;
for(int t=0;t<ips.size();t++){
MsgProcess pro=ips.get(t);
pro.processMsg(s);
}
try {
this.sleep(1000);
} catch (InterruptedException e) {e.printStackTrace();}
}
}
}
6.好的,做完了上面的這些工作,接下來就讓我們來寫一個主函式吧:
Java程式碼
import java.awt.FlowLayout;
import javax.swing.JFrame;
public class Main {
public static void main(String srga[]){
NetConn nc=new NetConn();
nc.start();
JLabelProcess lp=new JLabelProcess();
nc.addMsgProcess(lp);
JButtonProcess tp=new JButtonProcess();
nc.addMsgProcess(tp);
JFrame jf=new JFrame("test");
jf.add(tp);
jf.setSize(300,300);
jf.setLayout(new FlowLayout());
jf.add(lp);
jf.setVisible(true);
jf.setDefaultCloseOperation(3);
}
}
事件監聽模式介紹到這裡你是不是心裡隱隱感覺,這個世界上的好多事情都變成了一個個事件源和一個個監聽處理器了?如果對於事件監聽模式還有一些不解或者困惑,請細心看上面提供的程式碼示例,慢慢體會它裡邊所蘊含的一些東西,相信你會獲得意想不到的收穫的!