JAVA设计模式学习之Flyweight模式(2)

  

   在我上次写过的关于Flyweight设计模式的文章中,通过Flyweight模式的运用,已经达到了共享元类的目的.但进一步深入探讨上一次的实现过程,在对象的安全性方面将会发现一些问题:

  

   由于Student类中,学生的学号与姓名在整个对象的生命周期中都是不可变的,且每一个学号应只能对应一个姓名,所以我们应该除了在工厂类的静态初始代码块中通过初始化创建Student类的信息之外,应该保证在外界不能随便地再去创建或篡改Student的信息.

   而我们上次的实现当中Student类是一个public的类,StuScore类中就可以随意地进行访问与创建Student对象.这与我们的目的相违背.

   所以应该对上次的设计模式进行改进.在改进后的设计模式中,我们的实现应该做到,只能在工厂类中通过静态代码块创建Student类的实例,且将它们保存在工厂类的Hashtable,且外部将不能篡改Student的信息. 

 

   因为只有工厂类才能创建Student对象,所以可以考虑把其作为工厂类的私有内部类.这样外部将不可能创建Student的实例.但注意到如果只采用此种方式进行实现,外部即StuScore类将不可能通过两个get方法获得学生的姓名与学号信息.此时为了解决这种矛盾,可以采用在外界定义一个Student接口,在接口中定义分别获得学生学号姓名信息的方法,然后由工厂类里的内部类StudentImpl实现Student接口,这样就可完美地实现即只在工厂内内部创建学生对象,又可在外部访问学生对象信息的功能.

   以下是改进后的各个类的代码:

  

StuScore类代码如下:

package org.xqq.flyweight;

 

public class StuScore {

    private Student student;

    private String course;

    private int score;

   

    public StuScore(String stuNum,String course,int score)

    {

       this.course=course;

       this.score=score;

       this.student=StudentFactory.getStudent(stuNum);

    }

   

    public String getCourse() {

       return course;

    }

    public int getScore() {

       return score;

    }

   

    public String getStuName()

    {

       return student.getStuName();

    }

    public String getStuNum()

    {

       return student.getStuNum();

    }

}

 

Student接口代码如下

package org.xqq.flyweight;

 

//Student接口定义取得学生各种信息的行为

public interface Student {

    String getStuName();//获取学生姓名

    String getStuNum();//获取学生学号

}

 

工厂类StudentFactory的代码如下:

package org.xqq.flyweight;

 

import java.util.Hashtable;

 

public class StudentFactory {

   

    private static Hashtable stuTable=new Hashtable();

   

    static

    {

       StudentFactory factory=new StudentFactory();

       stuTable.put("AP0501",

              factory.new StudentImpl("AP0501","张三"));

       stuTable.put("AP0502",

              factory.new StudentImpl("AP0502","李四"));

       stuTable.put("AP0503",

              factory.new StudentImpl("AP0503","王五"));

    }

    //内部类StudentImpl包括学生的各属性,实现了Student接口

    private class StudentImpl implements Student

    {

       private String stuName;//学生姓名

       private String stuNum;//学生学号

       public StudentImpl(String stuName, String stuNum) {

           this.stuName = stuName;

           this.stuNum = stuNum;

       }

       public String getStuName() {

           // TODO Auto-generated method stub

           return stuName;

       }

       public String getStuNum() {

           // TODO Auto-generated method stub

           return stuNum;

       }

    }

    //从工厂类中取得特定的学生信息

    public static Student getStudent(String stuNum)

    {

       Student student=(Student) stuTable.get(stuNum);

       return student;

    }

}

 

然后利用StudentTest的代码进行测试,可得到与上篇文章一样的结果,于是经过改进的FlyWeight设计模式得以实现.

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值