1. 程式人生 > >cordova-plugin-datepicker 新增只選擇年月的模式(android)

cordova-plugin-datepicker 新增只選擇年月的模式(android)

cordova-plugin-datepicker 這個cordova 官網的日期選擇的外掛,裡面有幾個模式,分別是date 日期選擇,time 時間選擇,還有datetime 日期時間都選的模式。但是有時候會有這樣的需求,只顯示選擇年和月,或者只顯示選擇月和日。這時候就需要我們來改造下這個外掛,以下下只顯示選擇年和月為例。

首先,我們去扒下這個官方的外掛的程式碼,我們可以看到,裡面在呼叫日期和時間選擇的時候是直接呼叫系統的DatePickerDialog 和TimePickerDialog 這個對話方塊,看來下程式碼,感覺DatePickerDialog這個對話方塊和我們需要有點像,就是要把DatePickerDialog裡面的年的選擇或者日的選擇隱藏掉就可以。然後在修改下,改變選擇器時對應的擡頭的變化和返回的值就可以了。大概思路就是這樣了。開始搞。

寫個CustomerDatePickerDialog 來整合DatePickerDialog,重寫當滑輪變化的時候title的顯示。

class CustomerDatePickerDialog extends DatePickerDialog {

        public CustomerDatePickerDialog(Context context,
                                        OnDateSetListener callBack, int year, int monthOfYear,
                                        int
dayOfMonth) { super(context, callBack, year, monthOfYear, dayOfMonth); } @Override public void onDateChanged(DatePicker view, int year, int month, int day) { super.onDateChanged(view, year, month, day); mDialog.setTitle(year+"年"+(month + 1
) + "月" ); } }

顯示選擇器,然後通過獲取介面的內容來獲取DatePicker這個元件,我們要改變的年月日的滑輪都在這個裡面。
獲取DatePicker:

final DateSetListener dateSetListener = new DateSetListener(datePickerPlugin, theme, callbackContext, jsonDate);
                    mDialog = new CustomerDatePickerDialog(currentCtx, dateSetListener, jsonDate.year,
                            jsonDate.month, jsonDate.day);

mDialog.show();

介面上有顯示這個對話方塊後,我們就要獲取DatePicker這個元件,然後隱藏掉想隱藏的東西。

DatePicker dp = findDatePicker((ViewGroup) mDialog.getWindow().getDecorView());
                    if (dp != null) {

                        ((ViewGroup)((ViewGroup) dp.getChildAt(0)).getChildAt(0)).getChildAt(2).setVisibility(View.GONE);   //隱藏掉日滾輪,一般最後一個的子元件0是年,1是月,2是日
                        }

從介面中獲取DatePicker:

private DatePicker findDatePicker(ViewGroup group) {
        if (group != null) {
            for (int i = 0, j = group.getChildCount(); i < j; i++) {
                View child = group.getChildAt(i);
                if (child instanceof DatePicker) {
                    return (DatePicker) child;
                } else if (child instanceof ViewGroup) {
                    DatePicker result = findDatePicker((ViewGroup) child);
                    if (result != null)
                        return result;
                }
            }
        }
        return null;

    }

完整修改後外掛的DatePickerPlugin.java檔案如下,呼叫的時候mode的型別用YearAndMonth 就可以了,用法基本和date的一樣:

/**
 * @author Bikas Vaibhav (http://bikasv.com) 2013
 * Rewrote the plug-in at https://github.com/phonegap/phonegap-plugins/tree/master/Android/DatePicker
 * It can now accept `min` and `max` dates for DatePicker.
 *
 * @author Andre Moraes (https://github.com/andrelsmoraes)
 * Refactored code, changed default mode to show date and time dialog.
 * Added options `okText`, `cancelText`, `todayText`, `nowText`, `is24Hour`.
 *
 * @author Diego Silva (https://github.com/diego-silva)
 * Added option `titleText`.
 */

package com.plugin.datepicker;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Random;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.NumberPicker;
import android.widget.TimePicker;

