設計模式
簡單工廠模式--->靜態工廠方法模式
設計一個工廠類:
工廠類提供一些靜態方法,間接的去創建具體的對象
優點:
不需要在創建具體類的對象,而是把創建的工作交給了工廠類來創建!
弊端:
如果有新的對象增加,或者某些對象的創建方式不同,就需要不斷的修改工廠類,不利於後期的維護
工廠方法模式:
提供一個抽象類(抽象工廠)還需要提供一個接口(工廠接口),每一個具體的類都有對應的工廠類(實現工廠接口)
具體對象的創建工作由繼承抽象工廠的具體類實現
優點:
客戶端不需要在負責對象的創建(不需顯示創建具體對象),從而明確了各個類的職責,
如果有新的對象增加,只需要增加一個具體的類和具體的工廠類即可,不影響已有的代碼,後期維護容易,增強了系統的 擴展性
弊端:
書寫代碼量大了!
public static void main(String[] args) { //創建Factory對象 //接口多態的形式 Factory f = new CatFactory() ; Animal a = f.creatAnimal() ; a.eat(); System.out.println("-------------------"); f = new DogFactory() ; a = f.creatAnimal() ; a.eat(); }
單例模式
設計模式之單例模式:
單例模式核心思想:
某些類的對象在創建的時候 ,在系統內存始終只有一個對象!
單例模式分類:
1)餓漢式 2)懶漢式(類似於多線程環境..)
兩種分類在設計上幾乎一樣:
1)定義個類,將該類的無參構造方法私有化
2)在該類的成員位置創建該類對象 並且一定要私有化,防止外界更改這個對象
3)在該類中提供靜態成員方法(返回值就是創建的那個對象),能被當前類直接調用,static修飾
餓漢式:
在加載那個類的時候,對象的創建工作就已經完成了!
符合單例模式核心思想
1)自定義一個類,將無參構造私有化
2)在成員位置聲明變量
3)提供公共靜態功能,在裏面判斷的創建該類對象,返回該類對象
如果是開發中,那麼就使用餓漢式(餓漢式它不會出現問題的單例模式)
如果是面試中,那麼使用懶漢式(因爲他是可能出現問題的一種單例模式)
public class Teacher {
private Teacher() {
}
private static Teacher t = null ;
//靜態的同步方法 (鎖對象: 類名.class)
public synchronized static Teacher getTeacher() {
if(t==null) {
t = new Teacher() ;
}
return t ;
}
}
懶漢式(延遲加載 -->懶加載)
可能會出現問題
---> 多線程的問題
--->校驗多線程安全問題的標準
1)是否是多線程環境
2)是否有共享數據
3)是否有多條語句對共享數據進行操作 (使用同步機制進行操作)
public class Student {
//無參構造私有化,目的爲了防止用戶創建對象的時候,會產生多個對象!
//爲了不讓直接通過構造方法創建該類對象
//成員位置創建該類的實例
//靜態方法只能訪問靜態變量
//加入私有修飾
private static Student s = new Student() ; //靜態的類變量
//提供一個公共的成員方法
public static Student getStudent() {
return s ;
}
}
//無參構造私有化,目的爲了防止用戶創建對象的時候,會產生多個對象!
//爲了不讓直接通過構造方法創建該類對象
//成員位置創建該類的實例
//靜態方法只能訪問靜態變量
//加入私有修飾
private static Student s = new Student() ; //靜態的類變量
//提供一個公共的成員方法
public static Student getStudent() {
return s ;
}
}
Runtime類
每個 Java 應用程序都有一個 Runtime 類實例,使應用程序能夠與其運行的環境相連接。
public static Runtime getRuntime() 返回與當前 Java 應用程序相關的運行時對象
public Process exec(String command)
throws IOException在單獨的進程中執行指定的字符串命令。
public static void main(String[] args) throws IOException {
//創建Runtime類的實例
Runtime r = Runtime.getRuntime() ;
//開啓某一個進程
// r.exec("calc") ;
// r.exec("notepad") ;
r.exec("mspaint") ;
}
網絡編程
InetAddress:類表示互聯網協議 (IP) 地址
如果一個類中沒有構造方法,沒有字段,只有成員方法?有什麼特徵
1)應該有一些靜態功能(Math類,Arrays,Collections...)
2)可能符合一種單例模式(餓漢/懶漢)
3)該類中的某些靜態成員方法的返回值是該類本身
常用方法:
public static InetAddress getByName(String host)
throws UnknownHostException在給定主機名的情況下確定主機的 IP 地址。
參數:
主機名可以是機器名(如 "java.sun.com"),也可以是其 IP 地址的文本表示形式
創建InetAddress對象,通過來獲取ip地址
在知道主機名的情況下
InetAddress address = InetAddress.getByName("USER-20171205ZR") ;
public String getHostAddress() 返回 IP 地址字符串(以文本表現形式)。
public String getHostName() 獲取此 IP 地址的主機名。
public static void main(String[] args) throws UnknownHostException { //創建InetAddress對象,通過來獲取ip地址 //在知道主機名的情況下 //InetAddress address = InetAddress.getByName("USER-20171205ZR") ; //IP 地址的文本表示形式 //Ip地址對象 InetAddress address = InetAddress.getByName("192.168.10.1") ; //上面獲取到了Ip地址 //public String getHostAddress()返回 IP 地址字符串(以文本表現形式)。 String ip = address.getHostAddress() ; System.out.println(ip);//192.168.10.1 // public String getHostName()獲取此 IP 地址的主機名。 String name = address.getHostName() ; System.out.println(name); }
Udp編程
Udp編程的接收端 開發步驟:
1)創建Socket對象
2)創建一個數據報包(接收容器)
3)調用Socket對象中的接收的方法
4)解析實際傳遞的數據
5)將解析的數據(ip,數據)展示在控制檯上
6)關閉資源
注意:
接收端不要運行多次,會出現異常:
java.net.BindException: Address already in use: Cannot bind
1)創建Socket對象
public DatagramSocket(int port)創建數據報包套接字對象並且將其綁定到本地主機上的指定端口
2)創建一個數據報包(接收容器)
public DatagramPacket(byte[] buf, int length)
3)調用Socket對象中的接收的方法
public void receive(DatagramPacket p):接收數據報包
獲取ip地址文本形式
public InetAddress getAddress() :返回ip地址對象 數據報包類:DataGramPacket
4)解析實際傳遞的數據
public byte[] getData() :獲取緩衝中實際數據(從接收容器中獲取)
public int getLength()返回將要發送或接收到的數據的長度。
6)關閉資源
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(10086);
byte[] bys = new byte[1024] ;
int len = bys.length ;
DatagramPacket dp = new DatagramPacket(bys, len) ;
ds.receive(dp);
InetAddress address = dp.getAddress() ;
String ip = address.getHostAddress() ;
byte[] bys2 = dp.getData() ;
int len2 = dp.getLength() ;
String data = new String(bys2, 0, len2) ;
System.out.println("當前接收到的數據是:"+data+",來自於"+ip);
ds.close();
}
Udp編程
1)不需要建立連接通道
2)數據大小有限制
3)不可靠連接---->傳輸速度快!
發送端的開發步驟:
1)創建發送端的Socket對象
2)創建數據,並打包
3)調用當前發送端Socket對象中的發送的方法
4)關閉資源
1)創建發送端的Socket對象
DatagramSocket:此類表示用來發送和接收數據報包的套接字。
創建DataGramSocket對象
構造方法
public DatagramSocket(int port,InetAddress laddr)
這個構造方法,裏面傳遞並不是Ip地址的文本形式
構造數據報套接字並將其綁定到本地主機上任何可用的端口
2)創建數據,並打包
DatagramPacket 數據報包
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
buf - 包數據。
offset - 包數據偏移量。
length - 包數據長度。
address - 目的地址。
port - 目的端口號。
有數據
3)調用當前發送端Socket對象中的發送的方法
public void send(DatagramPacket p)
throws IOException從此套接字發送數據報包/
4)關閉資源
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket() ;
byte[] bys = "hello,udp,我來了".getBytes() ;
int len = bys.length ;
InetAddress address = InetAddress.getByName("192.168.10.1") ;
int port = 10086 ;
DatagramPacket dp =new DatagramPacket(bys, 0, len, address, port) ;
ds.send(dp);
ds.close();
}