Skip to content

Latest commit

 

History

History
545 lines (479 loc) · 16.6 KB

设计模式汇总.md

File metadata and controls

545 lines (479 loc) · 16.6 KB

设计模式分类

模式 & 描述 包括
创建型模式
提供了一种在创建对象的同时隐藏创建逻辑的方式。
工厂模式(Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)
单例模式(Singleton Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)
结构型模式
关注类和对象的组合。
适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
过滤器模式(Filter、Criteria Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
行为型模式
特别关注对象之间的通信。
责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
备忘录模式(Memento Pattern)
观察者模式(Observer Pattern)
状态模式(State Pattern)
空对象模式(Null Object Pattern)
策略模式(Strategy Pattern)
模板模式(Template Pattern)
访问者模式(Visitor Pattern)

面向对象六大原则

原则 描述
单一职责原则 一个类只负责一个功能领域中的相应职责。
开闭原则 对象应该对于扩展是开放的,对于修改是封闭的。
里氏替换原则 所有引用基类的地方必须能透明地使用其子类的对象。
依赖倒置原则 高层模块不依赖低层模块,两者应该依赖其对象;抽象不应该依赖细节;细节应该依赖抽象。
接口隔离原则 类间的依赖关系应该建立在最小的接口上。
迪米特原则 也称最少知识原则,一个对象对其他对象有最少的了解。

工厂模式

适用于复杂对象的创建。

示例:

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.demo);

BitmapFactory.java

// 生成 Bitmap 对象的工厂类 BitmapFactory
public class BitmapFactory {
    ···
    public static Bitmap decodeFile(String pathName) {
        ···
    }
    ···

    public static Bitmap decodeResource(Resources res, int id, Options opts) {
        validate(opts);
        Bitmap bm = null;
        InputStream is = null; 
        
        try {
            final TypedValue value = new TypedValue();
            is = res.openRawResource(id, value);

            bm = decodeResourceStream(res, value, is, null, opts);
        } 
        ···
        return bm;
    }
    ···
}

单例模式

确保某一个类只有一个实例,并自动实例化向整个系统提供这个实例,且可以避免产生多个对象消耗资源。

示例:

InputMethodManager.java

/**
* Retrieve the global InputMethodManager instance, creating it if it
* doesn't already exist.
* @hide
*/
public static InputMethodManager getInstance() {
    synchronized (InputMethodManager.class) {
        if (sInstance == null) {
            try {
                sInstance = new InputMethodManager(Looper.getMainLooper());
            } catch (ServiceNotFoundException e) {
                throw new IllegalStateException(e);
            }
        }
        return sInstance;
    }
}

建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,适用于初始化的对象比较复杂且参数较多的情况。

示例:

AlertDialog.Builder builder = new AlertDialog.Builder(this)
        .setTitle("Title")
        .setMessage("Message");
AlertDialog dialog = builder.create();
dialog.show();

AlertDialog.java

public class AlertDialog extends Dialog implements DialogInterface {
    ···

    public static class Builder {
        private final AlertController.AlertParams P;
        ···

        public Builder(Context context) {
            this(context, resolveDialogTheme(context, ResourceId.ID_NULL));
        }
        ···

        public Builder setTitle(CharSequence title) {
            P.mTitle = title;
            return this;
        }
        ···

        public Builder setMessage(CharSequence message) {
            P.mMessage = message;
            return this;
        }
        ···

        public AlertDialog create() {
            // Context has already been wrapped with the appropriate theme.
            final AlertDialog dialog = new AlertDialog(P.mContext, 0, false);
            P.apply(dialog.mAlert);
            ···
            return dialog;
        }
        ···
    }
}

原型模式

用原型模式实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

示例:

ArrayList<T> newArrayList = (ArrayList<T>) arrayList.clone();

ArrayList.java

/**
 * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The
 * elements themselves are not copied.)
 *
 * @return a clone of this <tt>ArrayList</tt> instance
 */
public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}

适配器模式

