《图解设计模式》学习笔记

我多想拥抱你,可惜时光之里山南水北,可惜你我之间人来人往。             —— 鸢喜            2019.9.12


      关于UML类图用idea画的,可以看博客:https://www.cnblogs.com/liruilong/p/11506280.html

第一部分,适应设计模式

第一章,Iterator模式:

迭代器模式:提供一种方法顺序访问迭代器中的每个元素。,而不暴露其内部表示。迭代器模式就是将迭代元素的责任交给迭代器,而不是聚合函数,通过迭代器,使得聚合对象的结构更加简单,不需要关注它元素的遍历,符合单一职责原则.

理解:迭代器模式需要一个迭代器接口(定义遍历集合的方法),一个聚合类接口(定义创建迭代器方法),然后有实现了聚合类接口的存放元素的类和一个实现了迭代器接口的类,用于遍历元素.

我们一般在使用集合的时候用的最多,forEach本身就是迭代器实现的,对于集合类来讲,我们通过集合类获取迭代器之后,集合中的元素都存在于迭代器里了.然后调用迭代器里的方法进行迭代..

  1. Iterator模式中的角色:
    1. Iterator(抽象迭代器)
      package com.liruilong.tx_sjms.Iterator;
      /**
       * @Description : 遍历集合的接口
       * @Author: Liruilong
       * @Date: 2019/9/11 0:11
       */
      public interface Iterator {
          boolean hasNext();
          Object next();
      }
      
    2. ConcreteIterator(具体的迭代器)
      package com.liruilong.tx_sjms.Iterator;
      /**
       * @Description : 遍历书籍的类
       * @Author: Liruilong
       * @Date: 2019/9/11 0:21
       */
      public class BooShifkIterator implements Iterator {
          private BookShelf bookShelf;
          private int index;
          public BooShifkIterator(BookShelf bookShelf) {
              this.bookShelf = bookShelf;
              this.index = 0;
          }
          @Override
          public boolean hasNext() {
              if (index < bookShelf.getlength()){
                  return  true;
              } else {
                  return false;
              }
          }
          @Override
          public Object next() {
              Book book = bookShelf.getBooksAt(index);
              index++;
              return book;
          }
      }
      
    3. Aggregate(抽象聚合类)
      package com.liruilong.tx_sjms.Iterator;
      /**
       * @Description : 表示集合的接口
       * @Author: Liruilong
       * @Date: 2019/9/11 0:10
       */
      public interface Aggregate {
          Iterator iterator();
      }
    4. ConcerteAggregate(具体的聚合类):
      package com.liruilong.tx_sjms.Iterator;
      
      
      
      /**
       * @Description :表示书架的类
       * @Author: Liruilong
       * @Date: 2019/9/11 0:14
       */
      public class BookShelf implements Aggregate {
      
          private  Book[] books;
          private int last = 0;
          // 初始化书架
          public BookShelf(int maxsize) {
              this.books = new Book[maxsize];
          }
          // 在书架的最后放入书
          public void appendBook(Book book){
              this.books[last] = book;
              last++;
          }
          // 获取指定书籍
          public Book getBooksAt(int index) {
              return books[index];
          }
          // 获取书架容量
          public int getlength() {
              return last;
          }
          @Override
          public Iterator iterator() {
              return new BooShifkIterator(this);
          }
      }
      

第二章,Adapter模式

适配器模式:在实际情况和需求之间,填补两者之间的差异的设计模式,即将一个类的接口转换为客户期望的另一个接口,

将交流的220V的电由ac适配器转换为直流电100v,ac适配器就充当适配角色.

适配器有两种:类适配器模式(使用继承的适配器)和对象适配器模式(使用委托的适配器).

类适配器模式:

使用继承,即适配器继承于被适配者,实现了需求对象接口,可以理解为需求对象接口将需求告诉适配器(实了现接口方法),适配器对被适配者进行加工,然后满足客户需求.

  1. Adapter模式中的角色:
    1. Target(对象):定义需求方法
      package com.liruilong.tx_sjms.Adapter;
      /**
       * @Description : 需求的接口
       * @Author: Liruilong
       * @Date: 2019/9/11 21:39
       */
      public interface Print {
          void printWeak();
          void printStrong();
      }
      
    2. Client(请求者):即需求的客户
      package com.liruilong.tx_sjms.Adapter;
      /**
       * @Description :
       * @Author: Liruilong
       * @Date: 2019/9/11 21:43
       */
      public class Main {
          public static void main(String[] args) {
              Print print = new PrintBanner("Hello");
              print.printWeak();
              print.printStrong();
          }
      }
      
    3. Adaptee(被适配的对象),即持有既定方法的角色
      package com.liruilong.tx_sjms.Adapter;
      /**
       * @Description : 实际情况
       * @Author: Liruilong
       * @Date: 2019/9/11 21:28
       */
      public class Banner {
          private String string;
      
          public Banner(String string) {
              this.string = string;
          }
          public void showWithParen(){
              System.out.println("("+string+")");
          }
          public void showWithAster(){
              System.out.println("*"+string+"*");
          }
      
      }
      
    4. Adapter(适配):将用户需求通过被适配对象转换为对象.
      package com.liruilong.tx_sjms.Adapter;
      
      /**
       * @Description :
       * @Author: Liruilong
       * @Date: 2019/9/11 21:41
       */
      public class PrintBanner extends Banner implements Print {
          public PrintBanner(String string) {
              super(string);
          }
          @Override
          public void printWeak() {
              showWithParen();
          }
          @Override
          public void printStrong() {
              showWithAster();
          }
      
      }

对象适配器模式:

  1. 使用委托,适配器继承了需求抽象类,与被适配者为聚合关系.可以理解需求对象抽象类将需求告诉适配器(实现了抽象类方法),适配器委托被适配者进行加工.然后满足客户需求.
  2. Adapter模式中的角色:
    1. Target(对象):定义需求方法
      package com.liruilong.tx_sjms.Adapter;
      
      /**
       * @Description :
       * @Author: Liruilong
       * @Date: 2019/9/12 0:42
       */
      public abstract class Prints {
          public  abstract void printWeak();
          public  abstract void printStrong();
      }
      
    2. Client(请求者):即需求的客户
      package com.liruilong.tx_sjms.Adapter;
      
      /**
       * @Description :
       * @Author: Liruilong
       * @Date: 2019/9/11 21:43
       */
      public class Main {
          public static void main(String[] args) {
              Print print = new PrintBanner("Hello");
              print.printWeak();
              print.printStrong();
          }
      }
      
    3. Adaptee(被适配的对象),即持有既定方法的角色
      package com.liruilong.tx_sjms.Adapter;
      /**
       * @Description : 实际情况
       * @Author: Liruilong
       * @Date: 2019/9/11 21:28
       */
      public class Banner {
          private String string;
      
          public Banner(String string) {
              this.string = string;
          }
          public void showWithParen(){
              System.out.println("("+string+")");
          }
          public void showWithAster(){
              System.out.println("*"+string+"*");
          }
      
      }
      
    4. Adapter(适配):将用户需求通过被适配对象转换为对象.
      package com.liruilong.tx_sjms.Adapter;
      
      /**
       * @Description :
       * @Author: Liruilong
       * @Date: 2019/9/11 21:41
       */
      public class PrintBanners extends Prints {
          private Banner banner;
          public PrintBanners(String string) {
              this.banner = new Banner(string);
          }
          @Override
          public void printWeak() {
              banner.showWithParen();
          }
          @Override
          public void printStrong() {
              banner.showWithAster();
          }
      }
    5. Main:

第二部分,交给子类.

第三章,Template Method 模式

模板方法:即在一个方法中定义算法骨架,而将一些步骤延迟到子类,或者讲在父类中定义处理流程框架,在子类中实现具体的处理,

模板方法可以使得子类在不改变算法算法结构的情况下,重新定义算法中的某些步骤.Thread类中,start方法就是一种模板方法模式的应用,对于不同的实现,有不同的run()方法.

Template Method模式中的角色:

  1. AbstractClass(抽象类):实现模板方法,声明中模板方法中所使用得到的抽象方法.
    package com.liruilong.tx_sjms.TemplaterMethod;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 11:26
     */
    public abstract class AbstractDisplay {
            public abstract void open();
            public  abstract  void  print();
            public  abstract  void close();
            public  final  void  display(){
                open();
                for (int i = 0; i < 5; i++){
                    print();
                }
                close();
            }
    }
    
  2. ConcreteClass(具体类):
    package com.liruilong.tx_sjms.TemplaterMethod;
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 11:29
     */
    public class CharDisplay  extends AbstractDisplay {
        private char ch;
        public CharDisplay(char ch) {
            this.ch = ch;
        }
        @Override
        public void open() {
            System.out.print("<<");
        }
        @Override
        public void print() {
            System.out.print(ch);
        }
        @Override
        public void close() {
            System.out.println(">>");
        }
    }
    
    
    package com.liruilong.tx_sjms.TemplaterMethod;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 12:14
     */
    public class StringDisplay extends AbstractDisplay {
        private String string;
        private int width;
        public StringDisplay(String string) {
            this.string = string;
            // 保存字符串的字节长度
            this.width = string.getBytes().length;
        }
        @Override
        public void open() {
            pringLine();
        }
        @Override
        public void print() {
            System.out.println("|"+string+"|");
        }
        @Override
        public void close() {
            pringLine();
        }
        private void pringLine(){
            System.out.println("+");
            for (int i = 0; i < width; i++){
                System.out.print("-");
            }
            System.out.println("+");
        }
    }
    
    
  3. main:
    package com.liruilong.tx_sjms.TemplaterMethod;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 12:22
     */
    public class Main {
        public static void main(String[] args) {
            AbstractDisplay display = new CharDisplay('H');
            AbstractDisplay display1 = new StringDisplay("你好,世界");
            display.display();
            display1.display();
        }
    }
    

     

类的层次和抽象类:

  1. 父类对子类的要求(子类角度);
    1. 在子类中可以使用父类中定义的方法.
    2. 可以通过在子类中增加方法实现新的功能
    3. 在子类中重写父类的方法可以改变程序的行为.
  2. 父类角度:
    1. 期待子类去实现抽象方法
    2. 要求子类去实现抽象方法
  3. 抽象类的意义,在抽象阶段处理好流程.

第四章,factory Method模式

Factory Method模式:用Template Method模式来构建生成实例的工厂,就是factory Method模式.只要是FactoryMethod模式,在生成实例时就一定会使用到TemplateMethod模式.

FactoryMethod模式中的登场角色

  1. Product(产品):属于框架的一方,一个抽象类,定义生成那些实例所持有的API接口,
    package com.liruilong.tx_sjms.FactoryMethod.framework;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 19:35
     */
    public abstract class Product {
        public abstract void use();
    }
    
  2. Creator(创建者):属于框架一方,负责生成产品的抽象类.
    package com.liruilong.tx_sjms.FactoryMethod.framework;
    
    import com.liruilong.concurrent.Producer_Consuner.Producer;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 19:35
     */
    public abstract class Factory {
        public final Product create(String owner){
            Product p = createProducer(owner);
            registerProduct(p);
            return p;
        }
    
        protected abstract Product createProducer(String owner);
        protected abstract void registerProduct(Product product);
    }
    
  3. ConcreteCreator(具体的创建者):负责具体生成产品
    package com.liruilong.tx_sjms.FactoryMethod.idcard;
    
    import com.liruilong.concurrent.Producer_Consuner.Producer;
    import com.liruilong.tx_sjms.FactoryMethod.framework.Product;
    
    /**
     * @Description : 一个产品
     * @Author: Liruilong
     * @Date: 2019/9/12 19:35
     */
    public class IDCard  extends Product {
       private  String owner;
        IDCard(String owner){
           System.out.println("制作"+owner+"的ID卡");
           this.owner = owner;
       }
        @Override
        public void use() {
            System.out.println("使用"+owner+"的ID卡。");
        }
        public  String getOwner(){
           return owner;
        }
    
    }
    
  4. ConcreteProduct(具体的产品):
    package com.liruilong.tx_sjms.FactoryMethod.idcard;
    
    
    import com.liruilong.concurrent.Producer_Consuner.Producer;
    import com.liruilong.tx_sjms.FactoryMethod.framework.Factory;
    import com.liruilong.tx_sjms.FactoryMethod.framework.Product;
    
    import java.util.ArrayList;
    import java.util.LinkedHashMap;
    import java.util.List;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 19:36
     */
    public class IDCardFactory extends Factory {
    
        private List owners = new ArrayList();
        // 生产产品
        @Override
        protected Product createProducer(String owner) {
            return new IDCard(owner);
        }
        // 注册产品
        @Override
        protected void registerProduct(Product producer) {
            owners.add(((IDCard)producer).getOwner());
        }
        public List getOwners(){
            return owners;
        }
    }
    
  5. Main
     

    package com.liruilong.tx_sjms.FactoryMethod;
    
    import com.liruilong.tx_sjms.FactoryMethod.framework.Factory;
    import com.liruilong.tx_sjms.FactoryMethod.framework.Product;
    import com.liruilong.tx_sjms.FactoryMethod.idcard.IDCardFactory;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/12 20:45
     */
    public class Main {
        public static void main(String[] args) {
            Factory factory = new IDCardFactory();
            Product product = factory.create("1");
            Product product1 = factory.create("2");
            Product product2 = factory.create("3");
            Product product3 = factory.create("4");
            product.use();
            product1.use();
            product2.use();
            product3.use();
    
    
        }
    }
    

     

