美文网首页
23种设计模式快速理解(android)

23种设计模式快速理解(android)

作者: 朱_c713 | 来源:发表于2020-07-19 17:06 被阅读0次

更新时间2020/09/10:添加组合模式的优秀案例:

一个模式一个代码案例:总结一下。

1. 策略模式:

使用技巧:

  1. 他其实是一种多对一的关系,一个实体(类,页面),可以呈现不同的形态。
  2. 个人的经验,一定要设置默认策略
  3. 策略,建议考虑33原则,第一,有大于等于三种不同的形态,第二,有三种不同的行为,这样才能使用策略模式。
    比如: 我有一个页面,三个地方跳转进来,要展示三种不同的view样式。同时里面有一个按钮,跳转三个不同的url,同时我还有一个请求,需要传递三种不同的参数。此时可以考虑。这种情况越多,越值得考虑。

能使用双向绑定化解的用双向绑定处理,更加规范清晰些。

  1. 注意一点,策略模式其实还牵涉到一个动态改变的问题,如果模型又动态改变的意思,那么将更加合适。

策略模式的主要优点如下。
多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句(例如swtich case 或者连续的if else)。
策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类里面,从而避免重复的代码。
策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
策略模式提供了对开闭原则的完美支持,可以在不修改原代码的情况下,灵活增加新算法。
策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

其主要缺点如下。
客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
策略模式造成很多的策略类。

2. 组合模式:

我之前写的应该不能叫做组合模式,顶多叫做组合。


组合模式的最大特点是可以取代父类。取代继承,比如本例中:operate2方法,可以是多个类的公共方法,也许这些方法,起初应该设计到父类里的,这里可以看到,他被以组合的形式添加到子类中。

3. 代理/委托模式

和策略模式相比,没有使用多态。直接使用代理类做事情。

package proxy;
public class ProxyTest
{
    public static void main(String[] args)
    {
        Proxy proxy=new Proxy();
        proxy.Request();
    }
}

//抽象主题
interface Subject
{
    void sellBaiFen();
}
//真实主题
class RealSubject implements Subject
{
    public void sellBaiFen()
    {
        System.out.println("卖白粉");
    }
}
//代理
class Proxy implements Subject
{
    private RealSubject realSubject;
    public void sellBaiFen()
    {
        if (realSubject==null)
        {
            realSubject=new RealSubject();
        }
        preRequest();
        realSubject.sellBaiFen();
        postRequest();
    }
    public void preRequest()
    {
        System.out.println("锡纸包裹,组成药丸的样子");
    }
    public void postRequest()
    {
        System.out.println("24小时售后");
    }
}

4 . 观察者模式:

观察模式,这里使用原生api实现。包含三个类,天气数据类,天气展板类,主类(调用显示结果)

public class WeatherData extends Observable {
   private float temperature;
   private float pressure;

   public WeatherData() {
   }

   public void setWeatherData(float temperature, float pressure) {
       this.temperature = temperature;
       this.pressure = pressure;
       dataChanged();
   }

   private void dataChanged() {
       setChanged();
       notifyObservers();
   }

   public float getPressure() {
       return pressure;
   }


   public float getTemperature() {
       return temperature;
   }
}

天气展板类

public class WeatherDisplay implements Observer {
   Observable observable;
   private float temperature;
   private float pressure;

   public WeatherDisplay(Observable observable) {
       this.observable = observable;
       observable.addObserver(this);
   }

   @Override
   public void update(Observable observable, Object o) {
       if (observable instanceof WeatherData){
           WeatherData weatherData= (WeatherData) observable;
           this.temperature=weatherData.getTemperature();
           this.pressure=weatherData.getPressure();
           display();
       }

   }

   private void display() {
       System.out.println("温度:"+temperature+"气压:"+pressure);
   }
}

调用一下,看效果:

 WeatherData weatherData=new WeatherData();
       weatherData.setWeatherData(38f,1000f);
       WeatherDisplay weatherDisplay=new WeatherDisplay(weatherData);
       weatherDisplay.update(weatherData,this);
       weatherData.setWeatherData(36f,1100f);

5. 装饰器模式:

先把需要的类贴在这里:
一共有四个类:1. 接口类,用来约束装饰的行为。2 ,具体实现类,实现接口所指明的行为

  1. 待装饰的类,使用具体装饰中的行为 4. 装饰类
    现在将具体的几个类代码贴出来:
