我正在尝试决定构建一些代码的最佳方法。我承认这可能是落伍的,并且变成了更具学术性而非实际的东西。有时你无法帮助自己。
让我设想一个简单的例子:
假设您有类/接口,例如:
interface IProcessedPhoto { }
interface IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes);
void Alter(IProcessedPhoto processedPhoto);
}
class PhotoProcessedWithAMethod : IProcessedPhoto { }
class PhotoProcessedWithBMethod : IProcessedPhoto { }
class AProcessor : IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes); // Returns PhotoProcessedWithAMethod
void Alter(IProcessedPhoto processedPhoto)
{
var casted = processedPhoto as PhotoProcessedWithAMethod;
// a "B" would crash here.
}
}
class BProcessor : IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes); // Returns PhotoProcessedWithBMethod
void Alter(IProcessedPhoto processedPhoto)
{
var casted = processedPhoto as PhotoProcessedWithBMethod;
// an "A" would crash here.
}
}
class Algorithm
{
void DoStuff()
{
var processor = ProcessorFactory.CreateProcessor(//stuff);
var processedPhoto = processor.ProcessPhoto(new byte[100]);
processor.Alter(processedPhoto);
}
}
所以基本上我希望DoStuff()方法创建一种图像处理器,并调用相应的Process方法。但是,尽管界面建议,Process仅适用于相应类型的IProcessedPhoto(A和B照片不可互换,它们只有类似的方法名称)。我的真实代码更复杂,因为每个处理器都有几个特定于它们的类,并且不可互换,但我想执行与模板方法相同的“逻辑”操作集。
var artifactA = processor.DoA();
var artifactB = processor.DoB();
var final = processor.Process(artifactA, artifactB);
我希望能够解释它。
答案 0 :(得分:1)
在我看来,您的IProcessedPhoto
/ IPhotoProcessor
抽象过于笼统,至少对于您描述的目的而言。
您可以为每个照片类和处理器创建派生接口(例如IProcessedPhotoA
/ IPhotoProcessorA
,B
也相同),并调整您的代码,以便只有那些照片实现所需的接口(A
或B
)将传递给给定的处理器。
我不确定这是否是整个代码库的最佳解决方案(我看不到)。我的建议基于你的帖子:
然而,尽管界面建议,Process仅适用于相应类型的IProcessedPhoto(A和B照片不可互换,它们只有类似的方法名称)
如果PhotoProcessor
使用它们是不可互换的,那么您的代码不应该这样对待它们。
答案 1 :(得分:1)
我很想将Alter方法放在IProcessedPhoto界面上,然后返回一个可以正确改变已处理照片的实现。请注意,您也可以将其连接到处理器,并在需要时使用它的方法(未显示)。
public enum PhotoProcessingMethod { A, B }
public interface IProcessedPhoto
{
void Alter();
}
public AProcessedPhoto : IProcessedPhoto
{
...
public void Alter()
{
... alter an A...
}
}
public BProcessedPhoto : IProcessedPhoto
{
...
public void Alter()
{
... alter a B...
}
}
public interface IPhotoProcessor
{
IProcessedPhoto Process(byte[] bytes, PhotoProcessingMethod method);
}
public class PhotoProcessor : IPhotoProcessor
{
public IProcessedPhoto Process(byte[] bytes, PhotoProcessingMethod method)
{
IProcessedPhoto photo;
switch (method)
{
case PhotoProcessingMethod.A:
photo = new AProcessedPhoto(bytes);
break;
case PhotoProcessingMethod.B:
photo = new BProcessedPhoto(bytes);
break;
}
...
return photo;
}
}
用作:
var processor = new PhotoProcessor();
var photoA = processor.Process( bytes, PhotoProcessingMethod.A );
photoA.Alter();
答案 2 :(得分:1)
您可以使用泛型将IProcessedPhoto
的特定实现绑定到IPhotoProcessor
:
interface IPhotoProcessor<TProcessedPhoto>
where TProcessedPhoto: IProcessedPhoto {
TProcessedPhoto Process(byte[] bytes);
void Alter(TProcessedPhoto processedPhoto);
}
...
class AProcessor : IPhotoProcessor<PhotoProcessedWithAMethod> { ... }
class BProcessor : IPhotoProcessor<PhotoProcessedWithBMethod> { ... }
缺点是您的工厂也需要这些信息:
ProcessorFactory.CreateProcessor<PhotoProcessedWithAMethod>(/*stuff*/);