@SuppressLint("NewApi")
public class DatePickerPlugin extends CordovaPlugin {

    private static final String ACTION_DATE = "date";
    private static final String ACTION_TIME = "time";
    private static final String ACTION_MONTH = "YearAndMonth";
    private static final String RESULT_ERROR = "error";
    private static final String RESULT_CANCEL = "cancel";
    private final String pluginName = "DatePickerPlugin";
    private CustomerDatePickerDialog mDialog;

    // On some devices, onDateSet or onTimeSet are being called twice
    private boolean called = false;
    private boolean canceled = false;

    @Override
    public boolean execute(final String action, final JSONArray data, final CallbackContext callbackContext) {
        Log.d(pluginName, "DatePicker called with options: " + data);
        called = false;
        canceled = false;
        boolean result = false;

        this.show(data, callbackContext);
        result = true;

        return result;
    }

    public synchronized void show(final JSONArray data, final CallbackContext callbackContext) {
        DatePickerPlugin datePickerPlugin = this;
        Context currentCtx = cordova.getActivity();
        Runnable runnable;
        JsonDate jsonDate = new JsonDate().fromJson(data);

    // Retrieve Android theme
    JSONObject options = data.optJSONObject(0);
    int theme = options.optInt("androidTheme", 1);

        if (ACTION_TIME.equalsIgnoreCase(jsonDate.action)) {
            runnable = runnableTimeDialog(datePickerPlugin, theme, currentCtx,
                    callbackContext, jsonDate, Calendar.getInstance(TimeZone.getDefault()));

        } else if(ACTION_MONTH.equalsIgnoreCase(jsonDate.action)){   //2016/12/5 新增只選擇年和月
            runnable = runnableDatePicker(datePickerPlugin, theme, currentCtx, callbackContext, jsonDate);
        }else {
            runnable = runnableDatePicker(datePickerPlugin, theme, currentCtx, callbackContext, jsonDate);
        }

        cordova.getActivity().runOnUiThread(runnable);
    }

    private TimePicker timePicker;
    private int timePickerHour = 0;
    private int timePickerMinute = 0;

