引申覆習面向對象的設計的六大原則,一些設計模式中就體現了這類原則
-
單一職責:一個合理的類功能應該只有一個,消除耦合減少需求變化對代碼的修改
-
開閉原則:一個類應該對擴展開啓,對修改關閉。降低程序模塊之間的耦合度,增加擴展性
-
里氏替換原則:子類應該能替換基類。 能夠很好的實現功能的調整和升級,並且不影響客戶端調用
-
依賴倒換原則:設計依賴於抽象而不是依賴於具體化。
-
接口隔離原則:劃分接口應該單一細緻,讓系統容易實現重構,對接口修改時影響較少。
-
迪米特法則:一個類儘可能少的去了解其他對象
這些原則其實最後的目的是爲了程序中模塊分工明確,便於升級和調整。
工廠模式:實例化對象,用工廠方法代替new操作,將實現類和對象的創建統一管理和控制,從而將調用者和實現類解耦。
工廠模式也分爲三種,簡單工廠模式(靜態工廠模式)、工廠方法模式,抽象工廠模式
一、簡單抽象模式(靜態抽象模式)
1、UML類圖
動物產品可以有Cat、Pig、Dog 客戶端來生成產品時需要與每一個具體的產品產生聯繫,比如 Animal cat = new Cat();這樣 對象的生成和控制全在客戶端client。 不便於管理,那麼我們可以將對象的生成交給第三方來管理。 客戶端需要產品 只要通知一個組件 我需要什麼對象,組件返回相應對象滿足客戶端;那麼對象的生成相對於客戶端透明, 便於統一管理。這就是簡單抽象模式。
2、產品類: Cat 、Pig、Dog實現Animal接口
package factory.simple;
public interface Animal {
public void say();
}
package factory.simple;
public class Cat implements Animal {
public void say() {
System.out.println("喵喵喵");
}
}
package factory.simple;
public class Dog implements Animal {
public void say() {
System.out.println("汪汪汪");
}
}
package factory.simple;
public class Pig implements Animal {
public void say() {
System.out.println("哼哼哼");
}
}
3、工廠類:SimpleFactory
package factory.simple;
public class SimpleFactory01 {
//第一種簡單工廠模式
public static Animal creatAnimal(String type){
if("cat".equals(type)){
return new Cat();
}else if("pig".equals(type)){
return new Pig();
}else{
return null;
}
}
//第二種簡單工廠模式
public static Animal creatCat(){
return new Cat();
}
public static Animal creatPig(){
return new Pig();
}
}
4、客戶端
package factory.simple;
public class Client1 {
public static void main(String[] args) {
Animal cat = SimpleFactory01.creatAnimal("cat");
cat.say();
Animal pig = SimpleFactory01.creatAnimal("pig");
pig.say();
Animal cat2 = SimpleFactory01.creatCat();
cat2.say();
Animal pig2 = SimpleFactory01.creatPig();
pig2.say();
}
}
5、總結:客戶端在需要動物產品時 只需要向SimpleFactory通知需要什麼對象就能得到滿足。實現了對象的生成與統一管理交給了工廠SimpleFactory。實現了分工。
優點:簡單工廠模式實現簡單。
缺點:對於新產品的添加需要對已存在的工廠代碼修改,違反了開閉原則。
二、工廠方法模式
通過上面的建檔工廠模式,當我們需要增加一個新的產品(alpaca羊駝)時,我們需要在原工廠內增加邏輯生成新產品,這違背了開閉原則,對擴展開放,對修改關閉。這顯然不合理,那麼我們可以通過工廠方法模式來解決這個問題。 我們可以將工廠類進行拆分。將產品和工廠類一一對應,那麼我們需要增加新的產品時,只需要增加相應的產品類和工廠類就可以解決了。
1、UML類圖
2、產品類(與簡單工程類一致)
3、工廠類
package factory.method;
import factory.method.Animal;
/**
* 工廠方法模式
*/
public interface MethodFactory {
Animal create();
}
package factory.method;
public class CatFactory implements MethodFactory {
public Animal create() {
return new Cat();
}
}
package factory.method;
public class PigFactory implements MethodFactory {
public Animal create() {
return new Pig();
}
}
4、客戶端
package factory.method;
public class Client {
public static void main(String[] args) {
Animal cat = new CatFactory().create();
cat.say();
Animal pig = new PigFactory().create();
pig.say();
}
}
5.總結:當需要新增加其他產品時,只需要增加產品類、和產品對應的工廠類。不需要對已存在的工廠類做修改,符合的開閉原則。
優點:符合開閉原則,對擴展支持良好
缺點:增加了類,增加了類的管理
三、抽象工廠模式
工廠方法模式很好的解決了簡單工廠模式遺留下的擴展問題。但並不是工廠方法就是完美的存在這種情況:當我們需要同種產品存在差異時,比如我需要一個很肥的貓,需要一個瘦的貓。 如果使用抽象工廠方法模式,那麼需要再增加肥的 和瘦的對應的商品類 並且增加對應的工廠類。
1、UML類圖
2.產品類
package factory.abstractfactory;
public interface Animal {
public void say();
}
package factory.abstractfactory;
public interface BigAnimal extends Animal {
}
package factory.abstractfactory;
public interface SmallAnimal extends Animal {
}
package factory.abstractfactory;
public class BigCat implements BigAnimal {
public void say() {
System.out.println("肥貓喵喵喵");
}
}
package factory.abstractfactory;
public class SmallCat implements BigAnimal {
public void say() {
System.out.println("瘦貓嗷嗷嗷");
}
}
3、工廠類
package factory.abstractfactory;
public interface AbstractFactory {
public Animal createBig();
public Animal createSmall();
}
package factory.abstractfactory;
public class CatFactory implements AbstractFactory{
public Animal createBig() {
return new BigCat();
}
public Animal createSmall() {
return new SmallCat();
}
}
4、客戶端
package factory.abstractfactory;
public class Client {
public static void main(String[] args) {
Animal bigCat = new CatFactory().createBig();
Animal smallCat = new CatFactory().createSmall();
bigCat.say();
smallCat.say();
}
}
5.總結:抽象工廠類在 工廠方法的基礎上對產品和產品的工廠進行再次的抽象分類。 抽象分爲建爲約束,那麼就只能建立類似的產品進行擴展,增加了約束條件。
總結:三種工廠類 沒有必須使用哪一種。 根據具體情況選擇使用