Android Ios 策略模式實戰(zhàn)使用場景

哪些常見的場景適合使用策略模式呢刻剥?我在寫聊天界面的時候遇到了一個非常適合用策略模式的地方囚聚,與大家分享 (本文以Android的聊天界面為案例厉斟,ios也是一個道理)
本文不做介紹 策略模式到底是什么兼犯,網(wǎng)上別人寫的很詳細珍语。

聊天界面的ViewHolder (ios中叫Cell)一共有哪幾種類型锤岸?

ViewHolder 位置 內(nèi)容 上傳狀態(tài)View
MySend_Text_ViewHolder 發(fā)文字
MyReceived_Text_ViewHolder 收文字 沒有
MySend_Image_ViewHolder 發(fā)圖片
MyReceived_Image_ViewHolder 收圖片 沒有
MySend_Voice_ViewHolder 發(fā)語音條
MyReceived_Voice_ViewHolder 收語音條 沒有
MySend_Location_ViewHolder 發(fā)位置
MyReceived_Location_ViewHolder 收位置 沒有
MySend_Call_ViewHolder 發(fā)語音通話
MyReceived_Call_ViewHolder 收語音通話 沒有

老方案1:左邊是BaseTextHolder,右邊的MySend_Text_ViewHolder extend BaseTextHolder板乙,然后加上progressbar 和 statusIV

缺點:

  1. private progressbar 和 private statusIV要寫5次(寫在MySend_XXX_ViewHolder類)
  2. 右邊要為了上傳的進度控件要復(fù)制粘貼多次findSubmitStatusViewById 和 diaplaySubmitStatusView
  3. 拓展性差是偷,如果在別的場景假如有多種位置的Item,要多寫很多類代碼

老方案2:左右都用TextHolder募逞;TextHolder包含private progressbar 和 private statusIV蛋铆;然后TextHolder有個isRight 的 boolean字段

缺點:

  1. private progressbar 和 private statusIV要寫5次(在TextHolder類里寫)
  2. 右邊要為了上傳的進度控件要復(fù)制粘貼多次findSubmitStatusViewById 和 diaplaySubmitStatusView

一切的原因,都是java 和 oc不支持多繼承放接,要是有多繼承刺啦,可以讓MySend_Text_ViewHolder extend BaseTextHolder,SubmitStatusHolder多好

下面使用策略模式,很好的解決了這些問題纠脾,代碼實現(xiàn)完美封裝(以下只拿Text文本消息來舉例)

//聊天Item的位置Interface(如果是我發(fā)出的玛瘸,就在右邊;我收到的消息苟蹈,在左邊)
public interface IBubbleDirection {
    //在getView()方法里的 convertView == null里觸發(fā)個方法
    public void findChildView(View convertView);
    //在getView()方法里 顯示上傳View的值
    public void display(int submitStatus);
}

public class RightBubbleDirectionImpl implements IBubbleDirection {
    
    private ProgressBar submitProgressBar;//上傳中的進度條
    private ImageView submitStatusImageView;//上傳失敗的感嘆號

    @Override
    public void findChildView(View convertView) {
        submitProgressBar = (ProgressBar) convertView.findViewById(R.id.progress_bar);
        submitStatusImageView = (ImageView) convertView.findViewById(R.id.msg_status_iv);
    }

    @Override
    public void display(int submitStatus) {
        switch (submitStatus) {
            case ChatBean.SUCCESS: // 發(fā)送成功
                submitProgressBar.setVisibility(View.GONE);
                submitStatusImageView.setVisibility(View.GONE);
                break;
            case ChatBean.FAIL: // 發(fā)送失敗
                submitProgressBar.setVisibility(View.GONE);
                submitStatusImageView.setVisibility(View.VISIBLE);
                break;
            case ChatBean.INPROGRESS: // 發(fā)送中
                submitProgressBar.setVisibility(View.VISIBLE);
                submitStatusImageView.setVisibility(View.GONE);
                break;
        }
    }
}
public class ChatListAdapter extends BaseAdapter {

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
            case MESSAGE_TYPE_RECV_TXT://我接受的文本消息
            case MESSAGE_TYPE_SENT_TXT:{//我發(fā)出的文本消息
                TextViewHolder holder;
                if (convertView == null) {
                    holder = new TextViewHolder(
                            type == MESSAGE_TYPE_SENT_TXT ? new RightBubbleDirectionImpl() : new LeftBubbleDirectionImpl(),
                            new TextBubbleViewImpl(myUserPhoto, onChatActionListener, mOnLinkClickListener));
                    convertView = mInflater.inflate(type == MESSAGE_TYPE_SENT_TXT ? R.layout.chatitem_sent_message : R.layout.chatitem_received_message, null);

                    //讓holder去findViewById
                    holder.findChildView(convertView);

                    convertView.setTag(holder);
                } else {
                    holder = (TextViewHolder) convertView.getTag();
                }
                holder.display(position, bean);
            }
                break;
    }


    //接受-文本-Text ; 其實這里無需 extends BaseTextViewHolder
    public static class TextViewHolder extends BaseTextViewHolder{

        private IBubbleDirection bubbleDirection;//上傳progress和statusiv控件
        private IBubbleView bubbleView;//文本Item控件

        public TextViewHolder(IBubbleDirection bubbleDirection, IBubbleView bubbleView){
            this.bubbleDirection = bubbleDirection;
            this.bubbleView = bubbleView;
        }

        public void findChildView(View convertView){
            //初始化Item自己的view
            bubbleView.findChildView(convertView);
            //初始化上傳狀態(tài)View
            bubbleDirection.findChildView(convertView);
        }

        public void display(int position, ChatBean chatBean){
            //處理Item自己的view
            bubbleView.display(position, chatBean);
            //處理上傳狀態(tài)View
            displaySubmitView(chatBean.getState());
        }

        //因為外部ac可能要重置上傳狀態(tài)捧韵,所以這里設(shè)置為public
        public void displaySubmitView(int submitStatus){
            //處理上傳狀態(tài)View
            bubbleDirection.display(submitStatus);
        }
    }

總結(jié):在什么情況下適合使用 橋接模式

  1. 你希望雙繼承的時候:比如聊天的ViewHolder,“我發(fā)出的圖片消息” 既想extend BaseImageViewHolder汉操,又想 extend BaseUploadViewHolder
  2. 你想創(chuàng)建N個對象再来,這N個對象有若干個共同的特點(或者說方法) :比如 文字消息ViewHolder,無論左右,他的View的都是普通文字(這是 文字消息的共同特點)芒篷;同時 我發(fā)出的消息ViewHolder 又有個共同特點:都有progress 和 statusImageView
    以上搜变,我們就可以把其中一組特點 (比如 發(fā)出的消息),抽成一個接口针炉,然后用RightViewHolderImpl實現(xiàn)這個接口挠他;然后安心搞好 TextViewHolder、ImageViewHolder就好了
  3. 關(guān)于 橋接模式策略模式 的區(qū)別:
    下面是橋接模式:
//橋接模式:注意這里篡帕,IBubbleDirection是由父類控制的
public abstract class FatherTextViewHolder {
    private IBubbleDirection bubbleDirectionInterFace

    public FatherTextViewHolder(IBubbleDirection bubbleDirectionInterFace) {
        this.bubbleDirectionInterFace = bubbleDirectionInterFace   
    }

    public void fatherDisplay(){
        bubbleDirectionInterFace.display()
    }
}

//橋接模式中殖侵,子類無需關(guān)心接口的實現(xiàn)方式,由父類實現(xiàn)
class ChildTextViewHolder extend FatherTextViewHolder{

    override
    public void fatherDisplay(){
        super.fatherDisplay()
        //TODO 子類自己的代碼
    }
}

//橋接模式與策略模式區(qū)別就在于:他多了父類這一步镰烧,在父類中實現(xiàn)接口拢军;而策略模式?jīng)]有父類
class ChildTextViewHolder2 extend FatherTextViewHolder{

    override
    public void fatherDisplay(){
        super.fatherDisplay()
        //TODO 子類自己的代碼
    }
}

下面是策略模式:

//策略模式要比橋接簡單一下,就單純的一層
public class TextViewHolder {
    private IBubbleDirection bubbleDirectionInterFace

    public TextViewHolder(IBubbleDirection bubbleDirectionInterFace) {
        this.bubbleDirectionInterFace = bubbleDirectionInterFace   
    }

    public void myDisplay(){
        bubbleDirectionInterFace.display()
       //TODO 自己的代碼
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怔鳖,一起剝皮案震驚了整個濱河市茉唉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌结执,老刑警劉巖度陆,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異献幔,居然都是意外死亡懂傀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門蜡感,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸿竖,“玉大人,你說我怎么就攤上這事铸敏「坑牵” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵杈笔,是天一觀的道長闪水。 經(jīng)常有香客問我,道長蒙具,這世上最難降的妖魔是什么球榆? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮禁筏,結(jié)果婚禮上持钉,老公的妹妹穿的比我還像新娘。我一直安慰自己篱昔,他們只是感情好每强,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布始腾。 她就那樣靜靜地躺著,像睡著了一般空执。 火紅的嫁衣襯著肌膚如雪浪箭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天辨绊,我揣著相機與錄音奶栖,去河邊找鬼。 笑死门坷,一個胖子當(dāng)著我的面吹牛宣鄙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播默蚌,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼冻晤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了敏簿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宣虾,失蹤者是張志新(化名)和其女友劉穎惯裕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绣硝,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡蜻势,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鹉胖。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片握玛。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖甫菠,靈堂內(nèi)的尸體忽然破棺而出挠铲,到底是詐尸還是另有隱情,我是刑警寧澤寂诱,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布拂苹,位于F島的核電站,受9級特大地震影響痰洒,放射性物質(zhì)發(fā)生泄漏瓢棒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一丘喻、第九天 我趴在偏房一處隱蔽的房頂上張望脯宿。 院中可真熱鬧,春花似錦泉粉、人聲如沸连霉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窘面。三九已至翠语,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間财边,已是汗流浹背肌括。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留酣难,地道東北人谍夭。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像憨募,于是被迫代替她去往敵國和親紧索。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 用兩張圖告訴你菜谣,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料珠漂? 從這篇文章中你...
    hw1212閱讀 12,730評論 2 59
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭尾膊,有人歡樂有人憂愁媳危,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,536評論 28 53
  • 首先介紹下自己的背景: 我11年左右入市到現(xiàn)在,也差不多有4年時間抓谴,看過一些關(guān)于股票投資的書籍暮蹂,對于巴菲特等股神的...
    瞎投資閱讀 5,731評論 3 8
  • ![Flask](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW...
    極客學(xué)院Wiki閱讀 7,249評論 0 3
  • 不知不覺易趣客已經(jīng)在路上走了快一年了仰泻,感覺也該讓更多朋友認識知道易趣客,所以就謝了這篇簡介滩届,已做創(chuàng)業(yè)記事我纪。 易趣客...
    Physher閱讀 3,420評論 1 2