1>接口类
public interface Component {
     void operate();
}

2>实现类
public class ContrateComponent implements Component {
   public ContrateComponent() {
       Log.d("ccccccccccccccccccc", "创建具体构建实体");
   }

   @Override
   public void operate() {
       Log.d("ccccccccccccccccccc", "调用具体构建方法");
   }
}
3>待装饰类

特点:类将实现类作为构造的参数传递进来。

public class NeedDecorator implements Component {
   Component component;

   public NeedDecorator(Component component) {
       this.component = component;
   }

   @Override
   public void operate() {
       component.operate();

   }
}

4>装饰类
public class Role extends NeedDecorator {


   public Role(Component component) {
       super(component);
   }

   @Override
   public void operate() {
       super.operate();
       addFunction();
   }

   public void addFunction(){
       Log.d("cccccccccccccccccccc","为具体角色的增加额外的方法");
   }
}

6. 外观模式:

意图:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口。

何时使用: 1、客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。 2、定义系统的入口。

如何解决:客户端不与系统耦合,外观类与系统耦合。

关键代码:在客户端和复杂系统之间再加一层,这一层将调用顺序、依赖关系等处理好。

应用实例: 1、去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。 2、JAVA 的三层开发模式。

优点: 1、减少系统相互依赖。 2、提高灵活性。 3、提高了安全性。

缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。

使用场景: 1、为复杂的模块或子系统提供外界访问的模块。 2、子系统相对独立。 3、预防低水平人员带来的风险。

注意事项:在层次化结构中,可以使用外观模式定义系统中每一层的入口。
外观模式也是一种简单而又常用的模式。代码如下:
1>首先创建接口(模型的主要功能):

public interface Shape  {
   void draw();
}

2>创建三个实体,实现模型的功能

public class Square implements Shape {
   @Override
   public void draw() {
       LogUtils.d("画square类型。。。。。");
   }
}

3>创建一个外观类,里面拥有三个实体,并具有用三个方法,来实现三个实体的各自的draw功能。

public class ShapeMaker {
   private Shape circle;
   private Shape rectangle;
   private Shape square;

   public ShapeMaker() {
       circle = new Circle();
       rectangle = new Rectangle();
       square = new Square();
   }

   public void drawCircle(){
       circle.draw();
   }
   public void drawRectangle(){
       rectangle.draw();
   }
   public void drawSquare(){
       square.draw();
   }
}

6. 原型模式:

主要解决:在运行期建立和删除原型。

public abstract class Shape implements Cloneable {
   private String id;
   protected String type;

   public String getId() {
       return id;
   }

   public void setId(String id) {
       this.id = id;
   }

   public String getType() {
       return type;
   }

   public void setType(String type) {
       this.type = type;
   }
   abstract void draw();

   public Object clone() {
       Object clone = null;
       try {
           clone = super.clone();

       } catch (Exception e) {
           e.printStackTrace();
       }
       return clone;
   }
}

三个一摸一样的实现类

public class Square extends Shape {
   public Square() {
       type="square";
   }

   @Override
   void draw() {
       LogUtils.d("Sqarue draw 内部 ");
   }
}

public class Rectangle extends Shape {
   public Rectangle() {
       type="Rectangle";
   }

   @Override
   void draw() {
       LogUtils.d("rrrrrrrrrrrrrrrr矩形内部");
   }
}

public class Circle extends Shape {
   public Circle() {
       type="Circle";
   }

   @Override
   void draw() {
       LogUtils.d("circle  内部方法。");
   }
}
public class ShapeCache {
   private static Hashtable<String, Shape> shapeMap
           = new Hashtable<String, Shape>();

   public static Shape getShape(String shapeId) {
       Shape cachedShape = shapeMap.get(shapeId);
       return (Shape) cachedShape.clone();
   }

   // 对每种形状都运行数据库查询,并创建该形状
   // shapeMap.put(shapeKey, shape);
   // 例如,我们要添加三种形状
   public static void loadCache() {
       Circle circle = new Circle();
       circle.setId("1");
       shapeMap.put(circle.getId(),circle);

       Square square = new Square();
       square.setId("2");
       shapeMap.put(square.getId(),square);

       Rectangle rectangle = new Rectangle();
       rectangle.setId("3");
       shapeMap.put(rectangle.getId(),rectangle);
   }
}

