Skip to content

問題當多個factory裡面有相同的function可以抽離嗎 #3

Open
@polo13999

Description

@polo13999

@polo13999

有正在學 angularjs的朋友嗎 我想找人討論
http://www.html-js.com/article/1825
目前大概知道用法 不過使用時機點有幾個還不太熟

@mvpdw06 雖然我對 Service 的概念也不是很熟,也許你可以直接提出你的疑問,讓大家集思廣益幫你解決你的疑惑

@polo13999

ok 是這樣的 比如說我有一個factory
裡面有很多 每次都要重複性的工作
例如

(function() {
   'use strict';

   angular
       .module('app.common')
       .factory('ExpertUsermeta', ExpertUsermeta);

   /* @ngInject */
   function ExpertUsermeta($q, $http, RoleStore, Restangular) {

       var factory ={};

       factory.rest = function(){
           return Restangular.service('ExpertUsermetas');
       };

       factory.findOne = function(id){
           return Restangular.one('ExpertUsermetas', id).get();
       };

那有沒有可能我在factory裡面再把 factory.findOne 與 factory.rest 抽離到 service 再注入到這個 factory
每次為model 建立factory 都會有重複的工作 ~還是有其他的抽離方式

@jacky
A factory 一直用到 B service 的資料,
如果 call api 方法在 A 我會把 AB 融合成一隻 factory

@polo13999
意思是把B的sevice 注入到A嗎

@jacky
以大大的範例 B sevice 已經注入到 A factory 了
所以我會把他們合成 1 隻檔案
不過這個我不知道你 A factory 裡面的邏輯其他 B service 注入的地方要不要用
題外,最近重構把 factory 根據 Angular 1 Style Guide 改成這樣覺得不錯

var STORE

var factory ={
    get: get,
    set: set
}

return factory;

function get(){ //.. }

function set(){ //.. }

@oliver
我的了解是這樣的,就Angular Service裡的Factory, Service, Provider的概念是同樣的,不同的是在於它們的實作方式。主要目的是要把一些邏輯抽離出Controller,所以基本上只要先熟悉一種實作方式即可。

我目前都是用Factory來去實作利用Ajax來去取得後端資料的邏輯
題外,寫code去參考Angular Style Guide真的不錯

@polo13999
那如果有時候需要開很多 factory 但裡面有些功能一樣 這樣用 factory 注入 一個servce 這樣抽離好嗎

@jacky

我們最近重構也是遇到這種問題,蠻難解的,但是我個人傾向操作相同資料,使用同一個 factory 如上 oliver 大大說(Factory, Service, Provider 都是 Provider 忘了在哪篇看到請盡量使用 Factory)Factory 內部可宣告幾個 STORE 當作暫存,中繼資料交換,Controller 間資料傳遞使用,並可當作廣播中心可以達到需多管理方法... 缺點就是 factory 有點大但是 Controller 非常輕巧(棒),後面的同事維護可以清楚了解這隻功能需要什麼資料,怎麼處理後就可以 call api

最後,我也想知道是不是有更好的方法,再請各位給意見,謝謝。

@oliver
這個問題我覺得比較偏設計面的思考問題,實作上angular 在這部份算很彈性了。

我寫Code的基本原則會 ​_比較朝向單一權責的方向做設計_​ (在能力與時間許可之下盡可能遵守),因此使用Angular Service比較常使用在幾個地方。

  • 第一,專職處理特定的邏輯程式,這部份裡面只會處理邏輯,無任何非邏輯上的事(如介面操作、資料驗證等),如前面所說的*專職利用Ajax來去取得後端資料,讓 Controller 可以Inject並呼叫其中的方法,簡少 Controller 的程式碼。
  • 第二,如為了要串接各不同的Controller之間的資料操作。此時,就是把Service當作Controller的_Model_在使用,可以讓較複雜的資料介面操作,分門別類至不同的 Controller 進行介面上的控制。你所提到的部份,就有可能在這個狀況下實現。不過在程式架構上我會看成 ​*Controller —> Model Service —> Logic Service

@Polo
另外有個問題想請問 記得factory 一定要有return 上面的語法可以解釋成擴充嗎

@oliver
我覺得不太能這樣解釋,比較像是angular 規定的寫法

@polo13999
那set部分這樣也是要return 一個值嗎?

@oliver
整個Angular Service看似有這麼多種,其實嚴格來說都是Provider。其他的只是用比較容易的方式來實現,像是在Angular裡有 $http ,但也會用 $get$post 來直接呼叫一樣

Factory的概念比較可以看成,像是給Controller一個Ajax物件,裡面提供了Get / GetList / GetCount / Insert / Update / Delete 等等的方法可供呼叫
沒有限制是get / set

@polo13999
so-ga 因為我看有些文章是說一定要有return

@oliver
是的,它一定會return一個object
所以Style Guide會建議Factory的寫法,主要是把介面宣告跟實作分開,在使用上可能不去管實作內容,看最一開始的object定義就知道什麼方法做什麼事

@polo13999
這邊有點卡住 set function 的話也要return嗎

@oliver
你這邊講的retrun應該是set function本身吧,這要看這個function的需求

@polo13999
嗯嗯 所以沒有強制規範 facrory 要return嚕

@oliver
我會這樣講

return object 是 angular.module(‘xx’).factory() 規定的寫法

然而在object裡所提供的方法來看,需不需要return要看實際用途

@polo13999
嗯所以我有點混亂為什麼

var STORE

var factory ={
   get: get,
   set: set
}

return factory;

function get(){ //.. }

function set(){ //.. }

所以其實也可以不需要 ~ 但基本上最好要

@oliver

angular.module(‘FactoryModule’).factory(‘AjaxService’, AjaxService);

AjaxService.$inject = [];

function AjaxService() {
  return {
      get: get,
      set: set
  };

  function get() {
     return;
  }

  function set() {
  }
}

完整來寫應該是這樣
AjaxService本身是一個Factory,它return一個object
這個object提供get / set兩個方法
get會回傳,set不會

@polo13999
so-ga 這樣我知道了 感謝 oliver 指導 拍謝 很多不懂的

@oliver
不會,一開始不懂是一定的
儘量去了解Service、Directive、Controller存在的目地,會讓整個app的程式結構比較單純
我也只是了解點皮毛,剛好可以回答你的問題

@polo13999
感謝指導 受益良多

@RaphaHsu 補充說明

Factory 需要 return 是因為他用 reveal pattern 包裝,new物件後只回傳 return 物件,當作Public API (也因此使用this要小心,必須搞清楚綁在哪個context)
https://carldanley.com/js-revealing-module-pattern/

Service則是直接回傳new出來的物件,因此定義時為OO寫法

兩者都是Provider的打包,若是要細部客製config階段操作,才會用到Provider

若是你可以避免 circular injection,可以把共用部分拆成 common factory,客製化的factory 都 inject common factory
keyword Inject Factory into Factory

@jacky
早上看了一下發現應是我範例 取名太爛 造成誤解..
感謝 @oliver @RaphaHsu 兩位大大的補充
我這邊講一個簡單的版本,用簡報說明看看會不會清楚點:

https://hackmd.io/p/ByDVwsyE#/

如果觀念錯誤在幫我指正一下,感恩

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions