zoukankan      html  css  js  c++  java
  • 常用设计模式

    何为模式

    经常使用的方案,公认为正确或相对正确

    何为设计模式

    一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结

    设计模式分类

    创建型模式

    •简单工厂模式
    •工厂方法模式
    •抽象工厂模式
    •建造者模式
    •原型模式

    结构型模式

    •外观模式
    •适配器模式
    •装饰模式
    •桥接模式
    •组合模式
    •享元模式

    行为型模式

    •观察者模式
    •状态模式
    •策略模式
    •职责链模式
    •命令模式
    •中介者模式
    •备忘录模式
    •迭代器模式

    设计模式详解

    简单工厂模式

    •定义:
    –根据输入或上下文选择创建哪种对象。
    •场景与功用:
    –将对象的创建与使用分离
    –集中处理共通创建步骤
    •样例代码:
    package simplefactory;
    class BaseView {
    }
    abstract class PicView extends BaseView {
    }
    abstract class VideoView extends BaseView {
    }
    class FeedPicView extends PicView {
    }
    class FeedVideoView extends VideoView {
    }
    class FeedFactory {
     public static BaseView createView(String type) {
     switch (type) {
     case "pic":
     return new FeedPicView();
     case "video":
     return new FeedVideoView();
     }
     return null;
     }
    }
    public class SimpleFactoryDemo {
     public static void main(String[] args) {
     BaseView picView = FeedFactory.createView("pic");
     BaseView videoView = FeedFactory.createView("video");
     System.out.println(picView.getClass().getSimpleName() + " "
     + videoView.getClass().getSimpleName());
     }
    }
     

    工厂方法模式

    •定义:
    –定义一个用于创建对象的接口,让子类决定实例化哪一个类。
    •场景与功用:
    –使一个类的实例化延迟到其子类
    –通过选择子工厂来生产对应的对象
    –将对象的创建与使用分离
    –抽象共通创建步骤
    •样例代码:
    package factorymethod;
    class BaseView {
    }
    abstract class PicView extends BaseView {
    }
    abstract class VideoView extends BaseView {
    }
    class FeedPicView extends PicView {
    }
    class FeedVideoView extends VideoView {
    }
    abstract class ViewFactory {
     abstract public BaseView createView();
    }
    class PicFactory extends ViewFactory {
     @Override
     public BaseView createView() {
     return new FeedPicView();
     }
    }
    class VideoFactory extends ViewFactory {
     @Override
     public BaseView createView() {
     return new FeedVideoView();
     }
    }
    public class FactoryMethodDemo {
     public static void main(String[] args) {
     BaseView picView = new PicFactory().createView();
     BaseView videoView = new VideoFactory().createView();
     System.out.println(picView.getClass().getSimpleName() + " "
     + videoView.getClass().getSimpleName());
     }
    }
     

    抽象工厂方法

    •定义:
    –提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
    •场景与功用:
    –两种以上产品系列
    –系列之间,产品的种数相同、抽象相同
    –将对象的创建与使用分离
    –抽象共通创建步骤
    •样例代码:
    package abstractfactory;
    class BaseView {
    }
    abstract class PicView extends BaseView {
    }
    abstract class VideoView extends BaseView {
    }
    class FeedPicView extends PicView {
    }
    class FeedVideoView extends VideoView {
    }
    class RecommendPicView extends PicView {
    }
    class RecommendVideoView extends VideoView {
    }
    abstract class ViewFactory {
     abstract PicView createPicView();
     abstract VideoView createVideoView();
    }
    class FeedViewFactory extends ViewFactory {
     @Override
     PicView createPicView() {
     return new FeedPicView();
     }
     @Override
     VideoView createVideoView() {
     return new FeedVideoView();
     }
    }
    class RecommendViewFactory extends ViewFactory {
     @Override
     PicView createPicView() {
     return new RecommendPicView();
     }
     @Override
     VideoView createVideoView() {
     return new RecommendVideoView();
     }
    }
    public class AbstractFactoryDemo {
     public static void main(String[] args) {
     // 在feed列表中
     displayViews(new FeedViewFactory());
     // 在recommend列表中
     displayViews(new RecommendViewFactory());
     }
     public static void displayViews(ViewFactory factory) {
     PicView picView = factory.createPicView();
     VideoView videoView = factory.createVideoView();
     System.out.println(picView.getClass().getSimpleName() + " "
     + videoView.getClass().getSimpleName());
     }
    }

    建造者模式

    •定义:
    –将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示
    –表示可以理解为实现方式
    •场景与功用
    –算法实现方式与对象构造过程无关
    –构造过程的抽象
    •样例代码:
    package builder;
    import android.net.Uri;
    public class BuilderDemo {
     public static void main(String[] args) {
     StringBuilder sb = new StringBuilder();
     sb.append("This ");
     sb.append("is ");
     sb.append("a ");
     sb.append("demo ");
     sb.append("for ");
     sb.append("Builder.");
     System.out.println(sb.toString());
     }
      
     public static void uriBuilderDemo(){
     Uri.Builder ub = new Uri.Builder();
     ub.scheme("http");
     ub.authority("api.sina.com:8080");
     ub.appendPath("list.json");
     ub.appendQueryParameter("wm", "0560");
     System.out.println(ub.build().toString());
     }
    }

    原型模式

    •定义:
    –用原型对象指定创建对象的种类,并且通过拷贝这些原型对象创建新的对象
    –又名“克隆模式”
    •场景与功用:
    –需要创建一个初始化代价较大的对象
    –类自己决定哪些字段深拷贝哪些浅拷贝
    •样例代码:
    package prototype;
    import java.util.ArrayList;
    class NewsItem implements Cloneable {
     private String id = "";
     private String title = "";
     private String source = "";
     private String link = "";
     private int comment;
     private String category = "";
     private ArrayList<String> pv = new ArrayList<String>();
     private ArrayList<String> monitor = new ArrayList<String>();;
     @Override
     public NewsItem clone() throws CloneNotSupportedException {
     NewsItem obj = (NewsItem) super.clone();
     obj.pv = (ArrayList<String>) pv.clone();
     obj.monitor = (ArrayList<String>) monitor.clone();
     return obj;
     }
    }
    class VideoNewsItem implements Cloneable {
     private VideoInfo video_info = new VideoInfo();
     @Override
     public VideoNewsItem clone() throws CloneNotSupportedException {
     VideoNewsItem item = (VideoNewsItem) super.clone();
     item.video_info = video_info.clone();
     return item;
     }
    }
    class VideoInfo implements Cloneable {
     private String pic = "";
     private String url = "";
     private String runtime = "";
     private String playnumber = "";
     private String type = "";
     @Override
     public VideoInfo clone() throws CloneNotSupportedException {
     return (VideoInfo) super.clone();
     }
    }
    public class PrototypeDemo {
     public static void main(String[] args) throws CloneNotSupportedException {
     VideoNewsItem item1 = new VideoNewsItem();
     VideoNewsItem item2 = item1.clone();
      
     System.out.println(item1==item2);
     }
    }

    外观模式

    •定义:
    –为子系统中的一组接口提供一个一致的界面
    •场景与功用
    –调用旧系统或第三方系统
    –调用接口繁杂的系统
    –将常用子接口组合封装成为简单的新接口
     

    适配器模式

    •定义:
    –将一个类的接口转换成使用者希望的接口形式
    •分类:
    –类适配器:继承适配
    –对象适配器:委托适配
    •场景:
    –两个系统接口不兼容时
    –双方系统都不易或不能修改时
     

    装饰模式

    •定义:
    –动态地给一个对象添加一些额外的职责。
    •场景与功用:
    –将类的核心职能和额外的装饰功能分离,并且可以随意重用或选用装饰逻辑。
    •样例代码:
    package decorator;
    interface Number {
     public String getNumber();
    }
    class PhoneNumber implements Number {
     private String number;
     public PhoneNumber(String number) {
     this.number = number;
     }
     @Override
     public String getNumber() {
     return number;
     }
    }
    class CityDecorator implements Number {
     private Number number;
     public CityDecorator(Number number) {
     this.number = number;
     }
     @Override
     public String getNumber() {
     return "010-" + number.getNumber();
     }
    }
    class NationDecorator implements Number {
     private Number number;
     public NationDecorator(Number number) {
     this.number = number;
     }
     @Override
     public String getNumber() {
     return "+86-" + number.getNumber();
     }
    }
    class AsteriskDecorator implements Number {
     private Number number;
     public AsteriskDecorator(Number number) {
     this.number = number;
     }
     @Override
     public String getNumber() {
     return "***" + number.getNumber() + "***";
     }
    }
    public class DecoratorDemo {
     public static void main(String[] args) {
     Number number = null;
      
     ////////////////////////////////
     number = new PhoneNumber("82675588");
     number = new CityDecorator(number);
     number = new NationDecorator(number);
     number = new AsteriskDecorator(number);
     System.out.println(number.getNumber());
      
     ////////////////////////////////
     number = new PhoneNumber("82675588");
     number = new CityDecorator(number);
     number = new AsteriskDecorator(number);
     System.out.println(number.getNumber());
      
     ////////////////////////////////
     number = new PhoneNumber("82675588");
     number = new AsteriskDecorator(number);
     number = new CityDecorator(number);
     System.out.println(number.getNumber());
     }
    }

    桥接模式

    •定义:
    –将抽象部分与它的实现部分分离,使它们都可以独立地变化。
    •组合/聚合复用原则:
    –尽量使用组合/聚合,而不是使用类继承
    •场景与功用
    –一个抽象出现了多个维度的变化
    –控制类爆炸,以减弱维度间的耦合
    •样例代码:
    不使用桥接
     package bridge;
    import com.sina.news.R;
    import com.sina.news.bean.NewsItem;
    class PicNewsItem extends NewsItem {
     //category = "cms";
     public int getIcon() {
     return -1;
     }
    }
    class VideoNewsItem extends NewsItem {
     //category = "video";
     public int getIcon() {
     return R.drawable.ic_list_item_video_normal;
     }
    }
    class RecommendPicNewsItem extends NewsItem {
     //category = "cms";
     public int getIcon() {
     return -1;
     }
    }
    class RecommendVideoNewsItem extends NewsItem {
     //category = "video";
     public int getIcon() {
     return R.drawable.ic_list_item_video_normal;
     }
    }
    public class NonBridgeDemo {
     public static void main(String[] args) {
     }
    }
    使用桥接
    package bridge;
    import com.sina.news.R;
    import com.sina.news.bean.NewsItem;
    abstract class Category {
     abstract public int getIcon();
    }
    class PicCategory extends Category {
     @Override
     public int getIcon() {
     return -1;
     }
    }
    class VideoCategory extends Category {
     @Override
     public int getIcon() {
     return R.drawable.ic_list_item_video_normal;
     }
    }
    class NormalNewsItem extends NewsItem {
     // Category category = new PicCategory();
     Category category = new VideoCategory();
    }
    class RecommendNewsItem extends NewsItem {
     Category category = new PicCategory();
     // Category category = new VideoCategory();
    }
    public class BridgeDemo {
     public static void main(String[] args) {
     }
    }

    组合模式

    •定义:
    –将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
    •场景与功用
    –需要树形数据结构时
    –树枝与树叶没有区别,使用时可以一致对待
    •样例代码:
    package composite;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    class View {
    }
    class ViewGroup extends View {
     private List<View> children = new ArrayList<View>();
     public void add(View v) {
     children.add(v);
     }
     public Collection<View> getChildren() {
     return new ArrayList<View>(children);
     }
    }
    public class CompositeDemo {
     public static void main(String[] args) {
     ViewGroup vg1 = new ViewGroup();
     ViewGroup vg2 = new ViewGroup();
     ViewGroup vg3 = new ViewGroup();
     ViewGroup vg4 = new ViewGroup();
     ViewGroup vg5 = new ViewGroup();
     // @formatter:off
     /* vg1
     * |--vg2
     * | |--vg4
     * | |--vg5
     * |
     * |--vg3
     */
     // @formatter:on
     vg1.add(vg2);
     vg1.add(vg3);
     vg2.add(vg4);
     vg2.add(vg5);
     }
    }

    享元模式

    •定义:
    –运用共享技术有效地支持大量细粒度的对象。
    •场景与功用:
    –同一时段使用不多,而总体数量庞大的可共享对象
    •可共享对象:
    –初始化代价较大(内部状态)
    –可变属性较少(外部状态)
     

    观察者模式

    •定义:
    –定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
    •场景与功用
    –对象联动,一个对象改变同时需要更新其他对象
    –对象定义时不知道有多少对象有待改变
    •样例代码:
    package observer;
    import java.util.Observable;
    import java.util.Observer;
    public class ObserverDemo {
     public static int SHARE_TYPE_NORMAL = 1;
     public static int SHARE_TYPE_EXCLUSIVE = 2;
     private CheckBox mCheckboxEnable = new CheckBox();
     private SelectBox mSelectShareType = new SelectBox();
     private TextBox mTextShareName = new TextBox();
     private CheckBox mCheckboxReadOnly = new CheckBox();
     private Label mLabelDescrpiton = new Label();
     abstract class View extends Observable implements Observer {
     private boolean disabled = false;
     public void setDisabled(boolean disabled) {
     this.disabled = disabled;
     }
     public boolean isDisabled() {
     return this.disabled;
     }
     }
     class SelectBox extends View {
     private int selected;
     public void setSelect(int index) {
     this.selected = index;
     setChanged();
     notifyObservers();
     }
     public int getSelect() {
     return selected;
     }
     @Override
     public void update(Observable observable, Object data) {
     if (mCheckboxEnable.isChecked()) {
     this.setDisabled(true);
     } else {
     this.setDisabled(false);
     }
     }
     }
     class TextBox extends View {
     private String text;
     public void setText(String text) {
     this.text = text;
     setChanged();
     notifyObservers();
     }
     public String getText() {
     return text;
     }
     @Override
     public void update(Observable observable, Object data) {
     if (mCheckboxEnable.isChecked()) {
     this.setDisabled(true);
     } else {
     this.setDisabled(false);
     }
     }
     }
     class CheckBox extends View {
     private boolean checked;
     public void setChecked(boolean checked) {
     this.checked = checked;
     setChanged();
     notifyObservers();
     }
     public boolean isChecked() {
     return checked;
     }
     @Override
     public void update(Observable observable, Object data) {
     if (this == mCheckboxEnable) {
     return;
     }
     if (this == mCheckboxReadOnly) {
     if (mSelectShareType.getSelect() == SHARE_TYPE_NORMAL) {
     this.setDisabled(false);
     } else if (mSelectShareType.getSelect() == SHARE_TYPE_EXCLUSIVE) {
     this.setChecked(true);
     this.setDisabled(true);
     }
     }
     }
     }
     class Label extends View {
     private String text;
     @Override
     public void update(Observable observable, Object data) {
     if (!mCheckboxEnable.isChecked()) {
     this.text = "Disabled";
     return;
     }
     this.text = mSelectShareType.toString() + mTextShareName.toString()
     + mCheckboxReadOnly.toString();
     }
     public String getText() {
     return text;
     }
     }
     public ObserverDemo() {
     mCheckboxEnable.addObserver(mSelectShareType);
     mCheckboxEnable.addObserver(mTextShareName);
     mCheckboxEnable.addObserver(mCheckboxReadOnly);
     mCheckboxEnable.addObserver(mLabelDescrpiton);
     mSelectShareType.addObserver(mCheckboxReadOnly);
     mSelectShareType.addObserver(mLabelDescrpiton);
     mTextShareName.addObserver(mCheckboxReadOnly);
     mTextShareName.addObserver(mLabelDescrpiton);
     }
     public static void main(String[] args) {
     }
    }

    状态模式

    •定义:
    –当一个对象的内在状态改变时,允许改变其行为,这个对象看起来是改变了其类。
    •场景与功用
    –控制一个对象状态转换的条件过于复杂
    –把状态转换逻辑封装到一系列类中,将逻辑局部化
    –降低状态之间的耦合
    •样例代码:
    package state;
     
    class Activity {
     protected State state;
     abstract class State {
     abstract void next();
     }
     class BootImageState extends State {
     @Override
     void next() {
     if (isFirstRun()) {
     state = new FinishState();
     } else {
     showBootImage();
     state = new AdState();
     }
     }
     }
     class AdState extends State {
     @Override
     void next() {
     if (isAdReady()) {
     showAd();
     state = new FinishState();
     } else {
     state = new CoverStoryState();
     }
     }
     }
     class CoverStoryState extends State {
     @Override
     void next() {
     if (isCoverStoryReady()) {
     showCoverStory();
     }
     state = new FinishState();
     }
     }
     class FinishState extends State {
     @Override
     void next() {
     state = null;
     enterMainActivity();
     }
     }
     private boolean isFirstRun() {
     return false;
     }
      
     private void showBootImage(){}
     private boolean isAdReady() {
     return true;
     }
     private void showAd() {
     }
     private boolean isCoverStoryReady() {
     return true;
     }
     private void showCoverStory() {
     }
     public void enterMainActivity() {
     // MainActivity.start();
     // this.finish();
     }
     public void execute() {
     while (state != null) {
     state.next();
     }
     }
    }
    public class StateDemo {
     public static void main(String[] args) {
     Activity powerOn = new Activity();
     powerOn.execute();
     }
    }

    策略模式

    •定义:
    –定义算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法使用者可以不改变实现的情况下灵活切换算法。
    •场景与功用:
    –减少了算法使用者与算法之间的耦合
    •扩展:
    –可以封装任何类型的变化
    •样例代码:
    package strategy;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    class Person {
     private final int id;
     private final String name;
     public Person(int id, String name) {
     this.id = id;
     this.name = name;
     }
     public int getId() {
     return id;
     }
     public String getName() {
     return name;
     }
     public String toString() {
     return "{" + id + ", " + name + "}";
     }
    }
    class PersonComparatorById implements Comparator<Person> {
     @Override
     public int compare(Person p0, Person p1) {
     return p0.getId() - p1.getId();
     }
    }
    class PersonComparatorByName implements Comparator<Person> {
     @Override
     public int compare(Person p0, Person p1) {
     return p0.getName().compareTo(p1.getName());
     }
    }
    public class StrategyDemo {
     public static void main(String[] args) {
     List<Person> persons = Arrays.asList(new Person(80, "Mick"), new Person(90, "Racheal"),
     new Person(15, "Jack"), new Person(21, "Don"), new Person(93, "Wislee"),
     new Person(65, "Lucy"), new Person(70, "Nazu"));
      
     Collections.sort(persons, new PersonComparatorById());
     System.out.println("Sorted by ID : " + persons);
     Collections.sort(persons, new PersonComparatorByName());
     System.out.println("Sorted by Name : " + persons);
     }
    }

    职责链模式

    •定义:
    –将请求的可能接收者组织成链,让请求延这条链传递直到有一个接收者处理它为止。
    •相关概念:
    –AOP:面向切片编程
    •场景与功用
    –请求处理逻辑经常变化的场合
    –各处理逻辑之间解耦合
    •样例代码:
    package responsibilitychain;
    import android.content.Intent;
    import android.net.ConnectivityManager;
    abstract class IntentHandler {
     private final IntentHandler nextHandler;
     public IntentHandler(IntentHandler nextHandler) {
     this.nextHandler = nextHandler;
     }
     abstract public boolean process(Intent intent);
     public void handle(Intent intent) {
     if (process(intent) && nextHandler != null) {
     nextHandler.process(intent);
     }
     }
    }
    class ActionValidateHandler extends IntentHandler {
     public ActionValidateHandler(IntentHandler nextHandler) {
     super(nextHandler);
     }
     @Override
     public boolean process(Intent intent) {
     if (intent.getAction() == null) {
     return false;
     }
     return true;
     }
    }
    class NetworkChangeHandler extends IntentHandler {
     public NetworkChangeHandler(IntentHandler nextHandler) {
     super(nextHandler);
     }
     @Override
     public boolean process(Intent intent) {
     if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
     // 处理网络变化逻辑
     }
     return true;
     }
    }
    class SaveIntentHandler extends IntentHandler {
     public SaveIntentHandler(IntentHandler nextHandler) {
     super(nextHandler);
     }
     @Override
     public boolean process(Intent intent) {
     save((Intent) intent.clone());
     return true;
     }
     private void save(Intent intent) {
     // 保存intent
     }
    }
    class Receiver {
     public void receive(Intent intent) {
     IntentHandler saveHandler = new SaveIntentHandler(null);
     IntentHandler netHandler = new NetworkChangeHandler(saveHandler);
     IntentHandler actionHandler = new ActionValidateHandler(netHandler);
     actionHandler.handle(intent);
     }
    }
    public class ChainOfResponsibilityDemo {
     public static void main(String[] args) {
     new Receiver().receive(new Intent());
     }
    }

    命令模式

    •定义:
    –将一个请求(命令)封装成一个对象,从而可用不同的请求对客户端进行参数化。
    •场景与功用
    –多方请求容易冲突的场合
    –请求可以排队,记录日志,重做以及撤销
     

    中介者模式

    •定义:
    –用一个中介对象来封装一系列对象的交互。
    •场景与功用:
    –各对象不需要显式地相互引用,独立变化互不干涉,降低耦合
     

    备忘录模式

    •定义:
    –在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。
    •场景与功用
    –功能比较复杂,但需要维护或记录属性历史的类
    –需要保存的属性只是部分属性,用原型模式的代价过大时
     

    迭代器模式

    •定义:
    –提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
    •场景与功用
    –自定义聚合数据
    –封装聚合数据的内部实现,与使用者的数据结构解耦合
    •样例代码:
    package iterator;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.List;
    import com.sina.news.bean.NewsItem;
    class NewsItemList implements Iterable<NewsItem> {
     private List<NewsItem> items = null;
     public NewsItemList() {
     items = new ArrayList<NewsItem>();
     }
     public void add(NewsItem item) {
     items.add(item);
     }
     public void addAll(Collection<NewsItem> c) {
     items.addAll(c);
     }
     @Override
     public Iterator<NewsItem> iterator() {
     return new Iterator<NewsItem>() {
     private int index = -1;
     @Override
     public boolean hasNext() {
     return index + 1 < items.size();
     }
     @Override
     public NewsItem next() {
     return items.get(++index);
     }
     @Override
     public void remove() {
     items.remove(index);
     }
     };
     }
    }
    public class IteratorDemo {
     public static void main(String[] args) {
     NewsItemList itemList = new NewsItemList();
     itemList.add(new NewsItem());
     itemList.add(new NewsItem());
     itemList.add(new NewsItem());
     itemList.add(new NewsItem());
     itemList.add(new NewsItem());
     Iterator<NewsItem> it = itemList.iterator();
     while (it.hasNext()) {
     System.out.println(it.next().hashCode());
     }
     // for(NewsItem item : itemList){
     // System.out.println(item.hashCode());
     // }
     }
    }
  • 相关阅读:
    react学习笔记一
    获取客户端时间差
    ts
    Linux学习笔记
    vuex 基本使用
    SQL入门
    ios 中倒计时计算,时间戳为NaN
    git归纳总结
    JS原型对象
    vue笔记
  • 原文地址:https://www.cnblogs.com/xinmengwuheng/p/7605443.html
Copyright © 2011-2022 走看看