工廠模式爲 MVC 解耦

緒論

最近使用 MVC 模式實在是不能自拔,同時也致使出現一列的問題:高耦合。
每一個程序猿談到程序如何設計纔好的時候,基本上張嘴就來:高併發、低耦合、高內聚......
那麼問題來了,什麼是耦合?如何實現低耦合?

耦合

耦合就是對模塊間關聯程度的度量。簡單來講就是個程序之間的依賴程度,包括類之間的依賴、函數之間的了依賴。

栗子

咱們有這麼一個場景,須要實現一個帳戶保存的功能。這個很簡單,無非就是兩個接口、兩個實現類、再加一個測試類的事情。

整個功能的包結構

包結構

上代碼

Talk is cheap, show me the code;
  • 建立帳戶持久層接口 IAccountDao,定義保存帳戶抽象方法
public interface IAccountDao {

    /**
     * 保存帳戶
     */
    void saveAccount();
}
  • 實現帳戶持久層酒樓 AccountDaoImpl,並建立並實現 saveAccount 方法,輸出保存信息。
public class AccountDaoImpl implements IAccountDao {

    @Override
    public void saveAccount() {
        System.out.println("已保存帳戶~!");
    }
}
  • 定義帳戶業務層接口 IAccountService,並定義一個保障帳戶的方法
public interface IAccountService {

    /**
     * 保存帳戶
     */
    void saveAccount();
}
  • 實現帳戶業務層接口 AccountServiceImpl,實現調用持久層 saveAccount 方法實現保存帳號抽象方法。
public class AccountServiceImpl implements IAccountService {

    /**
     * 持久層對象
     */
    private IAccountDao accountDao = new AccountDaoImpl();

    @Override
    public void saveAccount() {
        accountDao.saveAccount();
    }
}
  • 最後編寫表現層 AccountDemo,測試下該用例是否能正常運行(確定能,這步是多餘的),貼代碼了
public class AccountDemo {

    public static void main(String[] args) {
        IAccountService as = new AccountServiceImpl();
        as.saveAccount();
    }
}

// 如下爲輸出結果
已保存帳戶~!

強勢分析一波

那麼咱們剛剛說的低耦合,在上面的這幾段代碼中,耦合程度是很高的。爲啥說高耦合呢,倘若咱們不當心刪了 AccountDaoImpl ,整個程序都沒法經過編譯(如圖)。那麼這時候就須要解耦。

compile excetion

這時候咱們的工廠模式也就出來了。

工廠模式解耦

解耦

在實際開發中,耦合是必然存在的,故只能儘可能下降依賴,不能消除。
  • 通常的解耦的思路:java

      1. 經過反射來建立對象,而避免使用 new 關鍵字
      1. 經過讀取配置文件來獲取要建立對象的全限定類名

使用配置文件

使用配置文件能夠達到一個目的,就是當咱們經過一些固定不變的內容,能夠把其抽取出單獨保存,經過調用的方式獲取其實例(跟常量類的方式無異)。
  • 建立 bean.properties 文件,保存帳戶業務層實現類的路徑 AccountServiceImpl 和帳戶持久層接口實現類 AccountDaoImpl 信息,具體以下:
accountService=wiki.laona.service.impl.AccountServiceImpl
accountDao=wiki.laona.dao.impl.AccountDaoImpl
  • 使用反射獲取相應的對象實例,具體代碼以下:
/**
 * @description: Bean對象的工廠模式
 * @author: laona
 **/
public class BeanFactory {

    /**
     * Properties 對象
     */
    private static Properties props;

    /**
     * 靜態代碼塊爲 Properties 對象賦值
     */
    static {
        try {
            // 實例化對象
            props = new Properties();
            // 獲取 properties 文件的流對象
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            props.load(in);
        } catch (IOException e) {
            throw new ExceptionInInitializerError("初始化 properties 文件異常!");
        }
    }

    /**
     * 獲取對象實例
     * @param beanName 對象實例名
     * @return {@link Object} 對象實例
     */
    public static Object getBean(String beanName) {
        Object bean = null;
        try {
            String beanPath = props.getProperty(beanName);
            bean = Class.forName(beanPath).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
}
  • 那麼這時候,帳戶業務層實現類就能夠這麼寫:
public class AccountServiceImpl implements IAccountService {

    // 經過工廠模式獲取 AccountDaoImpl 的實例
    private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao");

    @Override
    public void saveAccount() {
        accountDao.saveAccount();
    }
}
  • 表現層這麼寫:
public class AccountDemo {

    public static void main(String[] args) {
//        IAccountService as = new AccountServiceImpl();
        IAccountService as = (AccountServiceImpl) BeanFactory.getBean("accountService");
        as.saveAccount();
    }
}
這樣整個包結構就變成了這樣:
new AccountDemo
  • 這時候相比以前耦合程度就大大下降了,這時候儘管刪除持久層包下的實現類 AccountDaoImpl,編譯是不會出錯,可是沒有該類是確定運行不了。編譯器會報 java.lang.ClassNotFoundException 異常,而不是 Error。

總結

耦合只是相對而言,工廠模式也不是完美的,仍然存在不少能夠優化的地方,可是能夠減小部分耦合就是對程序性能的一個大幅度的提高。
相關文章
相關標籤/搜索