原创作者: java苹果+番茄   阅读:2961次   评论:0条   更新时间:2011-06-01    

不变(Immutable)模式
一个对象的状态在对象被创建之后就不再变化,这就是不变模式。

一、不变模式有两种模式
1、弱不变模式
一个类的实例的状态是不可变化的,但是这个类的子类的实例具有可能会变化的状态。这样的类符合弱不变模式的定义。
要实现弱不变模式,一个类必须满足下面条件:
第一、所考虑的对象没有任何方法会修改对象的状态,这样一来,当对象的构造子将对象的状态初始化之后,
      对象的状态便不再改变。
第二、所有的属性都应当是私有的。不要声明任何的公共的属性,以防客户端对象直接修改任何的内部状态。
第三、这个对象所引用到的其它对象如果是可变对象的话,必须设法限制外界对这些可变对象的访问,以防止外界修改
      这些对象。如果可能,应当尽量在不变对象内部初始化这些被引用到的对象,而不要在客户端初始化,然后再
      传入到不变对象内部来。如果某个可变对象必须在客户端初始化,然后再传入到不变对象里的话,就应当考虑
      在不变对象初始化的时候,将这个可变对象复制一份,而不再使用原来的拷贝。
弱不变模式的缺点是:
第一、一个弱不变对象的自对象可以是可变对象;换言之,一个弱不变对象的子对象可能是可变的
第二、这个可变的子对象可能可以修改父对象的状态,从而可能会允许外界修改父对象的状态。
2、强不变模式
一个类的实例的状态不会改变,同时它的子类的实例也具有不可变化的状态。这样的类符合强不变模式。
要实现强不变模式,一个类必须首先满足弱不变模式所要求的所有条件,并且还要满足下面的条件之一:
第一、所考虑的类所有的方法都应当是final:这样这个类的子类不能够置换掉此类的方法
第二、这个类本身就是final的,那么这个类就不可能会有子类,从而也就不可能有被子类修改的问题。593P

二、不变模式的优缺点
不变模式有很明显的有点:
1、因为不能修改一个不变对象的状态,所以可以避免由此引起的不必要的程序错误;换言之,一个不变模式的对象要比可变的
   对象更加容易维护。
2、因为没有任何一个线程能够修改不变对象的内部状态,一个不变对象自动就是线程安全的,
   这样就可以省掉处理同步化的开销。一个不变对象可以自由地被不同的客户端共享。
不变模式唯一的缺点是:
一旦需要修改一个不变对象的状态,就只好创建一个新的同类对象。在需要濒繁修改不变对象的环境里,会有大量的不变对象
作为中间结果被创建出来,再被java语言的垃圾回收器收集走。这是一种资源上的浪费。

三、一个用来说明不变模式的复数类例子