在main类里运行一下内容:

  ShapeCache.loadCache();

       Shape clonedShape = (Shape) ShapeCache.getShape("1");
       LogUtils.d("Shape : " + clonedShape.getType());

       Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
       LogUtils.d("Shape : " + clonedShape2.getType());

       Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
       LogUtils.d("Shape : " + clonedShape3.getType());

7. 适配器模式:

1>首先定义一个接口,既具备播放vlc的功能,又具有播放MP4的功能

public interface AdvancedMediaPlayer {
   void playVlc(String fileName);

   void playMp4(String fileName);
}

定义两个类,各去实现其中一个功能:

public class Mp4Player implements AdvancedMediaPlayer {
   @Override
   public void playVlc(String fileName) {

   }

   @Override
   public void playMp4(String fileName) {
       System.out.println("Playing mp4 file. Name: "+ fileName);

   }
}

vlcplayer功能

public class VlcPlayer implements AdvancedMediaPlayer {
   @Override
   public void playVlc(String fileName) {
       System.out.println("Playing vlc file. Name: "+ fileName);
   }

   @Override
   public void playMp4(String fileName) {

   }
}

定义播放接口:

public interface MediaPlayer {
   void play(String audioType, String fileName);
}

紧接着,真实的播放类实现这个接口,适配器也实现这个接口。
适配器适配这个播放接口,为了实现播放vlc和MP4,播放类实现此接口,因为本身需要这个功能,不多解释。

public class MediaAdapter implements MediaPlayer {
   AdvancedMediaPlayer advancedMusicPlayer;

   public MediaAdapter(String audioType){
       if(audioType.equalsIgnoreCase("vlc") ){
           advancedMusicPlayer = new VlcPlayer();
       } else if (audioType.equalsIgnoreCase("mp4")){
           advancedMusicPlayer = new Mp4Player();
       }
   }

   @Override
   public void play(String audioType, String fileName) {
       if(audioType.equalsIgnoreCase("vlc")){
           advancedMusicPlayer.playVlc(fileName);
       }else if(audioType.equalsIgnoreCase("mp4")){
           advancedMusicPlayer.playMp4(fileName);
       }
   }
}

播放类:播放类中传入adapter来播放那些指定的功能。

public class AudioPlayer implements MediaPlayer {

   MediaAdapter mediaAdapter;

   @Override
   public void play(String audioType, String fileName) {

       //播放 mp3 音乐文件的内置支持
       if (audioType.equalsIgnoreCase("mp3")) {
           System.out.println("Playing mp3 file. Name: " + fileName);
       } else if (audioType.equalsIgnoreCase("vlc")
               || audioType.equalsIgnoreCase("mp4")) {
           //mediaAdapter 提供了播放其他文件格式的支持
           mediaAdapter = new MediaAdapter(audioType);
           mediaAdapter.play(audioType, fileName);
       } else {
           System.out.println("Invalid media. " +
                   audioType + " format not supported");
       }
   }


}

在主类main方法中调用一下此功能。

 AudioPlayer audioPlayer = new AudioPlayer();
       audioPlayer.play("mp3", "beyond the horizon.mp3");
       audioPlayer.play("mp4", "alone.mp4");
       audioPlayer.play("vlc", "far far away.vlc");
       audioPlayer.play("avi", "mind me.avi");

盘点一下,一共是两个接口类,一个是通用的播放接口,一个是显示其中具体格式的播放接口。
这个接口内部,又两种具体播放功能,播放mp4和vlc。

8. 享元模式:

创建一个shape:

public interface Shape {
  void draw();
}

创建一个圆形,实现shape接口。

public class Circle implements Shape {
   private String color;
   private int x;
   private int y;
   private int radius;

   public Circle(String color) {
       this.color = color;
   }

   public void setX(int x) {
       this.x = x;
   }

   public void setY(int y) {
       this.y = y;
   }

   public void setRadius(int radius) {
       this.radius = radius;
   }

   @Override
   public void draw() {
       System.out.println("Circle: Draw() [Color : " + color
               + ", x : " + x + ", y :" + y + ", radius :" + radius);
   }
}

3>. 在运行类里面做工作:

 private static final String colors[] =
           { "Red", "Green", "Blue", "White", "Black" };

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       binding = DataBindingUtil.setContentView(this, R.layout.activity_main);        
       for(int i=0; i < 20; ++i) {
           Circle circle =
                   (Circle)ShapeFactory.getCircle(getRandomColor());
           circle.setX(getRandomX());
           circle.setY(getRandomY());
           circle.setRadius(100);
           circle.draw();
       }
   }

   private static String getRandomColor() {
       return colors[(int)(Math.random()*colors.length)];
   }
   private static int getRandomX() {
       return (int)(Math.random()*100 );
   }
   private static int getRandomY() {
       return (int)(Math.random()*100);
   }

