我有一个Dog
个对象,每个Dog
都有一个colour
和一个photoUrl
,这是它的照片在互联网上的位置。
class Dog {
private String colour;
private String photoUrl;
private Bitmap photo;
public Dog(String colour, String photoUrl){
this.colour = colour;
this.photoUrl = photoUrl;
}
}
我想下载照片并将其存储在磁盘上。我应该在Dog.download()
或其他地方实现下载功能,比如在一个名为FileDownloader
的新类中?这个问题有设计模式吗?
答案 0 :(得分:6)
下载文件是一个跨领域的问题,与狗没有特别的关系。因此,我建议您在Dog之外存在一个DownloadUtil(或类似的东西),您可以在其中实现下载。
答案 1 :(得分:2)
我同意也许狗不是最适合它的地方。也许如果你有其他可下载的对象或计划,你可以做...
public interface Downloadable { public String getUrl(); }
public class Dog implements Downloadable...
public class Downloader { public Bitmap download(Downloadable obj); }
答案 2 :(得分:2)
目前为止好几个答案。但是,我有一些意见:
所以,可能一个好主意是复制一些关于此的春天概念。请参阅:http://static.springsource.org/spring/docs/3.0.6.RELEASE/spring-framework-reference/html/resources.html
class Dog {
private final String color;
private final Photo photo;
public Dog(final String color, final Photo photo) {
this.color = color;
this.photo = photo;
}
}
class Photo {
private final Resource resource;
public Photo(final String path) throws MalformedURLException {
this.resource = new UrlResource(path);
}
public String getUrl() {
return resource.getUrl();
}
public Bitmap getBitmap() {
final InputStream is = resource.getInputStream();
// transform is to Bitmap
// cache the result
return bitmap;
}
}
class UrlResource implements Resource {
private final URL url;
public UrlResource(final String path) throws MalformedURLException {
Assert.notNull(path, "Path must not be null");
this.url = new URL(path);
}
@Override
public InputStream getInputStream() throws IOException {
final URLConnection con = this.url.openConnection();
con.setUseCaches(false);
try {
return con.getInputStream();
} catch (final IOException ex) {
// Close the HTTP connection (if applicable).
if (con instanceof HttpURLConnection) {
((HttpURLConnection) con).disconnect();
}
throw ex;
}
}
@Override
public String getUrl() {
return url.toString();
}
}
interface Resource {
InputStream getInputStream() throws IOException;
String getUrl();
}
// Multi thread approach.... just the idea... it won't compile
interface AsyncResource extends Resource {
Future<Data> getData();
}
// On Photo
public Photo(final AsyncResource resource) {
this.resource = resource;
}
public Bitmap getBitmap() {
final Future<Data> data = resource.getData();
// call data.get(), Hopefully won't block
// transform is to Bitmap
// cache the result
return bitmap;
}
class AsyncResourceProvider {
final ExecutorService threadExecutor = Executors.newFixedThreadPool(10);
AsyncResource schedule(String path) {
// submit the taks and return the future
}
}
// Create a Dog and a Photo
AsyncResource resource = asyncResourceProvider.schedule(path);
Dog d = new Doc("black", new Photo(resource));
答案 3 :(得分:1)
我看到两个选项:
a)如果层次结构允许,则创建具有该功能的抽象超类。这很容易,但很僵硬。
b)更灵活的方法是在Downloader界面中委派它。每个对象都将在外部提供(setDownloader(Downloader downloader)
)。也许允许在对象中自动创建的默认HttpDownloader。更灵活,更轻松的测试,但还有一些工作。
最后,您应该评估您的问题并确定额外的工作是否值得将来需要该功能的风险。
答案 4 :(得分:1)
创建另一个类Downloader,在其构造函数中使用一个接口Animal。然后它也适用于猫...
答案 5 :(得分:1)
拥有Dog.download()。但是让Dog.download()转而调用一个fileDownloader.download(),就像Chris指出的那样。
我不确定你是否可以将其称为设计模式,但这种做法称为delegation
<小时/>
并且不要将Dog对象传递给fileDownloader.download(),而只传递它应该关注的URL。除了下载逻辑更改之外,fileDownloader不需要因任何原因而更改。另请参阅Single Responsibility principle