Java类装饰自己

时间:2017-01-17 11:21:40

标签: java caching decorator

我认为我在Java中重新发明缓存,但有一点我不能进一步发展。 如果这个问题的答案在Stackoverflow上的任何地方,我可能在搜索时没有理解它,或者没有理解所需的复杂性并且搜索了更简单的方法。

简短我要做的事:在Object上调用一个方法。该对象应加载图片并将其存储为图像。然后它应该使用Decorator进行自我修饰,以便下次调用的方法只返回没有IO操作的图像。

我的Interace Picture Interafce很简单:

import java.awt.*;

public interface PictureInterface {

    public Image getImage();

}

我的装饰师看起来像这样:

import java.awt.*;

public class PictureDecorator implements PictureInterface {

    private final Picture p;

    public PictureDecorator(Picture p){
        this.p = p;
    }

    public Image getImage(){
        return this.p.pipeImage();
    }

}

它保存了一张图片并在getImage()调用图片管道图片 - 图片"真实" getImage()

最后但并非最不重要的是图片类:

import java.awt.Image;

public class Picture implements PictureInterface{

    private final String path;
    private final Image image;

    public Picture(String path){
        this.path = path;

    }

    private void loadImage(){
        this.image = /*IO Magic Loading the Image from path*/
    }

    public Image getImage() {
        loadImage();
        /*Decorate Yourself with Picture Decorator*/
        return /*Decorator.getImage*/;
    }

    Image pipeImage(){
        return this.image;
    }
}

如果调用了getImage,我希望Picture自己装饰并调用Decorators getImage并且大多数importent覆盖它的旧引用(Java是按值调用的,这是我被困在的地方)所以进一步的getImage调用Decorator调用getImage方法。

作为一个额外的问题,我认为我从装饰师那里获取法师不是最佳做法,提示欢迎^^

修改

添加一个东西:我已经想过如果这是不可能的:那将是什么"更聪明":去if(image==NUll)或者做一个decorateYourself()函数,其中加载图像并返回装饰器在Picture和Decorator中它只返回自身,将其应用于Image var,然后调用getImage,如:

ImageInterface x = new Image("path);

x = x.decorateYourself()
Image i = x.getImage()

这种方式我只会做一个方法调用来返回装饰器本身,但我必须调用这两种方法......

1 个答案:

答案 0 :(得分:2)

  

如果调用了getImage,我希望Picture自己装饰并调用   装饰器getImage和大多数importent覆盖旧的refference   (Java是按价值调用,这是我被困的地方)所以进一步   getImage调用装饰器调用getImage方法。

装饰师不会这样工作。
使用装饰器,您希望增强或减少现有类的行为而不会侵入此类:无需修改 因此装饰器实例装饰一个对象,该对象必须与装饰器类共享一个常见类型和一个常用方法。

此外我认为你不需要使用装饰器。 在这里你不装饰图片,但是如果之前已经执行过,你可以绕过它的加载。

我认为使用代理决定是否必须加载从缓存中获取资源的代理会更合适 别担心,它不会改变你引入的类中的很多东西:仍然需要接口,常用方法和对象包装。

在您的情况下,PictureInterface是代理类和提供常用方法的代理主题类之间的通用类型:getImage()

import java.awt.*;

   public interface PictureInterface {        
        public Image getImage();        
    }

PictureProxy,代理类可以实现PictureInterface作为任何PictureInterface个实例。

PictureProxy应该负责检查它是否缓存了之前加载图像的结果。这是它返回它的情况。否则,它会在保留的getImage()实例上调用Picture,并缓存结果。

import java.awt.*;

public class PictureProxy implements PictureInterface {

    private final Picture p;
    private final Image image;

    public PictureProxy(Picture p){
        this.p = p;
    }

    public Image getImage(){
        if (image != null){
           return image;
        }
        image = p.getImage();
        return image;
    }
}

Picture类在执行getImage()时不应该知道代理。 它是处理缓存状态的代理类。

import java.awt.Image;

public class Picture implements PictureInterface{

    private final String path;
    private final Image image;

    public Picture(String path){
        this.path = path;   
    }

    private void loadImage(){
        this.image = /*IO Magic Loading the Image from path*/
    }

    public Image getImage() {
        loadImage();
        return image;
    }           
}

从类的客户端你可以做类似的事情:

Picture picture = new PictureProxy(new Picture("picturePath"));
Image img = picture.getImage(); // load the image from Picture the first time and get it
Image img = picture.getImage(); // get it from the PictureProxy cache