设计模式

1.工厂模式(利用反射实现)

demo1:这是最原始的工厂方法

 1 interface fruit{
 2     public abstract void eat();
 3 }
 4  
 5 class Apple implements fruit{
 6     public void eat(){
 7         System.out.println("Apple");
 8     }
 9 }
10  
11 class Orange implements fruit{
12     public void eat(){
13         System.out.println("Orange");
14     }
15 }
16 
17 // 构造工厂类
18 // 也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了
19 class Factory{
20     public static fruit getInstance(String fruitName){
21         fruit f=null;
22         if("Apple".equals(fruitName)){
23             f=new Apple();
24         }
25         if("Orange".equals(fruitName)){
26             f=new Orange();
27         }
28         return f;
29     }
30 }
31 
32 public class Hello18{
33     public static void main(String[] a){
34         fruit f=Factory.getInstance("Orange");
35         f.eat();
36     }
37  
38 }
View Code

demo2:利用反射实现的工厂方法;当我们在添加一个子类的时候,就需要修改工厂类了。如果我们添加太多的子类的时候,改的就会很多。

 1 class Factory1{
 2     public static fruit getInstance(String ClassName){
 3         fruit f=null;
 4         try{
 5             f=(fruit)Class.forName(ClassName).newInstance();
 6         }catch (Exception e) {
 7             e.printStackTrace();
 8         }
 9         return f;
10     }
11 }
12 
13 public class Hello19{
14     public static void main(String[] a){
15         fruit f=Factory1.getInstance("Reflect.Apple");
16         if(f!=null){
17             f.eat();
18         }
19     }
20 }
View Code

上面的代码虽然可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道一个接口有多少个可以使用的子类,所以我们通过

属性文件的形式配置所需要的子类。

 1 首先创建一个fruit.properties的资源文件,
 2 
 3 内容为:
 4 apple=Reflect.Apple
 5 orange=Reflect.Orange
 6  */
 7 //操作属性文件类
 8 class init{
 9   public static Properties getPro() throws FileNotFoundException, IOException{
10       Properties pro=new Properties();
11       File f=new File("fruit.properties");
12       if(f.exists()){
13           pro.load(new FileInputStream(f));
14       }else{
15           pro.setProperty("apple", "Reflect.Apple");
16           pro.setProperty("orange", "Reflect.Orange");
17           pro.store(new FileOutputStream(f), "FRUIT CLASS");
18       }
19       return pro;
20   }
21 }
22 
23 public class Hello20{
24   public static void main(String[] a) throws FileNotFoundException, IOException{
25       Properties pro=init.getPro();
26       fruit f=Factory1.getInstance(pro.getProperty("apple"));
27       if(f!=null){
28           f.eat();
29       }
30   }
31 }
View Code

类的生命周期
在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。
类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。 但是同一个类只会被类装载器装载以前
链接就是把二进制数据组装为可以运行的状态。
链接分为校验,准备,解析这3个阶段校验一般用来确认此二进制文件是否适合当前的JVM(版本),
准备就是为静态成员分配内存空间,。并设置默认值
解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)
完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。
当没有任何引用指向Class对象时就会被卸载,结束类的生命周期将反射用于工厂模式

 

2.单例模式(double check问题)

http://www.cnblogs.com/limingluzhu/p/5156659.html

 

3.原型模式(注意浅克隆和深克隆的区别)

demo1:传统克隆模式(即浅克隆)步骤

 (1)实现Clonable接口
 (2)重写clone()方法
 (3)返回super.clone()

 1 public class Prototype implements Cloneable {
 2     private String name;
 3 
 4     public String getName() {
 5         return name;
 6     }
 7 
 8     public void setName(String name) {
 9         this.name = name;
10     }
11     
12     @Override
13     public Object clone(){
14         try {
15             return super.clone();
16         } catch (Exception e) {
17             // TODO: handle exception
18             e.printStackTrace();
19             return null;
20         }
21     }
22     
23 }
24 
25 public class ConcretePrototype extends Prototype {
26     public ConcretePrototype(String name){
27         setName(name);
28     }
29 }
30 
31 public class Test {
32     public static void main(String[] args) {
33         
34         Prototype pro=new ConcretePrototype("prototype");
35         Prototype pro2=(Prototype)pro.clone();
36         System.out.println(pro.getName());
37         System.out.println(pro2.getName());
38         
39     }
40 }
View Code

demo2:浅克隆

浅拷贝存在对象属性拷贝不彻底的问题,如果是基本类型变量,则拷贝其值,如果是实例对象,则拷贝引用地址,也就是说
新拷贝出来对象与原有对象共享该实例变量,不受访问权限的限制。
demo3:深克隆

步骤:

(1)实现java.io.Serializable接口

(2)序列化与反序列化

下面是序列化与反序列化核心方法:

 1 public Object getObject(){
 2         try {
 3             ByteArrayOutputStream bos = new ByteArrayOutputStream();  
 4             ObjectOutputStream oos = new ObjectOutputStream(bos);  
 5             oos.writeObject(this);  
 6             ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
 7             ObjectInputStream ois = new ObjectInputStream(bis);  
 8             return ois.readObject();  
 9         } catch (Exception e) {
10             // TODO: handle exception
11             e.printStackTrace();
12             return null;
13         }
14     }
View Code

transient是瞬态变量,不进行序列化变量


序列化时如果是文件类型就用FileInputStream和FileOutputStream,如果是直接的对象则用
ByteArrayInputStream和ByteArrayOutputStream

 

posted @ 2016-08-27 14:52  ﹍。GG╊棒°  阅读(108)  评论(0)    收藏  举报