第三部分,生成实例

第五章,Singleton模式(单例模式)

Singleton模式:Singleton角色中返回一个实例static方法,该方法总会返回一个实例.

Singleton模式中的角色

Singleton角色


package com.liruilong.singleton;

/**
 * @Author: Liruilong
 * @Date: 2019/7/20 17:55
 */

// final 不允许被继承
public final class Singleton {
    // 实例变量
    private byte[] bate = new byte[1024];
    // 私有的构造函数,即不允许外部 new
    private Singleton(){ }

/**
     * @Author Liruilong
     * @Description 双重校验锁单例(Double-Check)+Volatile
     *  对懒汉-同步方法的改进,当有两个线程发现singleton为null时,只有一个线程可以进入到同步代码块里。
     *  即满足了懒加载,又保证了线程的唯一性
     *  不加volition的缺点,有时候可能会报NPE,(JVM运行指令重排序)
     *  有可能实例对象的变量未完成实例化其他线程去获取到singleton变量。
     *  未完成初始化的实例调用其方法会抛出空指针异常。
     * @Date 18:20 2019/7/26
     * @Param
     * @return
     **/

    private  static volatile Singleton singleton2 = null;
    public static Singleton getInstance4() {

        if (singleton2 == null){
            synchronized (Singleton.class){
                if (singleton2 ==null){
                    singleton2 = new Singleton();
                }
            }
        }
        return singleton2;
    }

使用场景:

  • ● 要求生成唯一序列号的环境;
  • ● 在整个项目中需要一个共享访问点或共享数据,例如一个 Web 页面上的计数 器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;
  • ● 创建一个对象需要消耗的资源过多,如要访问 IO 和数据库等资源;
  • ● 需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式 (当然,也可以直接声明为 static 的方式)。

第六章,Prototype模式(原型模式)

通过复制生成实例,在实际的开发过程中,有时候也会有在不指定类名的前提下生成实例的需求,

  1. 对象种类繁多,无法将它们整合到一个类中时
  2. 难以根据类生成实例时.
  3. 想解耦框架与生成的实例时.

理解:原型模式,即原型对象实现了Cloneable接口,具有复制能力.在具体的原型实现类中获取该原型使用复制实例的方法获取,在使用者中直接调用具体原型中获取实例的方法.

原型模式中的角色:

  1. Prototype:负责用于定义现有实例来生成新实例的方法
    package com.liruilong.tx_sjms.Prototype.framework;
    
    
    
    /**
     * @Description : 复制功能的接口
     * @Author: Liruilong
     * @Date: 2019/9/13 14:53
     */
    public interface Products extends Cloneable{
         void use(String s);
         Products createClone();
    }
    
  2. ConcretePrototype(具体的原型):负责实现复制现有实例并生成新实例的方法,
    package com.liruilong.tx_sjms.Prototype;
    
    
    import com.liruilong.tx_sjms.Prototype.framework.Products;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/13 14:52
     */
    public class MessageBox implements Products {
    
        private char decochar;
    
        public MessageBox(char decochar) {
            this.decochar = decochar;
        }
    
        @Override
        public void use(String s) {
            int length = s.getBytes().length;
            for (int i = 0; i < length + 4; i++){
                System.out.print(decochar);
            }
            System.out.println("");
            System.out.println(decochar + " " + s + " " + decochar);
            for (int i = 0; i <length + 4; i++){
                System.out.print(decochar);
            }
            System.out.println(" ");
    
        }
    
        @Override
        public Products createClone() {
            Products p = null;
            try{
                p = (Products) clone();
            }catch (CloneNotSupportedException e){
                e.printStackTrace();
            }
            return  p;
        }
    }
    
    package com.liruilong.tx_sjms.Prototype;
    
    import com.liruilong.tx_sjms.Prototype.framework.Products;
    
    
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/13 14:53
     */
    public class UnderlinePen implements Products {
        private char ulchar;
    
        public UnderlinePen(char ulchar) {
            this.ulchar = ulchar;
        }
    
        @Override
        public void use(String s) {
            int length = s.getBytes().length;
            System.out.println("\"" + s + "\"" );
            System.out.print(" ");
            for (int i = 0; i < length; i++){
                System.out.print(ulchar);
            }
            System.out.println(" ");
        }
        @Override
        public Products createClone(){
            Products p = null;
            try {
                p = (Products) clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return p;
        }
    
    
    }
    
  3. Client角色,负责使用复制实例的方法生成新的实例.?
    package com.liruilong.tx_sjms.Prototype.framework;
    
    
    import java.util.HashMap;
    
    /**
     * @Description : 使用Product接口来复制实例
     * @Author: Liruilong
     * @Date: 2019/9/13 14:54
     */
    public class Manager {
    
        private HashMap showcase = new HashMap();
    
        // 对产品进行注册,面向接口编程
        public void register(String name, Products products){
    
            showcase.put(name, products);
        }
        // 对产品进行复制
        public Products create(String protoname){
            Products p = (Products) showcase.get(protoname);
            return p.createClone();
        }
    
    }
    
  4. Mian
    package com.liruilong.tx_sjms.Prototype;
    
    import com.liruilong.tx_sjms.Prototype.framework.Manager;
    import com.liruilong.tx_sjms.Prototype.framework.Products;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/13 14:52
     */
    public class Main {
        public static void main(String[] args) {
            // 准备
            Manager manager = new Manager();
            UnderlinePen upen = new UnderlinePen('~');
            MessageBox mbox = new MessageBox('*');
            MessageBox sbox = new MessageBox('/');
            manager.register("strong message", upen);
            manager.register("warning box", mbox);
            manager.register("slash box", sbox);
            // 生成
            Products products = manager.create("strong message");
            products.use("Hello, world");
            Products products1 = manager.create("warning box");
            products1.use("Hello, world");
            Products products2 = manager.create("slash box");
            products2.use("Hello, word");
        }
    }
    

     

第七章,Builder模式,(组装复制的实例)

建造者模式,封装一个复杂对象的构建过程.

  • 将复杂的对象的构建过程分解在不同的方法中,使得创建过程清晰,
  • 同时也可以是使得相同的创建过程能够创建不同的产品,

Builder模式中的角色:

  1. Builder建造者
    package com.liruilong.tx_sjms.Builder;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/15 10:15
     */
    public abstract class Builder {
        public abstract void makeTitle(String string);
        public  abstract void maekString(String string);
        public  abstract void maekItems(String[] items);
        public abstract void close();
    
    }
    
  2. ConcreteBuilder具体的建造者
    package com.liruilong.tx_sjms.Builder;
    
    
    
    
    import java.io.FileOutputStream;
    import java.io.FilterWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/15 10:38
     */
    public class HTMLBulider extends Builder {
        private  String filename;
        private PrintWriter writer;
    