    private Runnable runnableTimeDialog(final DatePickerPlugin datePickerPlugin,
            final int theme, final Context currentCtx, final CallbackContext callbackContext,
            final JsonDate jsonDate, final Calendar calendarDate) {
        return new Runnable() {
            @Override
            public void run() {
                final TimeSetListener timeSetListener = new TimeSetListener(datePickerPlugin, callbackContext, calendarDate);
                final TimePickerDialog timeDialog = new TimePickerDialog(currentCtx, theme, timeSetListener, jsonDate.hour,
                        jsonDate.minutes, jsonDate.is24Hour) {
                    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
                        timePicker = view;
                        timePickerHour = hourOfDay;
                        timePickerMinute = minute;
                    }
                };
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    timeDialog.setCancelable(true);
                    timeDialog.setCanceledOnTouchOutside(false);

                    if (!jsonDate.titleText.isEmpty()){
                        timeDialog.setTitle(jsonDate.titleText);
                    }
                    if (!jsonDate.nowText.isEmpty()){
                        timeDialog.setButton(DialogInterface.BUTTON_NEUTRAL, jsonDate.nowText, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                if (timePicker != null) {
                                    Calendar now = Calendar.getInstance();
                                    timeSetListener.onTimeSet(timePicker, now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE));
                                }
                            }
                        });
                    }
                    String labelCancel = jsonDate.cancelText.isEmpty() ? currentCtx.getString(android.R.string.cancel) : jsonDate.cancelText; 
                    timeDialog.setButton(DialogInterface.BUTTON_NEGATIVE, labelCancel, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            canceled = true;
                            callbackContext.error(RESULT_CANCEL);
                        }
                    });
                    String labelOk = jsonDate.okText.isEmpty() ? currentCtx.getString(android.R.string.ok) : jsonDate.okText;
                    timeDialog.setButton(DialogInterface.BUTTON_POSITIVE, labelOk, timeDialog);
                }
                timeDialog.show();
                timeDialog.updateTime(new Random().nextInt(23), new Random().nextInt(59));
                timeDialog.updateTime(jsonDate.hour, jsonDate.minutes);
            }
        };
    }

    private Runnable runnableDatePicker(
            final DatePickerPlugin datePickerPlugin,
            final int theme, final Context currentCtx,
            final CallbackContext callbackContext, final JsonDate jsonDate) {
        return new Runnable() {
            @Override
            public void run() {
                if(ACTION_MONTH.equalsIgnoreCase(jsonDate.action)){     //只選擇年月
                    final DateSetListener dateSetListener = new DateSetListener(datePickerPlugin, theme, callbackContext, jsonDate);
                    mDialog = new CustomerDatePickerDialog(currentCtx, dateSetListener, jsonDate.year,
                            jsonDate.month, jsonDate.day);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        prepareDialog(mDialog, dateSetListener, callbackContext, currentCtx, jsonDate);
                    }
                    else {
                        prepareDialogPreHoneycomb(mDialog, callbackContext, currentCtx, jsonDate);
                    }



                    mDialog.show();
                    DatePicker dp = findDatePicker((ViewGroup) mDialog.getWindow().getDecorView());
                    if (dp != null) {

                        ((ViewGroup)((ViewGroup) dp.getChildAt(0)).getChildAt(0)).getChildAt(2).setVisibility(View.GONE);   //隱藏掉日滾輪

                    }
                }else{
                    final DateSetListener dateSetListener = new DateSetListener(datePickerPlugin, theme, callbackContext, jsonDate);
                    final DatePickerDialog dateDialog = new DatePickerDialog(currentCtx, theme, dateSetListener, jsonDate.year,
                            jsonDate.month, jsonDate.day);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                        prepareDialog(dateDialog, dateSetListener, callbackContext, currentCtx, jsonDate);
                    }
                    else {
                        prepareDialogPreHoneycomb(dateDialog, callbackContext, currentCtx, jsonDate);
                    }

                    dateDialog.show();
                }

            }
        };
    }

    private void prepareDialog(final DatePickerDialog dateDialog, final OnDateSetListener dateListener, 
            final CallbackContext callbackContext, Context currentCtx, JsonDate jsonDate) {
        dateDialog.setCancelable(true);
        dateDialog.setCanceledOnTouchOutside(false);
        if (!jsonDate.titleText.isEmpty()){
            dateDialog.setTitle(jsonDate.titleText);
        }
        if (!jsonDate.todayText.isEmpty()){
            dateDialog.setButton(DialogInterface.BUTTON_NEUTRAL, jsonDate.todayText, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Calendar now = Calendar.getInstance();
                    DatePicker datePicker = dateDialog.getDatePicker();
                    dateListener.onDateSet(datePicker, now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH));
                }
            });
        }
        String labelCancel = jsonDate.cancelText.isEmpty() ? currentCtx.getString(android.R.string.cancel) : jsonDate.cancelText; 
        dateDialog.setButton(DialogInterface.BUTTON_NEGATIVE, labelCancel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                canceled = true;
                callbackContext.error(RESULT_CANCEL);
            }
        });
        String labelOk = jsonDate.okText.isEmpty() ? currentCtx.getString(android.R.string.ok) : jsonDate.okText;
        dateDialog.setButton(DialogInterface.BUTTON_POSITIVE, labelOk, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                DatePicker datePicker = dateDialog.getDatePicker();
                datePicker.clearFocus();
                dateListener.onDateSet(datePicker, datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth());
            }
        });

        DatePicker dp = dateDialog.getDatePicker();
        if(jsonDate.minDate > 0) {
            dp.setMinDate(jsonDate.minDate);
        }
        if(jsonDate.maxDate > 0 && jsonDate.maxDate > jsonDate.minDate) {
            dp.setMaxDate(jsonDate.maxDate);
        }
    }

    private void prepareDialogPreHoneycomb(DatePickerDialog dateDialog,
            final CallbackContext callbackContext, Context currentCtx, final JsonDate jsonDate){
        java.lang.reflect.Field mDatePickerField = null;
        try {
            mDatePickerField = dateDialog.getClass().getDeclaredField("mDatePicker");
        } catch (NoSuchFieldException e) {
            callbackContext.error(RESULT_ERROR);
        }
        mDatePickerField.setAccessible(true);
        DatePicker pickerView = null;
        try {
            pickerView = (DatePicker) mDatePickerField.get(dateDialog);
        } catch (IllegalArgumentException e) {
            callbackContext.error(RESULT_ERROR);
        } catch (IllegalAccessException e) {
            callbackContext.error(RESULT_ERROR);
        }

        final Calendar startDate = Calendar.getInstance();
        startDate.setTimeInMillis(jsonDate.minDate);
        final Calendar endDate = Calendar.getInstance();
        endDate.setTimeInMillis(jsonDate.maxDate);

        final int minYear = startDate.get(Calendar.YEAR);
        final int minMonth = startDate.get(Calendar.MONTH);
        final int minDay = startDate.get(Calendar.DAY_OF_MONTH);
        final int maxYear = endDate.get(Calendar.YEAR);
        final int maxMonth = endDate.get(Calendar.MONTH);
        final int maxDay = endDate.get(Calendar.DAY_OF_MONTH);

        if(startDate !=null || endDate != null) {
            pickerView.init(jsonDate.year, jsonDate.month, jsonDate.day, new OnDateChangedListener() {
                @Override
                public void onDateChanged(DatePicker view, int year, int month, int day) {
                    if(jsonDate.maxDate > 0 && jsonDate.maxDate > jsonDate.minDate) {
                        if(year > maxYear || month > maxMonth && year == maxYear || day > maxDay && year == maxYear && month == maxMonth){
                            view.updateDate(maxYear, maxMonth, maxDay);
                        }
                    }
                    if(jsonDate.minDate > 0) {
                        if(year < minYear || month < minMonth && year == minYear || day < minDay && year == minYear && month == minMonth) {
                            view.updateDate(minYear, minMonth, minDay);
                        }
                    }
                }
            });
        }
    }

    private final class DateSetListener implements OnDateSetListener {
        private JsonDate jsonDate;
        private final DatePickerPlugin datePickerPlugin;
        private final CallbackContext callbackContext;
        private final int theme;

        private DateSetListener(DatePickerPlugin datePickerPlugin, int theme, CallbackContext callbackContext, JsonDate jsonDate) {
            this.datePickerPlugin = datePickerPlugin;
            this.callbackContext = callbackContext;
            this.jsonDate = jsonDate;
      this.theme = theme;
        }

        /**
         * Return a string containing the date in the format YYYY/MM/DD or call TimeDialog if action != date
         */
        @Override
        public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
            if (canceled || called) {
                return;
            }
            called = true;
            canceled = false;

            Log.d("onDateSet", "called: " + called);
            Log.d("onDateSet", "canceled: " + canceled);
            Log.d("onDateSet", "mode: " + jsonDate.action);

            if (ACTION_DATE.equalsIgnoreCase(jsonDate.action)) {
                String returnDate = year + "/" + (monthOfYear + 1) + "/" + dayOfMonth;
                Log.d("onDateSet", "returnDate: " + returnDate);

                callbackContext.success(returnDate);

            }else if(ACTION_MONTH.equalsIgnoreCase(jsonDate.action)){   //只返回年月
                String returnDate = year + "/" + (monthOfYear + 1) ;
                Log.d("onDateSet", "returnDate: " + returnDate);

                callbackContext.success(returnDate);
            } else {
                // Open time dialog
                Calendar selectedDate = Calendar.getInstance();
                selectedDate.set(Calendar.YEAR, year);
                selectedDate.set(Calendar.MONTH, monthOfYear);
                selectedDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);

                cordova.getActivity().runOnUiThread(runnableTimeDialog(datePickerPlugin, theme, cordova.getActivity(),
                        callbackContext, jsonDate, selectedDate));
            }
        }
    }

    private final class TimeSetListener implements OnTimeSetListener {
        private Calendar calendarDate;
        private final CallbackContext callbackContext;

        private TimeSetListener(DatePickerPlugin datePickerPlugin, CallbackContext callbackContext, Calendar selectedDate) {
            this.callbackContext = callbackContext;
            this.calendarDate = selectedDate != null ? selectedDate : Calendar.getInstance();
        }

        /**
         * Return the current date with the time modified as it was set in the
         * time picker.
         */
        @Override
        public void onTimeSet(final TimePicker view, final int hourOfDay, final int minute) {
            if (canceled) {
                return;
            }

            calendarDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
            calendarDate.set(Calendar.MINUTE, minute);
            calendarDate.set(Calendar.SECOND, 0);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
            String toReturn = sdf.format(calendarDate.getTime());

            callbackContext.success(toReturn);
        }
    }

    private final class JsonDate {

        private String action = ACTION_DATE;
        private String titleText = "";
        private String okText = "";
        private String cancelText = "";
        private String todayText = "";
        private String nowText = "";
        private long minDate = 0;
        private long maxDate = 0;
        private int month = 0;
        private int day = 0;
        private int year = 0;
        private int hour = 0;
        private int minutes = 0;
        private boolean is24Hour = false;

        public JsonDate() {
            reset(Calendar.getInstance());
        }

        private void reset(Calendar c) {
            year = c.get(Calendar.YEAR);
            month = c.get(Calendar.MONTH);
            day = c.get(Calendar.DAY_OF_MONTH);
            hour = c.get(Calendar.HOUR_OF_DAY);
            minutes = c.get(Calendar.MINUTE);
        }

        public JsonDate fromJson(JSONArray data) {
            try {
                JSONObject obj = data.getJSONObject(0);
                action = isNotEmpty(obj, "mode") ? obj.getString("mode")
                        : ACTION_DATE;

                minDate = isNotEmpty(obj, "minDate") ? obj.getLong("minDate") : 0l;
                maxDate = isNotEmpty(obj, "maxDate") ? obj.getLong("maxDate") : 0l;

                titleText = isNotEmpty(obj, "titleText") ? obj.getString("titleText") : "";
                okText = isNotEmpty(obj, "okText") ? obj.getString("okText") : "";
                cancelText = isNotEmpty(obj, "cancelText") ? obj
                        .getString("cancelText") : "";
                todayText = isNotEmpty(obj, "todayText") ? obj
                        .getString("todayText") : "";
                nowText = isNotEmpty(obj, "nowText") ? obj.getString("nowText")
                        : "";
                is24Hour = isNotEmpty(obj, "is24Hour") ? obj.getBoolean("is24Hour")
                        : false;

                String optionDate = obj.getString("date");

                String[] datePart = optionDate.split("/");
                month = Integer.parseInt(datePart[0]) - 1;
                day = Integer.parseInt(datePart[1]);
                year = Integer.parseInt(datePart[2]);
                hour = Integer.parseInt(datePart[3]);
                minutes = Integer.parseInt(datePart[4]);

            } catch (JSONException e) {
                reset(Calendar.getInstance());
            }

            return this;
        }

        public boolean isNotEmpty(JSONObject object, String key)
                throws JSONException {
            return object.has(key)
                    && !object.isNull(key)
                    && object.get(key).toString().length() > 0
                    && !JSONObject.NULL.toString().equals(
                            object.get(key).toString());
        }

    }



    ////////////////////////////////////////////////////////////////
    //////////////////只選擇年月情況新增程式碼//////////////////////////
    /**
     * 從當前Dialog中查詢DatePicker子控制元件
     *
     * @param group
     * @return
     */
    private DatePicker findDatePicker(ViewGroup group) {
        if (group != null) {
            for (int i = 0, j = group.getChildCount(); i < j; i++) {
                View child = group.getChildAt(i);
                if (child instanceof DatePicker) {
                    return (DatePicker) child;
                } else if (child instanceof ViewGroup) {
                    DatePicker result = findDatePicker((ViewGroup) child);
                    if (result != null)
                        return result;
                }
            }
        }
        return null;

    }


    class CustomerDatePickerDialog extends DatePickerDialog {

        public CustomerDatePickerDialog(Context context,
                                        OnDateSetListener callBack, int year, int monthOfYear,
                                        int dayOfMonth) {
            super(context, callBack, year, monthOfYear, dayOfMonth);
        }

        @Override
        public void onDateChanged(DatePicker view, int year, int month, int day) {
            super.onDateChanged(view, year, month, day);

            mDialog.setTitle(year+"年"+(month + 1) + "月" );
        }
    }

    ////////////////////////////////////////////////////////////////
    //////////////////只選擇年月情況新增程式碼//////////////////////////
}