运行类的时候会发现,创建对象的次数只有5次,和数组的长度相同。

意图:运用共享技术有效地支持大量细粒度的对象。

主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。

何时使用: 1、系统中有大量对象。 2、这些对象消耗大量内存。 3、这些对象的状态大部分可以外部化。 4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。 5、系统不依赖于这些对象身份,这些对象是不可分辨的。

如何解决:用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象。

关键代码:用 HashMap 存储这些对象。

应用实例: 1、JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。 2、数据库的数据池。

优点:大大减少对象的创建,降低系统的内存,使效率提高。

缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。

使用场景: 1、系统有大量相似对象。 2、需要缓冲池的场景。

注意事项: 1、注意划分外部状态和内部状态,否则可能会引起线程安全问题。 2、这些类必须有一个工厂对象加以控制。

9. 责任链模式:

责任链,链路上的类:

public abstract class Handler {
   private Handler next;

   public Handler getNext() {
       return next;
   }

   public void setNext(Handler next) {
       this.next = next;
   }

   public abstract void handlerRequest(String request);
}

链路 上的第一关:

public class ConcreteHandler1 extends Handler {
   @Override
   public void handlerRequest(String request) {
       if (request.equals("one")){
           System.out.println("具体处理者一负责处理该请求");
       }else {
           if (getNext()!=null){
               getNext().handlerRequest(request);
           }else {
               System.out.println("没有人处理该请求");
           }
       }

   }
}

链路上的第二关:

public class ConcreteHandler2 extends Handler {
   @Override
   public void handlerRequest(String request) {
       if (request.equals("two")){
           System.out.println("具体处理者二负责处理该请求");
       }else {
           if (getNext()!=null){
               getNext().handlerRequest(request);
           }else {
               System.out.println("没有人处理该请求");
           }
       }

   }
}

main方法中运行:

 //组装责任链
       Handler handler1=new ConcreteHandler1();
       Handler handler2=new ConcreteHandler2();
       handler1.setNext(handler2);
       //提交请求
       handler1.handlerRequest("two");

10. 命令模式:

public interface Order {
   void execute();
}

买卖股票的类:

public class BuyStock implements Order {
   private Stock abcStock;

   public BuyStock(Stock abcStock) {
       this.abcStock = abcStock;
   }

   @Override
   public void execute() {
       abcStock.buy();

   }
}

卖股票的类:

public class SellStock implements Order {
   public Stock abcStock;

   public SellStock(Stock abcStock) {
       this.abcStock = abcStock;
   }

   @Override
   public void execute() {
       abcStock.sell();

   }
}

股票类:

public class Stock {
   private String name = "ABC";
   private int quantity = 10;
   public void buy(){
       System.out.println("name+"+name+"quantity"+quantity+"buy");
   }
   public void sell(){
       System.out.println("name+"+name+"quantity"+quantity+"sell");
   }
}

股票经理人类:

public class Broker {
   private List<Order> orderList=new ArrayList<>();
   public void takeOrder(Order order){
       orderList.add(order);
   }
   public void placeOrders(){
       for (Order order : orderList) {
           order.execute();
       }
       orderList.clear();
   }
}

main类中执行的具体方法:

       Stock abcStock = new Stock();

       BuyStock buyStockOrder = new BuyStock(abcStock);
       SellStock sellStockOrder = new SellStock(abcStock);

       Broker broker = new Broker();
       broker.takeOrder(buyStockOrder);
       broker.takeOrder(sellStockOrder);
       broker.placeOrders();

11. 模板方法模式:

模板方法模式也是一种简单,常用的模式。

abstract class AbstractClass {
   //模板方法
   public void TemplateMethod(){
       SpecificMethod();
       abstractMethod1();
       abstractMethod2();
   }
   //具体方法
   public void SpecificMethod(){
       System.out.println("抽象类中的具体方法被调用");

   }
   //抽象方法1
   public abstract void abstractMethod1();
   //抽象方法2
   public abstract  void abstractMethod2();

}

具体实现