        @Override
        public void makeTitle(String title) {
            filename = title + ".html";
            try {
                writer = new PrintWriter(new FileOutputStream(filename));
            }catch (IOException e){
                e.printStackTrace();
            }
            writer.println("<html><head><title>" + title + "</title></head><body>" );
            writer.println("<p>" + title +"</p>");
        }
    
        @Override
        public void maekString(String string) {
            writer.println("<p>" + string + "</p>");
        }
    
        @Override
        public void maekItems(String[] items) {
            writer.println("<ul>");
            for (int i = 0; i < items.length; i++){
                writer.println("<li>" + items[i] + "</li>");
            }
            writer.println("/ul");
        }
    
        @Override
        public void close() {
            writer.println("</body></html>");
            writer.close();
        }
        public String getResoult(){
            return filename;
        }
    }
    
    package com.liruilong.tx_sjms.Builder;
    
    
    
    
    import java.io.FileOutputStream;
    import java.io.FilterWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/15 10:38
     */
    public class HTMLBulider extends Builder {
        private  String filename;
        private PrintWriter writer;
    
        @Override
        public void makeTitle(String title) {
            filename = title + ".html";
            try {
                writer = new PrintWriter(new FileOutputStream(filename));
            }catch (IOException e){
                e.printStackTrace();
            }
            writer.println("<html><head><title>" + title + "</title></head><body>" );
            writer.println("<p>" + title +"</p>");
        }
    
        @Override
        public void maekString(String string) {
            writer.println("<p>" + string + "</p>");
        }
    
        @Override
        public void maekItems(String[] items) {
            writer.println("<ul>");
            for (int i = 0; i < items.length; i++){
                writer.println("<li>" + items[i] + "</li>");
            }
            writer.println("/ul");
        }
    
        @Override
        public void close() {
            writer.println("</body></html>");
            writer.close();
        }
        public String getResoult(){
            return filename;
        }
    }
    

     

  3. Director监工
    package com.liruilong.tx_sjms.Builder;
    
    import java.io.BufferedReader;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/15 10:18
     */
    public class Director {
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
        public  void  construct(){
            builder.makeTitle("Greeting");
            builder.maekString("从早到下午");
            builder.maekItems(new String[]{"早上好", "下午好"});
            builder.maekString("晚上");
            builder.maekItems(new String[]{"晚上好", "晚安", "在见"});
            builder.close();
        }
    }
    
  4. Cilent使用者
    package com.liruilong.tx_sjms.Builder;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/15 10:59
     */
    public class Main {
        public static void main(String[] args) {
           TextBuilder textBuilder = new TextBuilder();
           Director director = new Director(textBuilder);
           director.construct();
            System.out.println(textBuilder.getResult());
    
            HTMLBulider htmlBulider =  new HTMLBulider();
            Director director1 = new Director(htmlBulider);
            director1.construct();
            System.out.println(htmlBulider.getResoult());
    
        }
        public  static  void usage(){
            System.out.println("Usage:java Main plain 编写纯文本");
            System.out.println("Usage: java Main html 编写html");
        }
    }
    
    

 

第八章,AbstractFactory模式

AbstractFactory模式,将关联零件组装成产品,即将抽象零件组装为抽象产品.即并不关心零件的具体实现,而只是关心接口API,即仅使用接口将零件组装.

第四部分,分开考虑:

第九章,Bridge模式

(将类的功能层次结构与现实层次结构分离)

类的层次结构的两个作用,

  • 希望增加新的功能时,使用继承,父类具有的基本功能,在子类中增加新的功能.---类的功能层次结构.
  • 希望增加新的实现的时候,定义了接口,然后子类负责实现这些抽象方法,父类通过声明抽象方法来定义接口,子类通过实现具体的方法来实现接口.---类的实现层次结构.

将类的功能层次和类的实现层次结构分离为两个独立的类层次结构,有利于独立的对他们进行扩展.

Bridge模式中的登场角色:

  1. Abstraction(抽象化):位于"类的功能结构的最上层",是与Implementor(实现者)建立桥梁的,
    package com.liruilong.tx_sjms.Bridge;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/17 2:05
     */
    public class Display {
        private  DisplayImpl impl;
        public Display(DisplayImpl impl) {
            this.impl = impl;
        }
        public void open(){
            impl.rawOpen();
        }
        public void print(){
            impl.rawPrint();
        }
        public void close(){
            impl.rawClose();
        }
        public final void display(){
            open();
            print();
            close();
        }
    }
    
  2. RefinedAbstraction:改善后的抽象化,即改变了类的功能结构的设计.
    package com.liruilong.tx_sjms.Bridge;
    
    /**
     * @Description : 类的功能层次结构
     * @Author: Liruilong
     * @Date: 2019/9/17 2:06
     */
    public class CountDisplay  extends  Display{
    
        public CountDisplay(DisplayImpl impl) {
            super(impl);
        }
        public  void multiDisplay(int times){
            open();
            for(int i = 0; i < times; i++ ){
                print();
            }
            close();
        }
    }
    
  3. Implenment(实现者):类的实现层次的最上层.
    package com.liruilong.tx_sjms.Bridge;
    
    /**
     * @Description :类的实现层次结构
     * @Author: Liruilong
     * @Date: 2019/9/17 2:06
     */
    public abstract class DisplayImpl {
        public abstract void rawOpen();
        public abstract void rawPrint();
        public abstract void rawClose();
    }
    
  4. ConcreteImplementor(具体的实现者):
    package com.liruilong.tx_sjms.Bridge;
    
    /**
     * @Description :类的实现层次结构
     * @Author: Liruilong
     * @Date: 2019/9/17 2:07
     */
    public class StringDisplayImpl extends DisplayImpl {
        private  String string;
        private int width;
    
        public StringDisplayImpl(String string) {
            this.string = string;
            this.width = string.getBytes().length;
        }
        @Override
        public void rawOpen() {
            printLine();
        }
        @Override
        public void rawPrint() {
            System.out.println("|" + string + "|");
        }
        @Override
        public void rawClose() {
            printLine();
        }
        private void printLine(){
            System.out.print("+");
            for (int i = 0; i < width;  i++){
                System.out.print("-");
            }
            System.out.println("+");
        }
    }
    
  5. main
    package com.liruilong.tx_sjms.Bridge;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/17 9:33
     */
    public class Main {
        public static void main(String[] args) {
            Display display = new Display(new StringDisplayImpl("Hello, China."));
            Display display1 = new CountDisplay(new StringDisplayImpl("Hello. word"));
            CountDisplay countDisplay = new CountDisplay(new StringDisplayImpl("Hello, Universe."));
            display.display();
            display1.display();
            countDisplay.multiDisplay(5);
        }
    }
    

     

继承是强关联,委托是弱关联,

第十章,Stratrgy模式

策略模式:整体的替换算法,定义了算法簇,每个方法都对应一个具体的算法,策略模式符合开闭原则,即用户可以在不修改原来的基础上选择算法和行为.定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

嗯,书上的感觉有些复杂,就那Thread类来记忆.

Strategy模式中具体的角色:

  1. Strategy(策略):负责决定实现策略所必须的接口(API),
    @FunctionalInterface
    public interface Runnable {
       
        public abstract void run();
    }
  2. ConcreteStrategy(具体的策略):角色负责实现Strategy角色的接口,
    package com.liruilong.tx_sjms.Stratrgy;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/17 17:02
     */
    public class Stratrgy1 implements Runnable {
        @Override
        public void run() {
            System.out.println("策略二");
        }
    }
    
    
    package com.liruilong.tx_sjms.Stratrgy;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/17 17:09
     */
    public class Stratrgy2 implements Runnable {
        @Override
        public void run() {
            System.out.println("策略二");
        }
    }
    
    
    package com.liruilong.tx_sjms.Stratrgy;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/17 17:10
     */
    public class Stratrgy3 implements Runnable {
        @Override
        public void run() {
            System.out.println("策略三");
        }
    }
  3. Context(上下文):负责选择不同的策略.
    package com.liruilong.tx_sjms.Stratrgy;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/17 17:01
     */
    public class Main {
        public static void main(String[] args) {
            Thread thread = null;
            thread = new Thread(new Stratrgy1(),"策略一");
            thread = new Thread(new Stratrgy2(),"策略二");
            thread = new Thread(new Stratrgy3(),"策略三");
            thread.start();
        }
    }
    

第五部分,一致性:

第十一章   Composite模式

组合模式:将对象组合为树形结构以表示部分于整体的层次关系。能够使内容和内容具有一致性。创建出递归结构的模式。组合模式或复合模式。
在使用组合模式中需要注意叶子对象和组合对象实现相同的接口,即也是组合模式能够将叶子节点和对象节点进行一致性的处理

Composite模式中的角色:

  1. Leaf(树叶):
    package com.liruilong.tx_sjms.Composite;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/23 0:26
     */
    public class File extends Entry{
    
        private String name;
        private int size;
    
        public File(String name, int size) {
            this.name = name;
            this.size = size;
        }
    
        @Override
        public String getName() {
             return name;
        }
    
        @Override
        public int getSize() {
            return size;
        }
    
        @Override
        protected void printList(String string) {
            System.out.println(string + "/" + this);
        }
    }
    

     

  2. Composite(组合容器):
    package com.liruilong.tx_sjms.Composite;
    
    import java.util.ArrayList;
    
    /**
     * @Description : 文件夹类
     * @Author: Liruilong
     * @Date: 2019/9/23 0:26
     */
    public class Directory extends Entry {
    
        private String name;
        private ArrayList<Entry> directory = new ArrayList();
    
        public Directory(String name) {
            this.name = name;
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        @Override
        public int getSize() {
            int size = 0;
            size = directory.stream().map(( entry) -> entry.getSize()).reduce(size,Integer::sum);
            return size;
        }
    
        @Override
        public Entry add(Entry entry ) throws FileTreatementException {
            directory.add(entry);
            return this;
        }
    
        /**
         * @Author Liruilong
         * @Description 显示条目
         * @Date 0:47 2019/9/23
         * @Param [string]
         * @return void
         **/
    
        @Override
        protected void printList(String string) {
            System.out.println(string + "/" + this);
            directory.stream().forEach((entry -> entry.printList(string + "/" + name)));
        }
    }
    

     

  3. Component:
    package com.liruilong.tx_sjms.Composite;
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/23 0:26
     */
    public abstract class Entry  {
        public abstract String getName();
        public abstract  int getSize();
    
    
        public Entry add(Entry entry) throws FileTreatementException{
            throw new FileTreatementException();
        }
        public void printList(){
            printList("");
        }
        protected abstract void  printList(String string);
        public String toString(){
            return getName() + "{" + getSize() + "}";
        }
    
    
    }
    
  4. Client
    package com.liruilong.tx_sjms.Composite;
    
    
    
    /**
     * @Description :
     * @Author: Liruilong
     * @Date: 2019/9/23 0:27
     */
    public class Mian {
        public static void main(String[] args) {
    
    
            System.out.println("Making root entries...");
            Directory rootdor = new Directory("root");
            Directory bindir = new Directory("bin");
            Directory tmpdir = new Directory("tmp");
            Directory usrdir = new Directory("usr");
            rootdor.add(bindir);
            rootdor.add(tmpdir);
            rootdor.add(tmpdir);
            bindir.add(new File("vi", 10000));
            bindir.add(new File("latex", 20000));
            rootdor.printList();
    
            System.out.println("");
            System.out.println("Making user entries...");
            Directory yuki = new Directory("yuki");
            Directory hanako = new Directory("hanako");
            Directory tomura = new Directory("tomura");
            usrdir.add(yuki);
            usrdir.add(tomura);
            yuki.add(new File("diary.html",100));
            yuki.add(new File("Compossite.java",200));
            hanako.add(new File("memo.tex", 300));
            tomura.add(new File("game.doc", 400));
            tomura.add(new File("junk.mail", 500));
            rootdor.printList();
    
        }
    }
    
    
    

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山河已无恙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值