相關推薦

cordova-plugin-datepicker 新增選擇年月模式android

cordova-plugin-datepicker 這個cordova 官網的日期選擇的外掛,裡面有幾個模式,分別是date 日期選擇,time 時間選擇,還有datetime 日期時間都選的模式。但是有時候會有這樣的需求,只顯示選擇年和月,或者只顯示選擇月和日

日期選擇年月

原文地址:https://my.oschina.net/147258369/blog/322903 .datetimepicker({          format: 'yyyy-mm',          weekStart: 1,          autoclose

Hybrid APP 混合開發模式選擇之路

原文出處:http://www.cnblogs.com/yuanyingke/p/6060150.html 1、混合開發概述 Hybrid App主要以JS+Native兩者相互呼叫為主,從開發層面實現“一次開發,多處執行”的機制,成為真正適合跨平臺的開發。Hybr

大資料架構和模式對大資料問題應用解決方案模式選擇實現它的產品

  簡介   本系列的 第 3 部分 描述了針對最常見的、經常發生的大資料問題及其解決方案的原子模式和複合模式。本文將推薦可以用於架構大資料解決方案的三個解決方案模式。每個解決方案模式都使用了一個複合模式,該模式由邏輯元件構成(參見第 3 部分的介紹)。在本文末尾處,列出了產品和工具清單,它們可對映到每

