本文共 31656 字,大约阅读时间需要 105 分钟。
设计模式主要有23种,大致可分为三类:创建型,机构行,行为型;具体如下:
持续更新中...
结构型模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决特定应用场景的问题。结构型模式包括:代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式。
装饰模式(Decorator Pattern)主要解决继承过于复杂的问题,通过组合来替代继承;也就是说是继承关系的一种替代方案之一;
UML图中各个部分代表的含义如下:
组件类
public abstract class Component { public abstract void operate();}
组件具体实现类
public class ConcreteComponent extends Component { @Override public void operate() { }}
抽象装饰类(如果装饰逻辑单一,只有一个的情况下我们可以省略该抽象类,直接是具体的装饰者)
public abstract class Decorator extends Component { private Component mComponent; public Decorator(Component mComponent) { this.mComponent = mComponent; } @Override public void operate() { mComponent.operate(); }}
抽象装饰类具体实现类
public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component mComponent) { super(mComponent); } @Override public void operate() { operateA(); super.operate(); operateB(); } public void operateA() { } public void operateB() { }}
装饰模式在生活中无处不在,比如说牙膏包装盒,人各种穿着,不管怎么包装但是,人还是那个人本质没有变;
学过Java语言的熟悉IO流,BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,DataInputStream,DataOutputStream;都是装饰者,都是对装饰设计模式的运用;感兴趣的可以自行查看源码;
下面以BufferedReader为例粘贴部分源码:
Writer:相当于UML图中的组件类
public abstract class Writer implements Appendable, Closeable, Flushable { protected Object lock; protected Writer() { lock = this; } protected Writer(Object lock) { if (lock == null) { throw new NullPointerException("lock == null"); } this.lock = lock; } public abstract void close() throws IOException; public abstract void flush() throws IOException; public void write(char[] buf) throws IOException { write(buf, 0, buf.length); } public abstract void write(char[] buf, int offset, int count) throws IOException; public void write(int oneChar) throws IOException { synchronized (lock) { char[] oneCharArray = new char[1]; oneCharArray[0] = (char) oneChar; write(oneCharArray); } } public void write(String str) throws IOException { write(str, 0, str.length()); } public void write(String str, int offset, int count) throws IOException { if ((offset | count) < 0 || offset > str.length() - count) { throw new StringIndexOutOfBoundsException(str, offset, count); } char[] buf = new char[count]; str.getChars(offset, offset + count, buf, 0); synchronized (lock) { write(buf, 0, buf.length); } } public Writer append(char c) throws IOException { write(c); return this; } public Writer append(CharSequence csq) throws IOException { if (csq == null) { csq = "null"; } write(csq.toString()); return this; } public Writer append(CharSequence csq, int start, int end) throws IOException { if (csq == null) { csq = "null"; } write(csq.subSequence(start, end).toString()); return this; } boolean checkError() { return false; }}
FileWriter(OutputStreamWriter或者其他具体实现类):相当于组件具体实现类(OutputStreamWriter 继承Writer)
public class FileWriter extends OutputStreamWriter { public FileWriter(File file) throws IOException { super(new FileOutputStream(file)); } public FileWriter(File file, boolean append) throws IOException { super(new FileOutputStream(file, append)); } public FileWriter(FileDescriptor fd) { super(new FileOutputStream(fd)); } public FileWriter(String filename) throws IOException { super(new FileOutputStream(new File(filename))); } public FileWriter(String filename, boolean append) throws IOException { super(new FileOutputStream(filename, append)); }}
BufferedWriter:相当于UML图中的具体装饰类(BufferedWriter内部持有了Writer的引用)
public class BufferedWriter extends Writer { private Writer out; private char[] buf; private int pos; public BufferedWriter(Writer out) { this(out, 8192); } public BufferedWriter(Writer out, int size) { super(out); if (size <= 0) { throw new IllegalArgumentException("size <= 0"); } this.out = out; this.buf = new char[size]; } @Override public void close() throws IOException { synchronized (lock) { if (isClosed()) { return; } Throwable thrown = null; try { flushInternal(); } catch (Throwable e) { thrown = e; } buf = null; try { out.close(); } catch (Throwable e) { if (thrown == null) { thrown = e; } } out = null; if (thrown != null) { SneakyThrow.sneakyThrow(thrown); } } } @Override public void flush() throws IOException { synchronized (lock) { checkNotClosed(); flushInternal(); out.flush(); } } private void checkNotClosed() throws IOException { if (isClosed()) { throw new IOException("BufferedWriter is closed"); } } private void flushInternal() throws IOException { if (pos > 0) { out.write(buf, 0, pos); } pos = 0; } private boolean isClosed() { return out == null; } public void newLine() throws IOException { write(System.lineSeparator()); } @Override public void write(char[] buffer, int offset, int count) throws IOException { synchronized (lock) { checkNotClosed(); if (buffer == null) { throw new NullPointerException("buffer == null"); } Arrays.checkOffsetAndCount(buffer.length, offset, count); if (pos == 0 && count >= this.buf.length) { out.write(buffer, offset, count); return; } int available = this.buf.length - pos; if (count < available) { available = count; } if (available > 0) { System.arraycopy(buffer, offset, this.buf, pos, available); pos += available; } if (pos == this.buf.length) { out.write(this.buf, 0, this.buf.length); pos = 0; if (count > available) { offset += available; available = count - available; if (available >= this.buf.length) { out.write(buffer, offset, available); return; } System.arraycopy(buffer, offset, this.buf, pos, available); pos += available; } } } } @Override public void write(int oneChar) throws IOException { synchronized (lock) { checkNotClosed(); if (pos >= buf.length) { out.write(buf, 0, buf.length); pos = 0; } buf[pos++] = (char) oneChar; } } @Override public void write(String str, int offset, int count) throws IOException { synchronized (lock) { checkNotClosed(); if (count <= 0) { return; } if (offset < 0 || offset > str.length() - count) { throw new StringIndexOutOfBoundsException(str, offset, count); } if (pos == 0 && count >= buf.length) { char[] chars = new char[count]; str.getChars(offset, offset + count, chars, 0); out.write(chars, 0, count); return; } int available = buf.length - pos; if (count < available) { available = count; } if (available > 0) { str.getChars(offset, offset + available, buf, pos); pos += available; } if (pos == buf.length) { out.write(this.buf, 0, this.buf.length); pos = 0; if (count > available) { offset += available; available = count - available; if (available >= buf.length) { char[] chars = new char[count]; str.getChars(offset, offset + available, chars, 0); out.write(chars, 0, available); return; } str.getChars(offset, offset + available, buf, pos); pos += available; } } } }}
在Android源码也有对装饰模式的运用
Context类做Android的都不陌生,毫不夸张的说几乎每天都在用,四大组件每个里面都有他的直接或间接的引用到;Context本质上是一个抽象类,在装饰设计模式相当于抽象组件,在其内部定义了大量的抽象方法,比如我经常用到的startService和startActivity方法。通过查看Context源码是不是感觉很多方法很熟悉;
package android.content;//省略很多方法和其他包名等public abstract class Context { public abstract AssetManager getAssets(); public abstract Resources getResources(); public abstract Looper getMainLooper(); @NonNull public final CharSequence getText(@StringRes int resId) { return getResources().getText(resId); } @NonNull public final String getString(@StringRes int resId) { return getResources().getString(resId); } @NonNull public final String getString(@StringRes int resId, Object... formatArgs) { return getResources().getString(resId, formatArgs); } @ColorInt public final int getColor(@ColorRes int id) { return getResources().getColor(id, getTheme()); } @Nullable public final Drawable getDrawable(@DrawableRes int id) { return getResources().getDrawable(id, getTheme()); } @NonNull public final ColorStateList getColorStateList(@ColorRes int id) { return getResources().getColorStateList(id, getTheme()); } public abstract void setTheme(@StyleRes int resid); @ViewDebug.ExportedProperty(deepExport = true) public abstract Resources.Theme getTheme(); public abstract ClassLoader getClassLoader(); public abstract String getPackageName(); @UnsupportedAppUsage public abstract String getBasePackageName(); @NonNull public String getOpPackageName() { throw new RuntimeException("Not implemented. Must override in a subclass."); } /** Return the full application info for this context's package. */ public abstract ApplicationInfo getApplicationInfo(); public abstract String getPackageResourcePath(); public abstract String getPackageCodePath(); @Deprecated @UnsupportedAppUsage public File getSharedPrefsFile(String name) { return getSharedPreferencesPath(name); } public abstract SharedPreferences getSharedPreferences(String name, @PreferencesMode int mode); public abstract SharedPreferences getSharedPreferences(File file, @PreferencesMode int mode); public abstract boolean moveSharedPreferencesFrom(Context sourceContext, String name); public abstract boolean deleteSharedPreferences(String name); /** @hide */ public abstract void reloadSharedPreferences(); public abstract FileInputStream openFileInput(String name) throws FileNotFoundException; public abstract FileOutputStream openFileOutput(String name, @FileMode int mode) throws FileNotFoundException; public abstract boolean deleteFile(String name); public abstract File getFileStreamPath(String name); public abstract File getSharedPreferencesPath(String name); public abstract File getDataDir(); public abstract File getFilesDir(); public abstract File getNoBackupFilesDir(); @Nullable public abstract File getExternalFilesDir(@Nullable String type); public abstract File getObbDir(); public abstract File[] getObbDirs(); public abstract File getCacheDir(); public abstract File getCodeCacheDir(); @Nullable public abstract File getExternalCacheDir(); @Nullable @SystemApi public abstract File getPreloadsFileCache(); public abstract File[] getExternalCacheDirs(); public abstract File[] getExternalMediaDirs(); public abstract String[] fileList(); public abstract File getDir(String name, @FileMode int mode); public abstract SQLiteDatabase openOrCreateDatabase(String name, @DatabaseMode int mode, CursorFactory factory); public abstract SQLiteDatabase openOrCreateDatabase(String name, @DatabaseMode int mode, CursorFactory factory, @Nullable DatabaseErrorHandler errorHandler); public abstract void startActivity(@RequiresPermission Intent intent); public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle options); @UnsupportedAppUsage public void startActivityForResult( @NonNull String who, Intent intent, int requestCode, @Nullable Bundle options) { throw new RuntimeException("This method is only implemented for Activity-based Contexts. " + "Check canStartActivityForResult() before calling."); } public abstract void startActivities(@RequiresPermission Intent[] intents); public abstract void startActivities(@RequiresPermission Intent[] intents, Bundle options); public abstract void sendBroadcast(@RequiresPermission Intent intent); public abstract void sendBroadcast(@RequiresPermission Intent intent, @Nullable String receiverPermission); @SystemApi public abstract void sendBroadcast(Intent intent, @Nullable String receiverPermission, @Nullable Bundle options); @UnsupportedAppUsage public abstract void sendBroadcast(Intent intent, String receiverPermission, int appOp); public abstract void sendOrderedBroadcast(@RequiresPermission Intent intent, @Nullable String receiverPermission); public abstract void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, @Nullable String receiverPermission, @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras); @SystemApi public abstract void sendOrderedBroadcast(@NonNull Intent intent, @Nullable String receiverPermission, @Nullable Bundle options, @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras); @Nullable public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter); @Nullable public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter, @RegisterReceiverFlags int flags); @Nullable public abstract Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler); @Nullable public abstract Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler, @RegisterReceiverFlags int flags); @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) @UnsupportedAppUsage public abstract Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, @Nullable String broadcastPermission, @Nullable Handler scheduler); public abstract void unregisterReceiver(BroadcastReceiver receiver); @Nullable public abstract ComponentName startService(Intent service); @Nullable public abstract ComponentName startForegroundService(Intent service); public abstract boolean stopService(Intent service); @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) @UnsupportedAppUsage public abstract ComponentName startServiceAsUser(Intent service, UserHandle user); public abstract boolean bindService(@RequiresPermission Intent service, @NonNull ServiceConnection conn, @BindServiceFlags int flags); public boolean bindService(@RequiresPermission @NonNull Intent service, @BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor, @NonNull ServiceConnection conn) { throw new RuntimeException("Not implemented. Must override in a subclass."); } @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) @UnsupportedAppUsage public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) { throw new RuntimeException("Not implemented. Must override in a subclass."); } public abstract void unbindService(@NonNull ServiceConnection conn); /** * Return the handle to a system-level service by name. The class of the * returned object varies by the requested name. Currently available names * are: * *
Note: System services obtained via this API may be closely associated with * the Context in which they are obtained from. In general, do not share the * service objects between various different contexts (Activities, Applications, * Services, Providers, etc.) * *
Note: Instant apps, for which {@link PackageManager#isInstantApp()} returns true, * don't have access to the following system services: {@link #DEVICE_POLICY_SERVICE}, * {@link #FINGERPRINT_SERVICE}, {@link #KEYGUARD_SERVICE}, {@link #SHORTCUT_SERVICE}, * {@link #USB_SERVICE}, {@link #WALLPAPER_SERVICE}, {@link #WIFI_P2P_SERVICE}, * {@link #WIFI_SERVICE}, {@link #WIFI_AWARE_SERVICE}. For these services this method will * return null
. Generally, if you are running as an instant app you should always * check whether the result of this method is {@code null}. * *
Note: When implementing this method, keep in mind that new services can be added on newer * Android releases, so if you're looking for just the explicit names mentioned above, make sure * to return {@code null} when you don't recognize the name — if you throw a * {@link RuntimeException} exception instead, you're app might break on new Android releases. * * @param name The name of the desired service. * * @return The service or {@code null} if the name does not exist. * * @see #WINDOW_SERVICE * @see android.view.WindowManager * @see #LAYOUT_INFLATER_SERVICE * @see android.view.LayoutInflater * @see #ACTIVITY_SERVICE * @see android.app.ActivityManager * @see #POWER_SERVICE * @see android.os.PowerManager * @see #ALARM_SERVICE * @see android.app.AlarmManager * @see #NOTIFICATION_SERVICE * @see android.app.NotificationManager * @see #KEYGUARD_SERVICE * @see android.app.KeyguardManager * @see #LOCATION_SERVICE * @see android.location.LocationManager * @see #SEARCH_SERVICE * @see android.app.SearchManager * @see #SENSOR_SERVICE * @see android.hardware.SensorManager * @see #STORAGE_SERVICE * @see android.os.storage.StorageManager * @see #VIBRATOR_SERVICE * @see android.os.Vibrator * @see #CONNECTIVITY_SERVICE * @see android.net.ConnectivityManager * @see #WIFI_SERVICE * @see android.net.wifi.WifiManager * @see #AUDIO_SERVICE * @see android.media.AudioManager * @see #MEDIA_ROUTER_SERVICE * @see android.media.MediaRouter * @see #TELEPHONY_SERVICE * @see android.telephony.TelephonyManager * @see #TELEPHONY_SUBSCRIPTION_SERVICE * @see android.telephony.SubscriptionManager * @see #CARRIER_CONFIG_SERVICE * @see android.telephony.CarrierConfigManager * @see #INPUT_METHOD_SERVICE * @see android.view.inputmethod.InputMethodManager * @see #UI_MODE_SERVICE * @see android.app.UiModeManager * @see #DOWNLOAD_SERVICE * @see android.app.DownloadManager * @see #BATTERY_SERVICE * @see android.os.BatteryManager * @see #JOB_SCHEDULER_SERVICE * @see android.app.job.JobScheduler * @see #NETWORK_STATS_SERVICE * @see android.app.usage.NetworkStatsManager * @see android.os.HardwarePropertiesManager * @see #HARDWARE_PROPERTIES_SERVICE */ public abstract @Nullable Object getSystemService(@ServiceName @NonNull String name); @SuppressWarnings("unchecked") public final @Nullable
其实现类是android.app.ContextImpl,ContextImpl继承Context,并实现了Context中的抽象方法;这里的ContextImpl相当于组件的具体实现类;
class ContextImpl extends Context { @Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, false, mUser); } @Override public ComponentName startForegroundService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, true, mUser); } @Override public boolean stopService(Intent service) { warnIfCallingFromSystemProcess(); return stopServiceCommon(service, mUser); } @Override public boolean bindService(Intent service, ServiceConnection conn, int flags) { warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, getUser()); } @Override public boolean bindService( Intent service, int flags, Executor executor, ServiceConnection conn) { warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, null, null, executor, getUser()); } @Override public void sendBroadcast(Intent intent) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }@Override public void sendBroadcast(Intent intent, String receiverPermission) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); String[] receiverPermissions = receiverPermission == null ? null : new String[] {receiverPermission}; try { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public void sendOrderedBroadcast(Intent intent, String receiverPermission) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); String[] receiverPermissions = receiverPermission == null ? null : new String[] {receiverPermission}; try { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE, null, true, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }}
Android中的Activity相比大家都很熟,从继承上说其实也是一个Content,但是Activity不是直接继承Content的,而是继承ContextThemeWrapper;
public class Activity extends ContextThemeWrapper { @MainThread @CallSuper protected void onCreate(@Nullable Bundle savedInstanceState) { }}
而ContextThemeWrapper又继承ContextWrapper
public class ContextThemeWrapper extends ContextWrapper { @UnsupportedAppUsage private int mThemeResource; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768723) private Resources.Theme mTheme; @UnsupportedAppUsage private LayoutInflater mInflater; private Configuration mOverrideConfiguration; @UnsupportedAppUsage private Resources mResources;}
最终ContextWrapper才继承Context,是不是感觉很复杂,其实这里就是一个典型的装饰模式的运用,ContextWrapper就是我们要找的装饰着,在ContextWrapper中有一个Context的引用。
public class ContextWrapper extends Context { @UnsupportedAppUsage Context mBase; public ContextWrapper(Context base) { mBase = base; } }
我们再看一下ContextWrapper内部的来自于组件的方法;
public class ContextWrapper extends Context { @Override public ComponentName startService(Intent service) { return mBase.startService(service); } @Override public boolean stopService(Intent name) { return mBase.stopService(name); }}
从上面的源码可以看出ContextWrapper中的startService方法也仅仅是调用了组件实现类(ContextImpl)中对应的方法而已,对于具体方法的包装扩展则有ContextWrapper的具体子类完成;比如我们的Service,Activity,Application.
转载地址:http://hcvjz.baihongyu.com/