JavaSE:设计模式详解

设计模式详解(重点)

1.  单例设计模式

      单例设计模式主要分为: 饿汉式  和 懒汉式, 懒汉式需要对多线程进行同步处理

      代码:https://www.cnblogs.com/JasperZhao/p/14953270.html

 

2.  普通工厂模式

      <1>  基本概念

            普通工厂模式:建立一个工厂类,对实现了同一接口的不同实现类,进行实例的创建 

                   (普通工厂 -----> 造对象)

      <2>  类图结构

          

           代码:

            https://www.cnblogs.com/JasperZhao/p/14954208.html

 

       <3>  主要缺点

            在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,并且可能出现空指针异常。 

 

3.  多个工厂方法模式

      <1>  类图结构

          

       <2>  代码: (在普通工厂模式的基础上,在SendFactory类中添加 produceMail() 和 produceSms()方法  )

           

 

 

           在测试类 SendFactory.java 的main()方法中:


                                  

       <2>  主要缺点

            在多个工厂方法模式中:为了能够正确创建对象,先需要创建工厂类的对象,才能调用工厂类中的生产方法。

 

4.  静态工厂方法模式

      <1>  类图结构

 

           

       可见, produceMail() 和 produceSms()方法被下划线修饰了

       下划线在类图中,表示静态的成员 

      <2>  代码

 

 

 

 

      <3>  实际意义

            工厂方法模式(以上三个模式的统称)适合:凡是出现了大量的产品,需要创建且具有共同的接口时,

            可以通过工厂方法模式进行创建

 

      <4>  主要缺点

            工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序生产新的产品,

            就必须对工厂类的代码进行修改,这就违背了开闭原则

            (因此,诞生了抽象工厂模式)

 

5.  抽象工厂模式

      <1>  类图结构

      

 

 

       

      <2>  优点:严格遵循了开闭原则

      <3>  代码

      

 

 

       

 

 

       main:

      

 

 

 

 

 

5.  装饰器模式

      <1>  基本概念

            装饰器模式就是给一个对象动态地增加一些功能,要求装饰对象 和 被装饰对象实现同一个接口,

            装饰对象持有被装饰对象的实例

      <2>  类图结构

            

 

              Source: 被装饰类

              Decorator: 装饰类

 

      <3>  代码

基类

       public interface Sourceable {

        // 自定义抽象方法

        void method();

      }

被装饰类

      public class Source implements Sourceable {

        @Override

        public void method(){

          print("素颜美可以如此之美!");

        }

      }

装饰类

      public class Decorator implements Sourceable {

        private Sourceable source;



        public Decorator (Sourceable source) {

          this.source = source;

        }



        @Override

        public void method() {

          source.method();  // 保证原有功能不变
          println("化妆之后你会更美!"); // 在此基础上,增加新的功能
        }

      }

 测试类

public class SourceableTest {

  main() {

// <1>不使用装饰类,只实现 "素颜"功能     Sourceable sourceable
= new Source();     sourceable.method(); // output: "素颜美可以如此之美!"

// <2>使用装饰类, 实现"素颜"和"化妆"功能     Sourceable sourceable1 = new Decorator(sourceable);     sourceable1.method(); // output: "素颜" "化妆"   } }

 

       <4>  实际意义

            可以实现一个类功能的拓展

            可以动态地增加功能,并且还能动态撤销 (继承是做不到的)

            缺点:产生过多相似的对象,不易排错

 

6.  代理模式

      <1>  基本概念

            代理模式:就是找一个代理类,替原对象进行一些操作

            比如我们在租房子的时候找中介,再如我们打官司需要请律师,中介和律师在这里就是我们的代理

 

      <2>  类图结构

          

 

 

 

       <3>  在装饰器模式的Sourceable.java 和 Source.java 的基础上, 将Decorator.java 替换为 Proxy.java (代理类):

  

        public class Proxy implements Sourceable {

            private Source source;


            public Proxy(){

              source = new Source();
            }


            @Override
            public void method(){

              source.method();
              print("我跟装饰器模式,其实是不一样的!");
            }
          }
 

测试类

    public class SourceableTest {
      main() {
        Sourceable sourceable2 = new Proxy();
        sourceable2.method(); // "素颜"    "我跟装饰器模式,其实是不一样的" 
      }
    }

       <4>  实际意义

            1.  如果在使用的时候,需要对原有的方法进行改进,可以采用一个代理类,调用原有方法,

                 并且对产生的结果进行控制,这种方式就是代理模式

            2.  使用代理模式,可以将功能划分地更加清晰,有助于后期维护

 

      <4>  代理模式和装饰器模式的比较

            1.  装饰器模式:通常的做法是将原始对象作为一个参数,传给装饰者的构造器

                  代理模式:通常在一个代理类中,创建一个被代理类的对象

            2.  装饰器模式:关注于在一个对象上动态地添加方法

                代理模式:关注于控制对对象的访问  

 

7.  模板方法模式

      <1>  基本概念

            模板方法模式:主要指一个抽象类中封装了一个固定流程,流程中的具体步骤,

            可以由不同子类进行不同的实现,通过抽象类,让固定的流程产生不同的结果

      <2>  类图结构

             (斜体在类图中表示:抽象的) 

            

 

       <3>  代码

基类      

 1           public abstract class AbstractCalculator {
 2 
 3 
 4 
 5         // 将参数指定的表达式,按照参数指定的规则 (+ -) ,进行切割,并返回计算结果
 6         // 例如: exp 为 1 + 1,  op 为 +
 7         public int splitExpression(String exp, String op) {
 8 
 9           String[] sArr = exp.split(op);
10           return calculate( Integer.parseInt(sArr[0]), Integer.parseInt(sArr[1]) );
11           // 相当于 return calculate (1,1)
12         }
13 
14 
15         // 自定义抽象方法,实现运算
16         public abstract int calculate (int ia, int ib);
17       }

子类一:

public class Plus extends AbstractCalculator{

  @Override

  public int calculate (int ia, int ib){

    return ia + ib;
  }

}

子类二:

public class Minus extends AbstractCalculator{

  @Override

  public int calculate (int ia, int ib){

    return ia - ib;
  }

}

测试类

 1 public class AbstractCalculatorTest {
 2 
 3   main() {
 4 
 5     AbstractCalculator ac = new Plus();
 6 
 7     int res = ac.splitExpression ("1+1","\\+");
 8 
 9     print("运算结果为:" + res);   // 2
10   }
11 
12 }

       <4>  实际意义

          1.  将多个子类共有,且逻辑基本相同的内容,提取出来,实现代码复用

          2.  不同的子类,实现不同的效果,形成多态,有助于后期维护

 

8. 常用的设计原则和设计模式 - 练习题

 

 

 

 

 

posted @ 2021-06-28 15:58  Jasper2003  阅读(66)  评论(0编辑  收藏  举报