Hybrid APP 混合開發模式選擇之路

原文出處:http://www.cnblogs.com/dailc/p/5930238.html#hybrid_2 目前的主流應用程式有四大型別:Native App、Hybrid App、React Native App、Web App。本文分別對這幾種方案做一些分析

GOF23—單例模式2

應該 一個 img bsp 漏洞 資源 nbsp 創建 就會 本文介紹單例模式(不包含枚舉單例模式)漏洞問題以及如何防止漏洞   1.反射可以破解單例模式,例子如下:       此時,我們運行Client類,發現s1和s2是一個對象,但s3和s4是不同的對象。 那麽如何防

『ORACLE』 設置Edit模式11g

配置 修改 sqlplus spa size span -s ont def SQL>define_editor=‘vi‘ 執行一條SQL語句再修改編輯 SQL>ed 可以將define _editor=‘vi‘這句話寫在sqlplus 的啟動配置腳本中『ORA

設計模式之適配器模式Adapter

功能 系統 第三方 抽象 可能 對象 期待 技術分享 適配器 我想要是說適配器模式,提一下“電壓”、“耳機”、“充電器”和 "USB” 的例子應該是比較恰當的了。就說說自己的親身經歷,我原來的手機是NOKIA5730。後來也不知道有沒有國行,但是不推薦大家買這款手機,不適

設計模式之建造者模式Builder

人的 做出 字體 存在 分享 定義 固定 也不會 抽象方法 一個人活到70歲以上,都會經歷這樣的幾個階段:嬰兒,少年,青年,中年,老年。並且每個人在各個階段肯定是不一樣的呀,我覺得可以說世界上不存在兩個人在人生的這5個階段的生活完全一樣,但是活到70歲以上的人,都經歷了這幾

[轉]設計模式--單例模式懶漢式和餓漢式

打印 是否 調用構造 餓漢 一段 tools 會有 輸出結果 java 單例模式是設計模式中比較簡單的一種。適合於一個類只有一個實例的情況,比如窗口管理器,打印緩沖池和文件系統, 它們都是原型的例子。典型的情況是,那些對象的類型被遍及一個軟件系統的不同對象訪問,因此需要一個

《跨界雜談》商業模式:金融

公眾 匯率 白狼 wcf qrcode 行業 mom 運動 bsp 2015-03-14 雷震子 雷震子 金融具有非常強的專業性,非常easy把筆者落到班門弄斧的境界。但也不想謹言慎行,大家將就看吧,別太把豆包當幹糧就中了。 金融歷史悠久,伴隨商業而生,

設計模式: 工廠模式

dem blank hibernate 執行 oid code 做出 void actor 工廠模式 工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。 在工廠模式中,我們在創建