public class ConcreteClass extends  AbstractClass {
   @Override
   public void abstractMethod1() {
       System.out.println("抽象方法1被调用");
   }

   @Override
   public void abstractMethod2() {
       System.out.println("抽象方法2被调用");
   }

}

main类中的方法:

AbstractClass tm=new ConcreteClass();
       tm.TemplateMethod();

可以看到:
1>它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
2>它在父类中提取了公共的部分代码,便于代码复用。
3>部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。

这样的例子在生活中还有很多,例如,一个人每天会起床、吃饭、做事、睡觉等,其中“做事”的内容每天可能不同。我们把这些规定了流程或格式的实例定义成模板,允许使用者根据自己的需求去更新它,例如,简历模板、论文模板、Word 中模板文件等。

和一般的写法有什么不同:
1>具体实现在子类中进行,面向功能的类不臃肿。这其实是依赖倒置。面向接口编程。
2> 父类中固定了一些方法,又开放了一些抽象的方法,让子类实现。这其实也符合某种现实世界,比如有些业务,对所有的子类都一样,那么在父类中实现。那些不具有一般性的功能,开放给子类,让子类实现。

12. 单例模式:

简单点说,就是一个应用程序中,某个类的实例对象只有一个,你没有办法去new,因为构造器是被private修饰的,一般通过getInstance()的方法来获取它们的实例。

getInstance()的返回值是一个对象的引用,并不是一个新的实例,所以不要错误的理解成多个对象。单例模式实现起来也很容易,直接看demo吧

public class Singleton {

 private static Singleton singleton;

 private Singleton() {
 }

 public static Singleton getInstance() {
  if (singleton == null) {
   singleton = new Singleton();
  }
  return singleton;
 }
}

按照我的习惯,我恨不得写满注释,怕你们看不懂,但是这个代码实在太简单了,所以我没写任何注释,如果这几行代码你都看不明白的话,那你可以洗洗睡了,等你睡醒了再来看我的博客说不定能看懂。

上面的是最基本的写法,也叫懒汉写法(线程不安全)下面我再公布几种单例模式的写法:

懒汉式写法(线程安全)

public class Singleton {
  private static Singleton instance;
  private Singleton (){}
  public static synchronized Singleton getInstance() {
  if (instance == null) {
      instance = new Singleton();
  }
  return instance;
  }
}

饿汉式写法

单例模式很多代理代码了,重点是理解他的特点和场景。

13. 建造者模式:

此模式也比较常见,至少在安卓的源码,以及一些开源项目种十分多见。

public abstract class Builder {
    //创建产品对象
    protected Product product=new Product();
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract void buildPartC();
    //返回产品对象
    public Product getResult()
    {
        return product;
    }
}

实体的类

public class ConcreteBuilder extends Builder {
    @Override
    public void buildPartA() {
        product.setPartA("建造 PartA");
    }

    @Override
    public void buildPartB() {
        product.setPartB("建造 PartB");

    }

    @Override
    public void buildPartC() {
        product.setPartC("建造 PartC");
    }
}
public class Director {
    private Builder builder;
    public Director(Builder builder)
    {
        this.builder=builder;
    }
    //产品构建与组装方法
    public Product construct()
    {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}
public class Product  {
    private String partA;
    private String partB;
    private String partC;
    public void setPartA(String partA)
    {
        this.partA=partA;
    }
    public void setPartB(String partB)
    {
        this.partB=partB;
    }
    public void setPartC(String partC)
    {
        this.partC=partC;
    }
    public void show()
    {
        System.out.println("产品有这些部分"+partA+partB+partC);
    }
}

main方法里面:

  Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product product = director.construct();
        product.show();

14. 状态模式:

public abstract class State {
    public abstract void Handle(Context context);
}

实现类:

public class ConcreteStateA extends State {
    @Override
    public void Handle(Context context) {
        System.out.println("当前状态是 A.");
        context.setState(new ConcreteStateB());
    }
}
public class ConcreteStateB extends State {
    @Override
    public void Handle(Context context) {
        System.out.println("当前状态是B");
        context.setState(new ConcreteStateA());
    }
}

环境类:

public class Context {
    private State state;

    public Context() {
        this.state = new ConcreteStateA();
    }
    //设置新状态
    public void setState(State state)
    {
        this.state=state;
    }
    //读取状态
    public State getState()
    {
        return(state);
    }
    //对请求做处理
    public void Handle()
    {
        state.Handle(this);
    }
}

main 入口中的代码:

