大二結(jié)束了java和java web的基礎(chǔ)課程循衰,大三開始自學(xué)各種框架厢漩,在看書和觀看視頻過程中發(fā)現(xiàn)自己設(shè)計模式知識的欠缺,使得自己學(xué)習(xí)的時候云里霧里劳澄,知其然不知其所以然地技,在某一篇博文中看到“框架是軟件,而設(shè)計模式是軟件的知識”秒拔,所以決定自己再扎實的學(xué)一遍設(shè)計模式莫矗,并且寫下自己總結(jié)的文章,各種繁雜的定義就不寫了砂缩,網(wǎng)上和書上一大堆作谚,希望自己可以寫的偏實際一點。(由于第一次寫文章庵芭,水平有限妹懒,若有錯誤希望大家指正)
簡單工廠模式
1.為什么需要使用工廠模式
其實這也是初學(xué)設(shè)計模式時經(jīng)常會想到的問題,網(wǎng)上給的例子一般都太簡單双吆,雖然能夠說明實現(xiàn)方式和原理眨唬,可總給人一種為了使用而使用的感覺,繞來繞去我還不如自己new一個對象
首先好乐,工廠模式是為了解耦匾竿,“高內(nèi)聚、低耦合”是所有軟件設(shè)計者所追求的蔚万,很多設(shè)計模式也都是為了這個目的而存在岭妖。接下來我會用很大篇幅的代碼一步一步的引出為什么需要簡單工廠模式
在《大話設(shè)計模式》有一個寫簡單計算器的例子如下
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入數(shù)字A");
Double numberA = scanner.nextDouble();
System.out.println("請輸入運算符號(+、-、*昵慌、/)");
scanner.nextLine();//吃一個換行符
String operator = scanner.nextLine();
System.out.println("請輸入數(shù)字B");
Double numberB = scanner.nextDouble();
Double result;
switch (operator) {
case "+":
result = numberA + numberB;
break;
case "-":
result = numberA - numberB;
break;
case "*":
result = numberA * numberB;
break;
case "/":
try {
result = numberA / numberB;
} catch (ArithmeticException e) {
System.out.println("除數(shù)不能為0");
return;
}
break;
default:
System.out.println("沒有該運算規(guī)則");
return;
}
System.out.println("結(jié)果是:"+result);
}
}
這是初學(xué)者在學(xué)習(xí)java時最容易寫出的代碼假夺,特別是剛剛學(xué)習(xí)C語言過后,我們來看一看上面的代碼在設(shè)計上存在哪些問題
(1)沒有使用到面向?qū)ο蟮乃枷?/h6>
如果現(xiàn)在我們的身邊有一個計算器斋攀,大家想一想它會是什么樣的已卷,首先我們會看到屏幕和各種按鍵,當(dāng)正確的按下一系列按鍵后蜻韭,我們會在屏幕上看到結(jié)果悼尾,可后面的具體運算過程我們是看不到的。接下來看上面的代碼肖方,輸出打印語句類比為屏幕闺魏,輸入語句是按鍵,剩下的case switch 定義變量等語句都是計算過程俯画,而這些計算過程都是可以隱藏起來的析桥,這樣界面和業(yè)務(wù)邏輯完全分離,降低耦合性艰垂,便于程序維護(hù)泡仗。
修改過后代碼如下
public class View {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入數(shù)字A");
Double numberA = scanner.nextDouble();
System.out.println("請輸入運算符號(+、-猜憎、*娩怎、/)");
scanner.nextLine();//吃一個換行符
String operator = scanner.nextLine();
System.out.println("請輸入數(shù)字B");
Double numberB = scanner.nextDouble();
Double result = null;
try {
result = Calculator.calculator(numberA,operator,numberB);
System.out.println("結(jié)果是:"+result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Calculator {
public static Double calculator(Double numberA,String operator,Double numberB) throws ArithmeticException{
double result;
switch (operator) {
case "+":
result = numberA + numberB;
break;
case "-":
result = numberA - numberB;
break;
case "*":
result = numberA * numberB;
break;
case "/":
try {
result = numberA / numberB;
} catch (ArithmeticException e) {
throw new ArithmeticException("被除數(shù)不能為0");
}
break;
default:
throw new ArithmeticException("沒有這個運算規(guī)則");
}
return result;
}
}
這樣就分離了業(yè)務(wù)邏輯和界面,但我們再看看這樣的代碼還有什么問題
(2)擴(kuò)展性極差
如果有一天我們需要加上開方胰柑、平方等運算截亦,所有的加減乘除等功能都得參與程序的編譯,在增加功能的同時還有誤修改源碼的風(fēng)險柬讨,違背開放閉合原則崩瓤。
繼續(xù)修改代碼
abstract public class Operation {
private double a;
private double b;
abstract public double getResult() throws Exception;
//定義一個抽象類 其中有一個運算抽象方法
public double getA() {
return a;
}
public void setA(double a) {
this.a = a;
}
public double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
}
public class AddOperation extends Operation{
@Override
public double getResult() {
double result=super.getA()+super.getB();
return result;
}
}
public class SubOperation extends Operation{
@Override
public double getResult() {
double result=super.getA()-super.getB();
return result;
}
}
public class MulOperation extends Operation {
@Override
public double getResult() {
double result=super.getA()*super.getB();
return result;
}
}
public class SubOperation extends Operation{
@Override
public double getResult() {
double result=super.getA()-super.getB();
return result;
}
}
修改后的代碼擴(kuò)展性大大增強,當(dāng)我們需要增加其他運算時踩官,我們只需要讓新類繼承Operation類并實現(xiàn)getResult方法却桶,不需要去修改其他功能模塊的代碼≌崮担可新問題來了颖系,在運算的時候,我們需要有選擇性的實例化某一個對象辩越,這個時候就用到了簡單工廠模式嘁扼。
2.簡單工廠模式的定義
雖然我真的特別特別特別的不喜歡那些臃腫的定義,不過在某些角度看來区匣,為了讓知識系統(tǒng)化,了解一些定義還是挺有必要的。不過在上定義之前亏钩,咱們先看看模式的結(jié)構(gòu)
簡單工廠模式包含如下角色:
Factory:工廠角色
Product:抽象產(chǎn)品角色
ConcreteProduct:具體產(chǎn)品角色
工廠角色(Creator)
是簡單工廠模式的核心莲绰,它負(fù)責(zé)實現(xiàn)創(chuàng)建所有具體產(chǎn)品類的實例。工廠類可以被外界直接調(diào)用姑丑,創(chuàng)建所需的產(chǎn)品對象蛤签。(也就是我們在后面的OperationFactory類)
抽象產(chǎn)品角色(Product)
是所有具體產(chǎn)品角色的父類,它負(fù)責(zé)描述所有實例所共有的公共接口栅哀。(上面代碼的Operation類)
具體產(chǎn)品角色(Concrete Product)
繼承自抽象產(chǎn)品角色震肮,一般為多個,是簡單工廠模式的創(chuàng)建目標(biāo)留拾。工廠類返回的都是該角色的某一具體產(chǎn)品戳晌。(Operation的子類)
補齊后面的代碼
public class OperationFactory {
public static Operation createOperation(char op) throws Exception{
switch (op) {
case '+':
return new AddOperation();
case '-':
return new SubOperation();
case '*':
return new MulOperation();
case '/':
return new DivOperation();
default:
throw new Exception("符號有誤!");
}
}
}
public class Main {
public static void main(String[] args) {
Operation opr = null;
double a;
char op;
double b;
Scanner sc = new Scanner(System.in);
a = sc.nextDouble();
op = sc.next().charAt(0);
b = sc.nextDouble();
try {
opr=OperationFactory.createOperation(op);
opr.setA(a);
opr.setB(b);
System.out.println(opr.getResult());
}catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
最后最后最后痴柔,上定義沦偎!
簡單工廠模式(Simple Factory Pattern):又稱為靜態(tài)工廠方法(Static Factory Method)模式,它屬于類創(chuàng)建型模式咳蔚。在簡單工廠模式中豪嚎,可以根據(jù)參數(shù)(也就是上述的各種運算符號)的不同返回不同類的實例(上述的運算方法子類)。簡單工廠模式專門定義一個類(上述的OperationFactory類)來負(fù)責(zé)創(chuàng)建其他類的實例谈火,被創(chuàng)建的實例通常都具有共同的父類(上述的Operation類)侈询。
最后說一下自己的理解
簡單工廠模式無非是對面向?qū)ο笏枷氲囊环N體現(xiàn),我需要什么糯耍,你就給我提供什么扔字,通過繼承和多態(tài)又將業(yè)務(wù)邏輯中的代碼解耦,使得各個功能之間耦合度降低谍肤,便于程序擴(kuò)展維護(hù)啦租,當(dāng)然有人會說,在增加新功能以后荒揣,我們依舊需要去修改工廠類的switch語句篷角,這個問題就通過以后在寫抽象工廠模式的總結(jié)的時候解答吧。