适配器模式把一个类的接口变成客户端所期待的另一种接口,从而使原因接口不匹配而无法一起工作的两个类能够在一起工作。

示例:

RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(new MyAdapter());

private class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        ···
    }

    ···
}

RecyclerView.java

···
private void setAdapterInternal(@Nullable Adapter adapter, boolean compatibleWithPrevious,
        boolean removeAndRecycleViews) {
    if (mAdapter != null) {
        mAdapter.unregisterAdapterDataObserver(mObserver);
        mAdapter.onDetachedFromRecyclerView(this);
    }
    ···
    mAdapterHelper.reset();
    final Adapter oldAdapter = mAdapter;
    mAdapter = adapter;
    if (adapter != null) {
        adapter.registerAdapterDataObserver(mObserver);
        adapter.onAttachedToRecyclerView(this);
    }
    if (mLayout != null) {
        mLayout.onAdapterChanged(oldAdapter, mAdapter);
    }
    mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious);
    mState.mStructureChanged = true;
}

···
public final class Recycler {
    @Nullable
    ViewHolder tryGetViewHolderForPositionByDeadline(int position,
            boolean dryRun, long deadlineNs) {
        ···
        ViewHolder holder = null;
        ···
        if (holder == null) {
            ···
            holder = mAdapter.createViewHolder(RecyclerView.this, type);
            ···
        }
        ···
        return holder;
    }
}

···
public abstract static class Adapter<VH extends ViewHolder> {
    ···
    @NonNull
    public abstract VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType);

    @NonNull
    public final VH createViewHolder(@NonNull ViewGroup parent, int viewType) {
        try {
            TraceCompat.beginSection(TRACE_CREATE_VIEW_TAG);
            final VH holder = onCreateViewHolder(parent, viewType);
            ···
            holder.mItemViewType = viewType;
            return holder;
        } finally {
            TraceCompat.endSection();
        }
    }
    ···
}

观察者模式

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

示例:

MyAdapter adapter = new MyAdapter();
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();

RecyclerView.java

···
private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver();

···
private void setAdapterInternal(@Nullable Adapter adapter, boolean compatibleWithPrevious,
        boolean removeAndRecycleViews) {
    ···
    mAdapter = adapter;
    if (adapter != null) {
        adapter.registerAdapterDataObserver(mObserver);
        adapter.onAttachedToRecyclerView(this);
    }
    ···
}

···
public abstract static class Adapter<VH extends ViewHolder> {
    private final AdapterDataObservable mObservable = new AdapterDataObservable();
    ···
    public void registerAdapterDataObserver(@NonNull AdapterDataObserver observer) {
        mObservable.registerObserver(observer);
    }

    ···
    public final void notifyDataSetChanged() {
        mObservable.notifyChanged();
    }
}

static class AdapterDataObservable extends Observable<AdapterDataObserver> {
    ···
    public void notifyChanged() {
        for (int i = mObservers.size() - 1; i >= 0; i--) {
            mObservers.get(i).onChanged();
        }
    }
    ···
}

private class RecyclerViewDataObserver extends AdapterDataObserver {
    ···
    @Override
    public void onChanged() {
        assertNotInLayoutOrScroll(null);
        mState.mStructureChanged = true;

        processDataSetCompletelyChanged(true);
        if (!mAdapterHelper.hasPendingUpdates()) {
            requestLayout();
        }
    }
    ···
}

代理模式

为其他的对象提供一种代理以控制对这个对象的访问。适用于当无法或不想直接访问某个对象时通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。

示例:

Context.java

public abstract class Context {
    ···
    public abstract void startActivity(@RequiresPermission Intent intent);
    ···
}

ContextWrapper.java

public class ContextWrapper extends Context {
    Context mBase; // 代理类,实为 ContextImpl 对象
    ···

    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }
    ···

    @Override
    public void startActivity(Intent intent) {
        mBase.startActivity(intent); // 核心工作交由给代理类对象 mBase 实现
    }
    ···
}

ContextImpl.java

