實作類別似美圖秀秀裡面的屬性增強調節——設計模式練習,秀秀設計模式

來源:互聯網
上載者:User

實作類別似美圖秀秀裡面的屬性增強調節——設計模式練習,秀秀設計模式
1.在介面下方有3個按鈕,分別是亮度、色彩度、飽和度 
2. 點擊按鈕,選中一個,上面用一個捲軸顯示亮度、色彩度、飽和度的值,三個用同一個捲軸。 
3.選中後,滑動捲軸,調節當前選擇的亮度、色彩度、飽和度。(不用真調節相機,假實現即可,但需要考慮將來可能會實現,要預留實現介面) 

4.考慮一下,上面的需求可能會變化的情況,比如可能會增加減少要調節的項目,每個調節項目調節時觸發的動作會修改,代碼要能夠很方便擴充。請採用適合的設計模式解決


思路&設計:

首先,根據題目要求,按下不同的按鈕,調節不同的項目,這可以使用狀態模式來實現。具體來說,按鈕按下相當於切換了狀態,在不同的狀態下具有不同的行為,如色彩狀態調節色彩,亮度狀態調節亮度。

其次,要求每個項目對應的演算法可以調節,比如說色彩調節可以有3種演算法來實現,而可能根據不同情況選擇不同演算法。這裡就其實就是演算法的封裝,採用策略模式。

結構圖如下:



代碼如下:

狀態相關代碼:

package com.wbp.designmodelpractice2;import android.widget.TextView;// 抽象狀態類 abstract class ButtonState {protected int progress = 50;// 滑動條位置protected AdjustAlgo adjustAlgo; // 演算法類// 演算法開始執行abstract public void beginAdjust();// 更新狀態(包含演算法執行)abstract public void update();public void setAdjustAlgorithm(AdjustAlgo adjustAlgo) {this.adjustAlgo = adjustAlgo;}public void setProcess(int progress) {this.progress = progress;}public AdjustAlgo getAdjustAlgo() {return adjustAlgo;}public int getProcess() {return progress;}}// 亮度調節狀態類:具體狀態class LumState extends ButtonState {TextView tv;// 後期可能還會添加其他狀態相關組件 如 ImageView@Overridepublic void beginAdjust() {// TODO Auto-generated method stubadjustAlgo.excute(progress);}@Overridepublic void update() {// TODO Auto-generated method stubtv.setText(String.valueOf(progress));beginAdjust();}}// 色彩調節狀態類:具體狀態class ColorState extends ButtonState {TextView tv;// 後期可能還會添加其他狀態相關組件 如 ImageView@Overridepublic void beginAdjust() {// TODO Auto-generated method stubadjustAlgo.excute(progress);}@Overridepublic void update() {// TODO Auto-generated method stubtv.setText(String.valueOf(progress));beginAdjust();}}// 飽和度調節狀態類:具體狀態class SaturaState extends ButtonState {TextView tv;// 後期可能還會添加其他狀態相關組件 如 ImageView@Overridepublic void beginAdjust() {// TODO Auto-generated method stubadjustAlgo.excute(progress);}@Overridepublic void update() {// TODO Auto-generated method stubtv.setText(String.valueOf(progress));beginAdjust();}}

演算法相關代碼:

package com.wbp.designmodelpractice2;// 抽象演算法類abstract public class AdjustAlgo {abstract public void excute(int progress);}//抽象演算法類abstract class ColorAdjustAlgo extends AdjustAlgo{abstract public void excute(int progress);}//抽象演算法類abstract class LumAdjustAlgo extends AdjustAlgo{abstract public void excute(int progress);}//抽象演算法類abstract class SaturaAdjustAlgo extends AdjustAlgo{abstract public void excute(int progress);}// 色彩調節演算法類:具體演算法class ColorAdjustAlgoOne extends ColorAdjustAlgo {public void excute(int progress) {// 具體色彩調節演算法System.out.println("色彩--------------->演算法 1");}}// 色彩調節演算法類:具體演算法class ColorAdjustAlgTwo extends ColorAdjustAlgo {public void excute(int progress) {// 具體色彩調節演算法System.out.println("色彩--------------->演算法 2");}}// 亮度調節演算法類:具體演算法class LumAdjustAlgoOne extends AdjustAlgo {public void excute(int progress) {// 具體亮度調節演算法System.out.println("亮度--------------->演算法 1");}}// 亮度調節演算法類:具體演算法class LumAdjustAlgoTwo extends AdjustAlgo {public void excute(int progress) {// 具體亮度調節演算法System.out.println("亮度--------------->演算法 2");}}// 飽和度調節演算法類:具體演算法class SaturaAdjustAlgoOne extends AdjustAlgo {public void excute(int progress) {// 具體飽和度調節演算法System.out.println("飽和度--------------->演算法 1");}}// 飽和度調節演算法類:具體演算法class SaturaAdjustAlgoTwo extends AdjustAlgo {public void excute(int progress) {// 具體飽和度調節演算法System.out.println("飽和度--------------->演算法 2");}}

用戶端相關代碼:

package com.wbp.designmodelpractice2;import java.util.ArrayList;import java.util.List;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;import android.widget.TextView;public class MainActivity extends Activity implements OnClickListener {SeekBar seekbar;Button btnLum;Button btnColor;Button btnSatura;TextView tvLum;TextView tvColor;TextView tvSatura;List<ButtonState> stateList = new ArrayList<ButtonState>(); //ButtonState state;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}private void init() {// 介面初始化seekbar = (SeekBar) findViewById(R.id.seekBar1);seekbar.setProgress(50);btnLum = (Button) findViewById(R.id.btnLum);btnLum.setTag(0);btnLum.setOnClickListener(this);btnColor = (Button) findViewById(R.id.btnColor);btnColor.setTag(1);btnColor.setOnClickListener(this);btnSatura = (Button) findViewById(R.id.btnSatura);btnSatura.setTag(2);btnSatura.setOnClickListener(this);// 建立所有狀態,並設定其對應的演算法LumState lum = new LumState();lum.tv = (TextView) findViewById(R.id.tvLum);lum.setAdjustAlgorithm(new LumAdjustAlgoOne());stateList.add(lum);ColorState color = new ColorState();color.tv = (TextView) findViewById(R.id.tvColor);color.setAdjustAlgorithm(new ColorAdjustAlgoOne());stateList.add(color);SaturaState satura = new SaturaState();satura.tv = (TextView) findViewById(R.id.tvSatura);satura.setAdjustAlgorithm(new SaturaAdjustAlgoTwo());stateList.add(satura);state = (ButtonState) stateList.get(0);seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stub// 應用演算法state.setProcess(progress);state.update();}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubstate = (ButtonState) stateList.get((Integer) arg0.getTag());seekbar.setProgress(state.getProcess());state.update();}}

說明:

1、擴充項目只需要增加新的狀態類即可,擴充項目對應的演算法只需要增加新的演算法類即可,擴充很方便,完全符合“開閉”原則。這裡有一點要說明的是,擴充項目的時候不一定像本題這樣只通過TextView來顯示項目數值,實際很可能還要顯示別的組件,比如說顯示顏色塊,能讓人直觀的感受顏色變化。這一點通過狀態類的擴充也容易做到。

2、標準的狀態模式增加新的狀態類需要修改負責狀態轉換的原始碼,所以對“開閉”原則的支援並不好,這裡巧妙的採用了Button點擊來切換狀態,解決了這個問題。

3、關於設計模式的選擇:剛接觸到這個題目的時候看到項目和演算法兩個維度變化,感覺應該用橋接模式。但是自己思考過後,認為用在這裡並不恰當。橋接模式兩個維度分別有M、N種變化,那麼總變化數為M*N,而且這M*N種變化都有存在的意義。但是本題目不是這樣的,比如說,將顏色演算法用到亮度狀態上,結果顯然是不倫不類的。

4、關於設計模式的體會:其實23中設計模式也只是相當於一些例子罷了,最重要的還是物件導向設計的那7個設計原則。開閉原則是目標,裡氏代換原則是基礎,依賴倒轉原則是手段。對於如何編寫擴充性好的程式,我的經驗是,類和介面的設計要功能簡單,然後編程的時候針對介面編程,這樣就很容易符合“開閉”原則了。


其他:

1、最近看到很多設計模式採用 設定檔+反射機制 ,擴充只需要增加相關類,修改設定檔即可,用戶端完全不需要改動。感覺這也太牛了吧!!千方百計想用在本例中,但是最終還是做不到。最起碼按鈕以及按鈕的響應得添加吧,這些內容的添加難道可以不修改用戶端嗎?求解啊%>_<%

2、感覺設計的並不好,希望路過的高人不吝賜教



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.