單例模式Singleton

ech 單例模式 bsp 在線 創建 private 解決 餓漢式 dir 1.解決的問題:使得一個類只能夠創建一個對象。2.如何實現: ①私有化構造器,使得在類的外部不能調用該構造器 ②在類的內部創建一個實例 ③私有化該對象,通過公共的方法來調用(返回該

工廠模式

log ofa clas pri com urn 兩層 實現 需求 工廠方法模式:簡單工廠模式的進一步抽象和推廣。工廠方法模式把簡單工廠中的具體的工廠類劃分為兩層:抽象工廠層+具體工廠層,類圖如下: 涉及到的角色: 抽象產品角色:所有產品的共同父類或共有接口,用以實現多態

JAVA設計模式之單例模式

單例對象 日誌 locking anti 常見 基本上 title 加載 懶漢式 本文繼續介紹23種設計模式系列之單例模式。 概念:  java中單例模式是一種常見的設計模式,單例模式的寫法有好幾種,這裏主要介紹三種:懶漢式單例、餓漢式單例、登記式單例。  單例模式有以下特

PHP面向對象單例模式懶漢式

檢查 私有 構造函數 知識 單例 懶漢 變量 eof php面向對象 知識點: 一、三私一公: ①、私有靜態屬性,又來儲存生成的唯一對象 ②、私有構造函數 ③、私有克隆函數,防止克隆——clone ④、公共靜態方法,用來訪問靜態屬性儲存的對象,如果沒有對象,則生成此單例 二

代理模式Proxy

p s log 場景 private span 方法 陌生 機制 特殊 代理模式(Proxy) 代理模式:簡單明了。簡稱代理商,對代理這個詞想必大家都不陌生,現在微信上,幾乎全是各種代理商,哈哈哈。。。不錯。我們的代理模式,也是如此。用java語言來說。就是,替原對象進行一

跟我學設計模式視頻教程——管擦者模式,責任鏈模式

tar eight color font content 設計模式 name -m ack 課程視頻 觀察者模式(下) 責任鏈模式(上) 課程筆記 課程筆記 課程代碼 課程代碼 新課程火熱報名中 課程介紹

java面向對象與設計模式

工廠方法模式 java 選擇 缺點 一個 聯系 面向 抽象工廠 pan 第五式 抽象工廠模式 定義:提供一個創建一系列相關或相互依賴對象的接口,而無需指定他們具體的類。(創建的對象之間有約束) 抽象工廠模式的本質:選擇產品簇的實現 優點:分離接口和產品簇,使得切換產品簇變得

設計模式觀察者模式

針對 ray 需求 als bool 模式 null rri 主動 觀察者模式 定義了對象之間的一對多的依賴,這樣一來,當一個對象狀態改變時,他的 多有依賴都會受到通知並自動更新。 本例為一個溫度基站,和三個終端。溫度基站為廣播類WeatherData,三個終端監聽者類分別