// Context 的真正实现类
class ContextImpl extends Context {
    ...
    @Override
    public void startActivity(Intent intent) {
        warnIfCallingFromSystemProcess();
        startActivity(intent, null);
    }
    ...
}

责任链模式

使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

ViewGroup.java

@UiThread
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
    ···
    private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
            View child, int desiredPointerIdBits) {
        final boolean handled;
        ···
        final MotionEvent transformedEvent;
        if (newPointerIdBits == oldPointerIdBits) {
            if (child == null || child.hasIdentityMatrix()) {
                if (child == null) {
                    handled = super.dispatchTouchEvent(event);
                } else {
                    ···
                    // 获取子 view 处理的结果
                    handled = child.dispatchTouchEvent(event);
                }
                return handled;
            }
            transformedEvent = MotionEvent.obtain(event);
        } else {
            transformedEvent = event.split(newPointerIdBits);
        }

        // Perform any necessary transformations and dispatch.
        if (child == null) {
            handled = super.dispatchTouchEvent(transformedEvent);
        } else {
            ···
            // 获取子 view 处理的结果
            handled = child.dispatchTouchEvent(transformedEvent);
        }
        ···
        return handled;
    }
    ···
}

策略模式

策略模式定义了一系列的算法,并封装起来,提供针对同一类型问题的多种处理方式。

示例:

// 匀速
animation.setInterpolator(new LinearInterpolator());
// 加速
animation.setInterpolator(new AccelerateInterpolator());
···

BaseInterpolator.java

/**
 * An abstract class which is extended by default interpolators.
 */
abstract public class BaseInterpolator implements Interpolator {
    private @Config int mChangingConfiguration;
    /**
     * @hide
     */
    public @Config int getChangingConfiguration() {
        return mChangingConfiguration;
    }

    /**
     * @hide
     */
    void setChangingConfiguration(@Config int changingConfiguration) {
        mChangingConfiguration = changingConfiguration;
    }
}

LinearInterpolator.java

@HasNativeInterpolator
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
    ···
}

AccelerateInterpolator.java

@HasNativeInterpolator
public class AccelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
    ···
}

备忘录模式

在不破坏封闭的前提下,在对象之外保存保存对象的当前状态,并且在之后可以恢复到此状态。

示例:

Activity.java

// 保存状态
protected void onSaveInstanceState(Bundle outState) {
    // 存储当前窗口的视图树的状态
    outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());

    outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
    // 存储 Fragment 的状态
    Parcelable p = mFragments.saveAllState();
    if (p != null) {
        outState.putParcelable(FRAGMENTS_TAG, p);
    }
    if (mAutoFillResetNeeded) {
        outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
        getAutofillManager().onSaveInstanceState(outState);
    }
    // 调用 ActivityLifecycleCallbacks 的 onSaveInstanceState 进行存储状态
    getApplication().dispatchActivitySaveInstanceState(this, outState);
}

···
// onCreate 方法中恢复状态
protected void onCreate(@Nullable Bundle savedInstanceState) {
    ···
    if (savedInstanceState != null) {
        mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
        mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
                View.LAST_APP_AUTOFILL_ID);

        if (mAutoFillResetNeeded) {
            getAutofillManager().onCreate(savedInstanceState);
        }

        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.fragments : null);
    }
    mFragments.dispatchCreate();
    getApplication().dispatchActivityCreated(this, savedInstanceState);
    ···
    mRestoredFromBundle = savedInstanceState != null;
    mCalled = true;
}

ActivityThread.java

@Override
public void handleStartActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions) {
    final Activity activity = r.activity;
    ···
    // Start
    activity.performStart("handleStartActivity");
    r.setState(ON_START);
    ···
    // Restore instance state
    if (pendingActions.shouldRestoreInstanceState()) {
        if (r.isPersistable()) {
            if (r.state != null || r.persistentState != null) {
                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                        r.persistentState);
            }
        } else if (r.state != null) {
            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
        }
    }
    ···
}