   Context context=new Context();    //创建环境
        context.Handle();    //处理请求
        context.Handle();
        context.Handle();
        context.Handle();

22. 迭代器模式:

这个模型代码其实,就是我们常用的一个迭代器.
迭代器(Iterator)模式的定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。迭代器模式是一种对象行为型模式,其主要优点如下。
访问一个聚合对象的内容而无须暴露它的内部表示。
遍历任务交由迭代器完成,这简化了聚合类。
它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
增加新的聚合类和迭代器类都很方便,无须修改原有代码。
封装性良好,为遍历不同的聚合结构提供一个统一的接口。
其主要缺点是:增加了类的个数,这在一定程度上增加了系统的复杂性。

结构如下:
抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

模式代码:

public interface Aggregate {
    void add(Object obj);

    void remove(Object obj);

    Iterator getIterator();
}

具体聚合对象

public class ConcreteAggregate implements Aggregate {
    private List<Object> list = new ArrayList<Object>();

    @Override
    public void add(Object obj) {
        list.add(obj);
    }

    @Override
    public void remove(Object obj) {
        list.remove(obj);

    }

    @Override
    public Iterator getIterator() {
        return (Iterator) new ConcreteIterator(list);
    }
}

具体:ConcreteIterator

public class ConcreteIterator implements Iterator {
    private List<Object> list;
    private  int index=-1;

    public ConcreteIterator(List<Object> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        if (index<list.size()-1){
            return true;

        }else {
            return false;
        }
    }
    @Override
    public Object first() {
        index=0;
        Object obj=list.get(index);
        return obj;
    }

    @Override
    public Object next() {
        Object obj=null;
        if (this.hasNext()){
            obj=list.get(++index);
        }
        return obj;

    }
}
public interface Iterator {
    Object first();
    Object next();
    boolean hasNext();
}

main方法内部要执行的内容:

  Aggregate ag = new ConcreteAggregate();
        ag.add("中山大学");
        ag.add("华南理工");
        ag.add("韶关学院");
        System.out.print("聚合的内容有:");
        Iterator it = ag.getIterator();
        while (it.hasNext()) {
            Object ob = it.next();
            System.out.print(ob.toString() + "\t");
        }
        Object ob = it.first();
        System.out.println("\nFirst:" + ob.toString());

23. 解释器模式:

目前个人感觉还是比较难以理解的模式,好多教材中都是最后。

1>表达的接口

public interface Expression {
   boolean interpret(String context);
}

2>终端表达类实现这个接口:

public class TerminalExpression implements Expression {
   private String data;

   public TerminalExpression(String data){
       this.data = data;
   }

   @Override
   public boolean interpret(String context) {
       if(context.contains(data)){
           return true;
       }
       return false;
   }
}

3>具体表达类,这里是and 或者or的两种:
构造的时候需要传入两个表达对象

public class AndExpression implements  Expression {
   private Expression expr1 = null;
   private Expression expr2 = null;

   public AndExpression(Expression expr1, Expression expr2) {
       this.expr1 = expr1;
       this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {
       return expr1.interpret(context) && expr2.interpret(context);
   }
}

另外一个Or的形式:

public class OrExpression implements Expression {
   private Expression expr1 = null;
   private Expression expr2 = null;

   public OrExpression(Expression expr1, Expression expr2) {
       this.expr1 = expr1;
       this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {
       return expr1.interpret(context) || expr2.interpret(context);
   }
}

main 入口类里又两个方法:

//规则:Robert 和 John 是男性
   public static Expression getMaleExpression(){
       Expression robert = new TerminalExpression("Robert");
       Expression john = new TerminalExpression("John");
       return new OrExpression(robert, john);
   }

   //规则:Julie 是一个已婚的女性
   public static Expression getMarriedWomanExpression(){
       Expression julie = new TerminalExpression("Julie");
       Expression married = new TerminalExpression("Married");
       return new AndExpression(julie, married);
   }

main方法内部代码:

 Expression isMale = getMaleExpression();
       Expression isMarriedWoman = getMarriedWomanExpression();

       System.out.println("John is male? " + isMale.interpret("John"));
       System.out.println("Julie is a married women? "
               + isMarriedWoman.interpret("Married Julie"));

相关文章

网友评论

      本文标题:23种设计模式快速理解(android)

      本文链接:https://www.haomeiwen.com/subject/jmkrkktx.html