美文网首页
android 设计模式总结之23种设计模式

android 设计模式总结之23种设计模式

作者: 快感的感知 | 来源:发表于2019-04-14 22:51 被阅读0次

    一、什么是设计模式

    • 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因

    二、为什么学习设计模式

    • 它是很多人很多年以来的经验智慧的总结,教你怎样更高效的来玩耍代码,使原来单一的代码模式变得有趣,漂亮。他是使编程艺术化的入门。

    三、常见的面向对象设计原则

    1、迪米特法则,又称最少知道原则(Demeter Principle)

    • 最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

    假设类A实现了某个功能,类B需要调用类A的去执行这个功能,那么类A应该只暴露一个函数给类B,这个函数表示是实现这个功能的函数,而不是让类A把实现这个功能的所有细分的函数暴露给B。

    2、里氏代换原则

    • 子类型必须能够替换他们的父类型。本质上就是说要好好利用继承和多态,从而以父类的形式来声明变量(或形参),为变量(或形参)赋值任何继承于这个父类的子类。

    3、依赖倒转原则(Dependence Inversion Principle)

    • 这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

    4、接口隔离原则(Interface Segregation Principle)

    • 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。

    5、开闭原则(Open Close Principle)

    • 开闭原则的意思是:对扩展开放,对修改关闭。
      在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

    6、单一原则(Composite Reuse Principle)

    • 一个类单一职责,防止耦合

    四、设计模式分类

    如下图所示:

    401339-20170928225241215-295252070.png

    创建型模式

    这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用新的运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

    public class ShapeFactory {
        
      //普通工厂模式,不符合开闭原则
       public Shape getShape(String shapeType){
           
          if(shapeType.equalsIgnoreCase("CIRCLE")){
             return new Circle();
          } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
             return new Rectangle();
          } else if(shapeType.equalsIgnoreCase("SQUARE")){
             return new Square();
          }
          return null;
       }
    }
    

    抽象工厂更符合开-闭原则,降低耦合,但抽象工厂模式很难支持新种类产品的变化。类复杂。实际应用中使用简单工厂多点

    public class Singleton {  
    //饿汉模式,简单,线程安全,效率高,但一开始就加载了,容易产生垃圾
        private static Singleton instance = new Singleton();  
        private Singleton (){}  
        public static Singleton getInstance() {  
        return instance;  
        }  
    }
    
    public class User {
        private final String firstName;     // 必传参数
        private final String lastName;      // 必传参数
        private final int age;              // 可选参数
        private final String phone;         // 可选参数
        private final String address;       // 可选参数
    
        private User(UserBuilder builder) {
            this.firstName = builder.firstName;
            this.lastName = builder.lastName;
            this.age = builder.age;
            this.phone = builder.phone;
            this.address = builder.address;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public int getAge() {
            return age;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public String getAddress() {
            return address;
        }
    
        public static class UserBuilder {
            private final String firstName;
            private final String lastName;
            private int age;
            private String phone;
            private String address;
    
            public UserBuilder(String firstName, String lastName) {
                this.firstName = firstName;
                this.lastName = lastName;
            }
    
            public UserBuilder age(int age) {
                this.age = age;
                return this;
            }
    
            public UserBuilder phone(String phone) {
                this.phone = phone;
                return this;
            }
    
            public UserBuilder address(String address) {
                this.address = address;
                return this;
            }
    
            public User build() {
                return new User(this);
            }
        }
    }
    
    
    调用
    new User.UserBuilder("王", "小二")
                    .age(20)
                    .phone("123456789")
                    .address("亚特兰蒂斯大陆")
                    .build();
    
    • 原型模式 (Prototype Pattern):通过拷贝原型创建新的对象,当我们的类初始化需要消耗很多的资源时,就可以使用原型模式,因为我们的克隆不会执行构造方法,避免了初始化占有的时间和空间。

    1、浅克隆:
    对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。

    对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组,某个类型的对象等,那么浅拷贝会进行引用传递,也就是只是该成员变量的引用值(内存地址)复制一份给新的对象,因为实际上两个对象的该成员变量都指向同一个实例,在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。

    //这里不实现Serializable接口也可以实现浅克隆
    public class User implements Cloneable,Serializable{
        
        private String name;
        
        private Date birth;
        
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Date getBirth() {
            return birth;
        }
    
        public void setBirth(Date birth) {
            this.birth = birth;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
        
        /**
         * 实现克隆的方法
         */
        public Object clone() throws CloneNotSupportedException{
            return super.clone();
        }
    }
        //使用
        Date date =  new Date(1231231231231l);
        User user = new User();
        user.setName("波波烤鸭");
        user.setAge(18);
        user.setBirth(date);
        System.out.println("----输出原型对象的属性------");
        System.out.println(user);
        System.out.println(user.getName());
        System.out.println(user.getBirth());
        // 克隆对象
        User user1 =(User) user.clone();
        // 修改原型对象中的属性
        date.setTime(123231231231l);
        System.out.println(user.getBirth());
        
        // 修改参数
        user1.setName("dpb");
        System.out.println("-------克隆对象的属性-----");
        System.out.println(user1);
        System.out.println(user1.getName());
        System.out.println(user1.getBirth());
    
    //打印如下
    ----输出原型对象的属性-----
    com.dpb.prototype.User@15db9742
    波波烤鸭
    Tue Jan 06 16:40:31 CST 2009 # 1
    Tue Nov 27 14:53:51 CST 1973 # 2
    
    -------克隆对象的属性-----
    com.dpb.prototype.User@5c647e05
    dpb
    Tue Nov 27 14:53:51 CST 1973 # 和2的结果一样 说明两个对象的Date的引用是同一个
    
    //虽然产生了两个完全不同的对象,但是被复制的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象(比如Date)的引用都仍然指向原来的对象
    

    深拷贝代码实例:
    方式一:重写clone方法

    public class DeepCloneableTarget implements Serializable, Cloneable {
    
        private static final long serialVersionUID = 1L;
    
        private String cloneName;
    
        private String cloneClass;
    
        public DeepCloneableTarget(String cloneName, String cloneClass) {
            this.cloneName = cloneName;
            this.cloneClass = cloneClass;
        }
    
        //因为该类的属性,都是String,因此我们这里使用默认的clone完成即可.
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
    
    
    public class DeepProtoType implements Serializable, Cloneable {
    
        public String name;
        public DeepCloneableTarget deepCloneableTarget;
    
        public DeepProtoType() {
            super();
        }
    
        //深拷贝 - 方式1 使用clone 方法
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Object deep = null;
            //完成对基本数据类型(属性)和String的克隆
            deep = super.clone();
            //对引用类型的属性,进行单独的处理。
            DeepProtoType deepProtoType = (DeepProtoType) deep;
            deepProtoType.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone();
    
            return deep;
        }
    }
    
    public class Client {
        public static void main(String[] args) throws  Exception{
            DeepProtoType p = new DeepProtoType();
            p.name="宋江";
            p.deepCloneableTarget=new DeepCloneableTarget("大牛","小牛的");
    
            //方式1 完成深拷贝
    
            DeepProtoType p2=(DeepProtoType)p.clone();
            System.out.println("p.name="+p.name+"p.deepCloneableTarget="+p.deepCloneableTarget.hashCode());
            System.out.println("p2.name="+p2.name+"p.deepCloneableTarget="+p2.deepCloneableTarget.hashCode());
    
        }
    }
    
    

    方式二:通过对象序列化来实现深拷贝(推荐使用)
    DeepCloneableTarget类

    public class DeepCloneableTarget implements Serializable, Cloneable {
    
        private static final long serialVersionUID = 1L;
    
        private String cloneName;
    
        private String cloneClass;
    
        public DeepCloneableTarget(String cloneName, String cloneClass) {
            this.cloneName = cloneName;
            this.cloneClass = cloneClass;
        }
    
        //因为该类的属性,都是String,因此我们这里使用默认的clone完成即可.
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    DeepProtoType 类
    
    public class DeepProtoType implements Serializable, Cloneable {
    
        public String name;
        public DeepCloneableTarget deepCloneableTarget;
    
        public DeepProtoType() {
            super();
        }
    
        //深拷贝 -  方式2 通过对象序列化实现(推荐使用)
    
        public Object deepClone() {
            //创建流对象
            ByteArrayOutputStream bos = null;
            ObjectOutputStream oos = null;
            ByteArrayInputStream bis = null;
            ObjectInputStream ois = null;
    
            try {
    
                //序列化
                bos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(bos);
                oos.writeObject(this);//当前这个对象以对象流的方式输出
    
                //反序列化
                bis = new ByteArrayInputStream(bos.toByteArray());
                ois = new ObjectInputStream(bis);
    
                DeepProtoType copyObj = (DeepProtoType) ois.readObject();
    
                return copyObj;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            } finally {
                try {
                    bos.close();
                    oos.close();
                    bis.close();
                    ois.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }
    Client 测试用例
    
    public class Client {
        public static void main(String[] args) throws Exception {
            DeepProtoType p = new DeepProtoType();
            p.name = "宋江";
            p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛的");
    
            //方式2 完成深拷贝
            DeepProtoType p3=(DeepProtoType) p.deepClone();
    
            System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
            System.out.println("p3.name=" + p3.name + "p.deepCloneableTarget=" + p3.deepCloneableTarget.hashCode());
    
        }
    }
    
    public class Computer {
        //我们的电脑需要连接1:转按器才可以1:网
        public void net(NetToUsb adapter) {
            //.上网的具体实现, 找“个转接义
            adapter.handleRequest();
        }
    
        public static void main(String[] args) {
            Computer computer = new Computer(); //电脑
            Adaptee adaptee = new Adaptee(); //网线
            Adapter adapter = new Adapter(); //转按器
            computer.net(adapter);*/
    }
    
    

    结构型模式

    这些设计模式关注类和对象的组合。

    //要被适配的类:网线
    public class Adaptee {
        public void request() {
            System.out.println("连接网线上网");
        }
    }
    
    //真正的适配器,需 要连接USB,连接网线~
    public class Adapter extends Adaptee implements NetToUsb {
        @Override
        public void handleRequest() {
            //上网的具体实现,找一个转接头
            super.request();
        }
    }
    
    //按1口转换器的抽象实现~
    public interface NetToUsb {
    //作1川:处理请求,网线=>usb
    public void handleRequest();
    }
    
    
    public class Computer {
        //我们的电脑需要连接1:转按器才可以1:网
        public void net(NetToUsb adapter) {
            //.上网的具体实现, 找“个转接义
            adapter.handleRequest();
        }
    
        public static void main(String[] args) {
    /*        //电脑,适配器,网线~   使用继承的方式
            Computer computer = new Computer(); //电脑
            Adaptee adaptee = new Adaptee(); //网线
            Adapter adapter = new Adapter(); //转按器
            computer.net(adapter);*/
    
            System.out.println("++++++++++++++++++++++++++++++");
    
            //电脑,适配器,网线~   使用组合的方式
            Computer computer = new Computer(); //电脑
            Adaptee adaptee = new Adaptee(); //网线
            Adapter2 adapter = new Adapter2(adaptee); //转按器
    
            computer.net(adapter);
        }
    }
    
    
    • [装饰器模式 (Decorator Pattern):允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。何时使用:在不想增加很多子类的情况下扩展类
    第一代机器人只会跳舞,第二代机器人通过传入第一代机器人拥有了跳舞功能,然后增加唱歌功能呢。
    public interface Robot {
       void dance();
    }
    public class  firstRobot implements Robot {
     
       @Override
       public void dance() {
          System.out.println("dance: dance");
       }
    }
    public class twoRobot implements Robot {
       protected Robot rebot;
     
       public ShapeDecorator(Robot rebot){
          this.rebot = rebot;
       }
     
       public void dance(){
          rebot.dance();
       }  
      public void singing(){
    
      }
    }
    
    • 桥接模式 (Bridge Pattern):两个维度独立变化,依赖方式实现抽象与实现分离:需要一个作为桥接的接口/抽象类,多个角度的实现类依赖注入到抽象类,使它们在抽象层建立一个关联关系


      image.png
    //品牌
    public interface Brand {
        void info();
    }
    
    public class Lenovo implements Brand {
        @Override
        public void info() {
            System.out.print("联想");
        }
    }
    
    public class Apple implements Brand {
        @Override
        public void info() {
            System.out.print("苹果");
        }
    }
    //抽象的电脑类型类
    public abstract class Computer {
        //组合,品牌~
        protected Brand brand;
    
        public Computer(Brand brand) {
            this.brand = brand;
        }
    
        public void info() {
            brand.info();//自带品牌
        }
    }
    class Laptop extends Computer {
        public Laptop(Brand brand) {
            super(brand);
        }
    
        @Override
        public void info() {
            super.info();
            System.out.print("笔记本");
        }
    }
    
    • 外观模式 (Facade Pattern):在客户端和复杂系统之间再加一层,这一次将调用顺序、依赖关系等处理好。即封装底层实现,隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的高层接口
    public class CPU {   
        public void startup(){  
            System.out.println("cpu startup!");  
        }  
        public void shutdown(){  
            System.out.println("cpu shutdown!");  
        }  
    }
     
    public class Memory {    
        public void startup(){  
            System.out.println("memory startup!");  
        }  
        public void shutdown(){  
            System.out.println("memory shutdown!");  
        }  
    } 
     
    public class Disk {  
        public void startup(){  
            System.out.println("disk startup!");  
        }  
        public void shutdown(){  
            System.out.println("disk shutdown!");  
        }  
    }
    public class Computer {  
        private CPU cpu;  
        private Memory memory;  
        private Disk disk;  
     
        public Computer(){  
            cpu = new CPU();  
            memory = new Memory();  
            disk = new Disk();  
        }  
     
        public void startup(){  
            System.out.println("start the computer!");  
            cpu.startup();  
            memory.startup();  
            disk.startup();  
            System.out.println("start computer finished!");  
        }  
     
        public void shutdown(){  
            System.out.println("begin to close the computer!");  
            cpu.shutdown();  
            memory.shutdown();  
            disk.shutdown();  
            System.out.println("computer closed!");  
        }  
    }
    Computer computer = new Computer();  
    computer.startup();  
    computer.shutdown();
    
    • 代理模式 (Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问:增加中间层(代理层),代理类与底层实现类实现共同接口,并创建底层实现类对象(底层实现类对象依赖注入代理类),以便向外界提供功能接口
    public interface Image {
       void display();
    }
    public class RealImage implements Image {
     
       private String fileName;
     
       public RealImage(String fileName){
          this.fileName = fileName;
          loadFromDisk(fileName);
       }
     
       @Override
       public void display() {
          System.out.println("Displaying " + fileName);
       }
     
       private void loadFromDisk(String fileName){
          System.out.println("Loading " + fileName);
       }
    }
    public class ProxyImage implements Image{
     
       private RealImage realImage;
       private String fileName;
     
       public ProxyImage(String fileName){
          this.fileName = fileName;
       }
     
       @Override
       public void display() {
          if(realImage == null){
             realImage = new RealImage(fileName);
          }
          realImage.display();
       }
    }
    public class ProxyPatternDemo {
       public static void main(String[] args) {
          Image image = new ProxyImage("test_10mb.jpg");
          // 图像将从磁盘加载
          image.display(); 
          System.out.println("");
          // 图像不需要从磁盘加载
          image.display();  
       }
    }
    
    • 过滤器模式 (Filter、Criteria Pattern):使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来
      https://www.runoob.com/design-pattern/filter-pattern.html

    • 组合模式 (Composite Pattern):用户对单个对象和组合对象的使用具有一致性的统一接口,何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

    public class Employee {
       private String name;
       private String dept;
       private int salary;
       private List<Employee> subordinates;
     
       //构造函数
       public Employee(String name,String dept, int sal) {
          this.name = name;
          this.dept = dept;
          this.salary = sal;
          subordinates = new ArrayList<Employee>();
       }
     
       public void add(Employee e) {
          subordinates.add(e);
       }
     
       public void remove(Employee e) {
          subordinates.remove(e);
       }
     
       public List<Employee> getSubordinates(){
         return subordinates;
       }
     
       public String toString(){
          return ("Employee :[ Name : "+ name 
          +", dept : "+ dept + ", salary :"
          + salary+" ]");
       }   
    }
    public class CompositePatternDemo {
       public static void main(String[] args) {
          Employee CEO = new Employee("John","CEO", 30000);
     
          Employee headSales = new Employee("Robert","Head Sales", 20000);
     
          Employee headMarketing = new Employee("Michel","Head Marketing", 20000);
     
          Employee clerk1 = new Employee("Laura","Marketing", 10000);
          Employee clerk2 = new Employee("Bob","Marketing", 10000);
     
          Employee salesExecutive1 = new Employee("Richard","Sales", 10000);
          Employee salesExecutive2 = new Employee("Rob","Sales", 10000);
     
          CEO.add(headSales);
          CEO.add(headMarketing);
     
          headSales.add(salesExecutive1);
          headSales.add(salesExecutive2);
     
          headMarketing.add(clerk1);
          headMarketing.add(clerk2);
     
          //打印该组织的所有员工
          System.out.println(CEO); 
          for (Employee headEmployee : CEO.getSubordinates()) {
             System.out.println(headEmployee);
             for (Employee employee : headEmployee.getSubordinates()) {
                System.out.println(employee);
             }
          }        
       }
    }
    
    • 享元模式 (Flyweight Pattern):主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
    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);
       }
    }
    
    public class ShapeFactory {
       private static final HashMap<String, Shape> circleMap = new HashMap<>();
     
       public static Shape getCircle(String color) {
          Circle circle = (Circle)circleMap.get(color);
     
          if(circle == null) {
             circle = new Circle(color);
             circleMap.put(color, circle);
             System.out.println("Creating circle of color : " + color);
          }
          return circle;
       }
    }
    //随机调用,有用过的会从hashmap中取出
    public class FlyweightPatternDemo {
       private static final String colors[] = 
          { "Red", "Green", "Blue", "White", "Black" };
       public static void main(String[] args) {
     
          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);
       }
    }
    

    行为型模式

    这些设计模式特别关注对象之间的通信。

    • 责任链模式(Chain of Responsibility Pattern):拦截的类都实现统一接口,每个接收者都包含对下一个接收者的引用。将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
      //抽象处理者角色
    abstract class Handler {
        private Handler next;
        public void setNext(Handler next) {
            this.next = next;
        }
        public Handler getNext() {
            return next;
        }
        //处理请求的方法
        public abstract void handleRequest(String request);
    }
    //具体处理者角色1
    class ConcreteHandler1 extends Handler {
        public void handleRequest(String request) {
            if (request.equals("one")) {
                System.out.println("具体处理者1负责处理该请求!");
            } else {
                if (getNext() != null) {
                    getNext().handleRequest(request);
                } else {
                    System.out.println("没有人处理该请求!");
                }
            }
        }
    }
    //具体处理者角色2
    class ConcreteHandler2 extends Handler {
        public void handleRequest(String request) {
            if (request.equals("two")) {
                System.out.println("具体处理者2负责处理该请求!");
            } else {
                if (getNext() != null) {
                    getNext().handleRequest(request);
                } else {
                    System.out.println("没有人处理该请求!");
                }
            }
        }
    }
    public class ChainOfResponsibilityPattern {
        public static void main(String[] args) {
            //组装责任链
            Handler handler1 = new ConcreteHandler1();
            Handler handler2 = new ConcreteHandler2();
            handler1.setNext(handler2);
            //提交请求
            handler1.handleRequest("two");
        }
    }
    
    /抽象目标
    abstract class Subject {
        protected List<Observer> observers = new ArrayList<Observer>();
        //增加观察者方法
        public void add(Observer observer) {
            observers.add(observer);
        }
        //删除观察者方法
        public void remove(Observer observer) {
            observers.remove(observer);
        }
        public abstract void notifyObserver(); //通知观察者方法
    }
    //具体目标
    class ConcreteSubject extends Subject {
        public void notifyObserver() {
            System.out.println("具体目标发生改变...");
            System.out.println("--------------");
            for (Object obs : observers) {
                ((Observer) obs).response();
            }
        }
    }
    //抽象观察者
    interface Observer {
        void response(); //反应
    }
    //具体观察者1
    class ConcreteObserver1 implements Observer {
        public void response() {
            System.out.println("具体观察者1作出反应!");
        }
    }
    //具体观察者1
    class ConcreteObserver2 implements Observer {
        public void response() {
            System.out.println("具体观察者2作出反应!");
        }
    }
    
    public class ObserverPattern {
        public static void main(String[] args) {
            Subject subject = new ConcreteSubject();
            Observer obs1 = new ConcreteObserver1();
            Observer obs2 = new ConcreteObserver2();
            subject.add(obs1);
            subject.add(obs2);
            subject.notifyObserver();
        }
    }
    
    • 模板模式(Template Pattern):将这些通用算法抽象出来,在一个抽象类中公开定义了执行它的方法的方式/模板。主要解决:一些方法通用,却在每一个子类都重新写了这一方法。
    public abstract class Game {
       abstract void initialize();
       abstract void startPlay();
       abstract void endPlay();
     
       //模板
       public final void play(){
     
          //初始化游戏
          initialize();
     
          //开始游戏
          startPlay();
     
          //结束游戏
          endPlay();
       }
    }
    
    public class Cricket extends Game {
     
       @Override
       void endPlay() {
          System.out.println("Cricket Game Finished!");
       }
     
       @Override
       void initialize() {
          System.out.println("Cricket Game Initialized! Start playing.");
       }
     
       @Override
       void startPlay() {
          System.out.println("Cricket Game Started. Enjoy the game!");
       }
    }
    public class Football extends Game {
     
       @Override
       void endPlay() {
          System.out.println("Football Game Finished!");
       }
     
       @Override
       void initialize() {
          System.out.println("Football Game Initialized! Start playing.");
       }
     
       @Override
       void startPlay() {
          System.out.println("Football Game Started. Enjoy the game!");
       }
    }
    public class TemplatePatternDemo {
       public static void main(String[] args) {
     
          Game game = new Cricket();
          game.play();
          System.out.println();
          game = new Football();
          game.play();      
       }
    }
    
    //不用命令模式,添加一个界面就要修改电视类和观看类
    //电视机对象:提供了播放不同频道的方法
    public class Television {
        
        public void playCctv1() {
            System.out.println("--CCTV1--");
        }
    
        public void playCctv2() {
            System.out.println("--CCTV2--");
        }
    }
    public class Watcher {
        //持有一个
        public Television tv;
    
        public Watcher(Television tv) {
            this.tv = tv;
        }
    
        public void playCctv1() {
            tv.playCctv1();
        }
    
        public void playCctv2() {
            tv.playCctv2();
        }
    }
     Watcher watcher = new Watcher(new Television());
            watcher.playCctv1();
            watcher.playCctv2();
    
    //使用命令模式
    public abstract class Command {
        //命令接收者:电视机
        protected Television television;
    
        public Command(Television television) {
            this.television = television;
        }
    
        //命令执行
        abstract void execute();
    }
    //播放cctv1的命令
    public class CCTV1Command extends Command {
        @Override
        void execute() {
            television.playCctv1();
        }
    }
    
    //播放cctv2的命令
    public class CCTV6Command extends Command {
        @Override
        void execute() {
            television.playCctv2();
        }
    }
    ————————————————
            historyCommand.add(command);
            command.execute();
        }
    
        //遥控器返回命令
    public class TeleController {
        //播放记录
        List<Command> historyCommand = new ArrayList<Command>();
    
        //切换卫视
        public void switchCommand(Command command) {
            historyCommand.add(command);
            command.execute();
        }
        public void back() {
            if (historyCommand.isEmpty()) {
                return;
            }
            int size = historyCommand.size();
            int preIndex = size-2<=0?0:size-2;
    
            //获取上一个播放某卫视的命令
            Command preCommand = historyCommand.remove(preIndex);
            preCommand.execute();
        }
    }
    
     //创建一个电视机
            Television tv = new Television();
            //创建一个遥控器
            TeleController teleController = new TeleController();
    
            teleController.switchCommand(new CCTV1Command(tv));
            teleController.switchCommand(new CCTV2Command(tv));
           //模拟遥控器返回键
            teleController.back();
            teleController.back();
    
    • 解释器模式(Interpreter Pattern):给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子
      何时使用:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

    • 迭代器模式(Iterator Pattern):集合中含有迭代器:分离了集合对象的遍历行为,抽象出一个迭代器类来负责,无须暴露该对象的内部表示

    • 中介者模式(Mediator Pattern):对象与对象之间存在大量的关联关系,将对象之间的通信关联关系封装到一个中介类中单独处理,从而使其耦合松散,可以独立地改变它们之间的交互

    • 策略模式(Strategy Pattern):策略对象依赖注入到context对象,context对象根据它的策略改变而改变它的相关行为(可通过调用内部的策略对象实现相应的具体策略行为)

    public class Context {
       private Strategy strategy;
     
       public Context(Strategy strategy){
          this.strategy = strategy;
       }
     
       public int executeStrategy(int num1, int num2){
          return strategy.doOperation(num1, num2);
       }
    }
    
    public interface Strategy {
       public int doOperation(int num1, int num2);
    }
    public class OperationAdd implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 + num2;
       }
    }
    public class OperationSubtract implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 - num2;
       }
    }
    public class OperationMultiply implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 * num2;
       }
    }
    
    public class StrategyPatternDemo {
       public static void main(String[] args) {
          Context context = new Context(new OperationAdd());    
          System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
     
          context = new Context(new OperationSubtract());      
          System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
     
          context = new Context(new OperationMultiply());    
          System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
       }
    }
    
    • 状态模式(State Pattern):状态对象依赖注入到context对象,context对象根据它的状态改变而改变它的相关行为(可通过调用内部的状态对象实现相应的具体行为)

    • 备忘录模式(Memento Pattern):通过一个备忘录类专门存储对象状态。客户通过备忘录管理类管理备忘录类。

    • 空对象模式(Null Object Pattern):创建一个未对该类做任何实现的空对象类,该空对象类将无缝地使用在需要检查空值的地方。不要为了屏蔽null而使用空对象,应保持用null,远比用非null的值来替代“无值”要好。(慎用)

    参考链接:https://www.jianshu.com/p/234a156b0210

    相关文章

      网友评论

          本文标题:android 设计模式总结之23种设计模式

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