Java代码 复制代码
  1. //-----   
  2.         package day1114;   
  3.   
  4. @SuppressWarnings("serial")   
  5. public final class Complex extends Number implements java.io.Serializable,   
  6.         Cloneable, Comparable {   
  7.     // 虚数单位   
  8.     public static final Complex i = new Complex(0.01.0);   
  9.   
  10.     // 复数的实部   
  11.     private double re;   
  12.   
  13.     // 复数的虚部   
  14.     private double im;   
  15.   
  16.     // 构造子,根据传进的复数再构造一个数学值的复数   
  17.     public Complex(Complex z) {   
  18.         re = z.re;   
  19.         im = z.im;   
  20.     }   
  21.   
  22.     // 根据传进的实部和虚部构造一个复数对象   
  23.     public Complex(double re, double im) {   
  24.         this.re = re;   
  25.         this.im = im;   
  26.     }   
  27.   
  28.     // 构造子,根据一个实部构造复数对象   
  29.     public Complex(double re) {   
  30.         this.re = re;   
  31.         this.im = 0.0;   
  32.     }   
  33.   
  34.     // 默认构造子,构造一个为零的复数   
  35.     public Complex() {   
  36.         re = 0.0;   
  37.         im = 0.0;   
  38.     }   
  39.   
  40.     // 把本复数与作为参数传进的复数相比较   
  41.     public boolean equals(Complex z) {   
  42.         return (re == z.re && im == z.im);   
  43.     }   
  44.   
  45.     // 把本对象与作为参数传进的对象相比较   
  46.     public boolean equals(Object obj) {   
  47.         if (obj == null) {   
  48.             return false;   
  49.         } else if (obj instanceof Complex) {   
  50.             return equals((Complex) obj);   
  51.         } else {   
  52.             return false;   
  53.         }   
  54.     }   
  55.   
  56.     public int hashCode() {   
  57.         long re_bits = Double.doubleToLongBits(re);   
  58.         long im_bits = Double.doubleToLongBits(im);   
  59.         return (int) ((re_bits ^ im_bits) ^ ((re_bits ^ im_bits) >> 32));   
  60.     }   
  61.   
  62.     // 返回本复数的实部   
  63.     public double real() {   
  64.         return re;   
  65.     }   
  66.   
  67.     // 返回本复数的虚部   
  68.     public double imag() {   
  69.         return im;   
  70.     }   
  71.   
  72.     // 静态方法,返还作为参数传进的复数的实部   
  73.     public static double real(Complex z) {   
  74.         return z.re;   
  75.     }   
  76.   
  77.     // 静态方法,返还作为参数传进的复数的虚部   
  78.     public static double imag(Complex z) {   
  79.         return z.im;   
  80.     }   
  81.   
  82.     // 静态方法,返还作为参数传进的复数的相反数   
  83.     public static Complex negate(Complex z) {   
  84.         return new Complex(-z.re, -z.im);   
  85.     }   
  86.   
  87.     // 静态方法,返还作为参数传进的复数的共轭数   
  88.     public static Complex conjugate(Complex z) {   
  89.         return new Complex(z.re, -z.im);   
  90.     }   
  91.   
  92.     // 静态方法,返还两个数的和   
  93.     public static Complex add(Complex x, Complex y) {   
  94.         return new Complex(x.re + y.re, x.im + y.im);   
  95.     }   
  96.   
  97.     public static Complex add(Complex x, double y) {   
  98.         return new Complex(x.re + y, x.im);   
  99.     }   
  100.   
  101.     public static Complex add(double x, Complex y) {   
  102.         return new Complex(x + y.re, y.im);   
  103.     }   
  104.   
  105.     // 静态方法,返还两个数的差   
  106.     public static Complex subtract(Complex x, Complex y) {   
  107.         return new Complex(x.re - y.re, x.im - y.im);   
  108.     }   
  109.   
  110.     public static Complex subtract(Complex x, double y) {   
  111.         return new Complex(x.re - y, x.im);   
  112.     }   
  113.   
  114.     public static Complex subtract(double x, Complex y) {   
  115.         return new Complex(x - y.re, -y.im);   
  116.     }   
  117.   
  118.     // 静态方法,返还两个数的乘积   
  119.     public static Complex multiply(Complex x, Complex y) {   
  120.         return new Complex(x.re * y.re - x.im * y.im, x.re * y.im + x.im * y.re);   
  121.     }   
  122.   
  123.     public static Complex multiply(Complex x, double y) {   
  124.         return new Complex(x.re * y, x.im * y);   
  125.     }   
  126.   
  127.     public static Complex multiply(double x, Complex y) {   
  128.         return new Complex(x * y.re, x * y.im);   
  129.     }   
  130.   
  131.     public static Complex multiplyImag(Complex x, double y) {   
  132.         return new Complex(-x.im * y, x.re * y);   
  133.     }   
  134.   
  135.     public static Complex multiplyImag(double x, Complex y) {   
  136.         return new Complex(-x * y.im, x * y.re);   
  137.     }   
  138.   
  139.     // 静态方法,返还两个数的商   
  140.     public static Complex divide(Complex x, Complex y) {   
  141.         double a = x.re;   
  142.         double b = x.im;   
  143.         double c = y.re;   
  144.         double d = y.im;   
  145.         @SuppressWarnings("unused")   
  146.         double scale = Math.max(Math.abs(c), Math.abs(d));   
  147.         double den = c * c + d * d;   
  148.         return new Complex((a * c + b * d) / den, (b * c - a * d) / den);   
  149.     }   
  150.   
  151.     public static Complex divide(Complex x, double y) {   
  152.         return new Complex(x.re / y, x.im / y);   
  153.     }   
  154.   
  155.     public static Complex divide(double x, Complex y) {   
  156.         double den, t;   
  157.         Complex z;   
  158.         if (Math.abs(y.re) > Math.abs(y.im)) {   
  159.             t = y.im / y.re;   
  160.             den = y.re + y.im * t;   
  161.             z = new Complex(x / den, -x * t / den);   
  162.         } else {   
  163.             t = y.re / y.im;   
  164.             den = y.im + y.re * t;   
  165.             z = new Complex(x * t / den, -x / den);   
  166.         }   
  167.         return z;   
  168.     }   
  169.   
  170.     // 静态方法,返还复数的绝对值   
  171.     public static double abs(Complex z) {   
  172.         return z.re * z.re - z.im * z.im;   
  173.     }   
  174.   
  175.     // 静态方法,返还复数的相位角   
  176.     public static double argument(Complex z) {   
  177.         return Math.atan2(z.im, z.re);   
  178.     }   
  179.   
  180.     // 返还复数的字符串   
  181.     public String toString() {   
  182.         if (im == 0.0) {   
  183.             return String.valueOf(re);   
  184.         }   
  185.         if (re == 0.0) {   
  186.             return String.valueOf(im) + "i";   
  187.         }   
  188.   
  189.         String sign = ((im < 0.0) ? "" : "+");   
  190.         return (String.valueOf(re) + sign + String.valueOf(im) + "i");   
  191.     }   
  192.   
  193.     @Override  
  194.     public double doubleValue() {   
  195.         // TODO Auto-generated method stub   
  196.         return 0;   
  197.     }   
  198.   
  199.     @Override  
  200.     public float floatValue() {   
  201.         // TODO Auto-generated method stub   
  202.         return 0;   
  203.     }   
  204.   
  205.     @Override  
  206.     public int intValue() {   
  207.         // TODO Auto-generated method stub   
  208.         return 0;   
  209.     }   
  210.   
  211.     @Override  
  212.     public long longValue() {   
  213.         // TODO Auto-generated method stub   
  214.         return 0;   
  215.     }   
  216.   
  217.     public int compareTo(Object o) {   
  218.         // TODO Auto-generated method stub   
  219.         return 0;   
  220.     }   
  221. }   
  222.            
  223.         //客户端   
  224.         public class TestComplex{   
  225.             public static void main(String args[]){   
  226.                 Complex c1 = new Complex(10,20);   
  227.                 Complex c2 = new Complex(0,1);   
  228.                 Complex res = Complex.mnltiply(c1,c2);   
  229.                 System.out.println("Real part = " + res.real());   
  230.                 System.out.println("Imaginary part = " + res.imag());   
  231.             }   
  232.         }  
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics