設計模式
設計模式是前人總結的,爲了解決一類問題而總結的代碼設計經驗。最初可能爲了使用而使用,後面就會發現,很多沒想到的問題因爲使用了正確的設計模式已經爲你考慮到了。《design patterns設計模式》這本書是程序員進階必學。
(一)工廠模式
工廠模式的意義在於定義一個用於創建對象的接口,並控制返回哪個類的實例。網上比較流行的一個普通工廠模式的例子。
interface Sender{
public void send();
}
class MainSender implements Sender{
public void send (){
System.out.println("MainSender");
}
}
class SnsSender implements Sender{
public void send(){
System.out.println("SnsSender");
}
}
class SendFactory{
public Sender product(String type){
if("Main".equals(type)){
return new MainSender();
}else if("Sns".equals(type)){
return new SnsSender();
}else{
System.out.println("請輸入正確類型");
return null;
}
}
}
public class Factory {
public static void main(String[] args){
SendFactory factory = new SendFactory();
Sender sender = factory.product("Main");
sender.send();
}
}
但是個人感覺這個沒啥用處。在《java設計模式》中對於工廠模式的定義感覺比較好,工廠模式使得客戶端代碼無須關心使用哪個類的實例,但是上面的例子需要調用者決定返回哪個類的實例。工廠模式不僅要求有一個能夠創建新對象的方法,還要讓客戶代碼無須瞭解具體實例化的類。返回的相同的抽象類型,但實際實例化了不同的類,由哪個類實例化取決於工廠對象接收創建請求時的行爲。所以我的理解是,工廠模式的意圖是讓服務的提供者確定實例化哪個類,而不是客戶代碼。修改下上面的代碼。
interface Sender{
public void send();
}
class MainSender implements Sender{
public void send (){
System.out.println("MainSender");
}
}
class SnsSender implements Sender{
public void send(){
System.out.println("SnsSender");
}
}
class SendFactory{
public int day = 0;
public SendFactory(){
day = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
}
public Sender product(){
if(day%2 == 0){
return new MainSender();
}else{
return new SnsSender();
}
}
}
public class Factory {
public static void main(String[] args){
SendFactory factory = new SendFactory();
Sender sender = factory.product();
sender.send();
}
}
(二)抽象工廠模式
抽象工廠相比於上面的工廠模式,多了一個抽象接口就是,上面的工廠類是無法擴展的,如果要擴展必須修改工廠類,違背閉包原則。如果將工廠也抽象出來就是一個抽象工廠模式,需要擴展時候直接擴展一個新的工廠。
優點:1、封裝性好,產品實現類高層模塊不關係,只要找到合適的工廠類。2、產品族內約束爲非公開。
缺點:擴展困難,添加一個新工廠,並且新工廠需要一個新接口,那麼需要修改抽象類接口,而且前面的每個工廠也要相應的修改。所以對於抽象工廠模式橫向擴展簡單,縱向擴展困難。在使用的時候可以注意。
interface Sender{
public void send();
}
interface Provider{
public Sender product();
}
class MainSender implements Sender{
public void send (){
System.out.println("MainSender");
}
}
class SnsSender implements Sender{
public void send(){
System.out.println("SnsSender");
}
}
class SendMainFactory implements Provider{
public int day = 0;
public SendMainFactory(){
day = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
}
public Sender product(){
if(day%2 == 0){
return new MainSender();
}
return null;
}
}
class SendSnsFactory implements Provider{
public int day = 0;
public SendSnsFactory(){
day = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
}
public Sender product(){
if(day%2 == 0){
return new SnsSender();
}
return null;
}
}
public class Factory {
public static void main(String[] args){
Provider factory = new SendSnsFactory();
Sender sender = factory.product();
sender.send();
}
}
上面的例子,如果增加一個新工廠只要新建一個工廠繼承Provider ,擴展很簡單,但是如果需要增加Provider的接口,那麼SendMainFactory
SendSnsFactory
也要相應修改。