C级铸造设计
本文关键字: | 更新日期: 2023-09-27 18:29:03
假设我有一个将文本写入文件的程序(不是真的,但这更容易解释)。我希望每个文件类型都有一个单独的类,比如从FileTypeMaster继承的PdfType和WordType。
FileTypeMaster (base)
-PdfType : FileTypeMaster
-WordType : FileTypeMaster (same methods as pdftype but works different)
现在来谈谈真正的问题。。。我希望用户在程序启动时决定使用哪种类型。如果他想要Pdf或Word,方法调用应该看起来是一样的(因为Word是新的,而且这个程序以前只是针对Pdf的)。
它应该如何工作,例如pdf:
static FileTypeMaster MyFavoriteType; //declare a general var
MyFavoriteType = new PdfType(); //cast general var to the wanted type
MyFavoriteType.CompileThis();
如何使用word:相同,但MyFavoriteType=new WordType();`
接口就是为此而设计的。MyFavoriteType应该是一个接口,内置任何您需要的东西(功能和特性)。然后,每个想要的类型都将实现该接口并做自己的事情。
这里有一个小例子:
public interface Polygon
{
float GetArea();
}
public class Square : Polygon
{
float Side;
public Square(float side)
{
Side = side;
}
Polygon.GetArea()
{
return side*side;
}
}
你现在可以这样做了:
Polygon MyPolygon = new Square(5f);
float area = MyPolygon.GetArea();
这将适用于正确实现Polygon
接口的ANY SINGLE CLASS。所以这是可能的:
Polygon MyPolygon = new Circle(5f);
float area = MyPolygon.GetArea();
在您的情况下,界面看起来是这样的:
public interface MyFavoriteType//or name it FileTypeMaster, since that's what you want to anme it
{
void CompileThis();
}
只有在子类之间共享行为时才使用基类。如果您只共享方法签名和属性(例如,每个子类并没有真正使用任何基类功能),那么请使用接口。
这里要做的是利用多态性。实际上,您在这里实现了策略设计模式,在这里您有一个基类(或接口)
public abstract class FileTypeMaster
{
public abstract CompileThis();
}
并且有不同的实现,对于Word和Pdf:
public class PdfType : FileTypeMaster
{
public override CompileThis () {}
}
然后,在您的调用程序中,您可以创建正确的实现:
FileTypeMaster x = new PdfType();
x.CompileThis()
或
FileTypeMaster x = new WordType() x.CompileThis()
事实上,您可以通过使用工厂类或工厂方法来抽象初始化:
public abstract class FileTypeMaster
{
public abstract CompileThis();
public static FileTypeMaster Create( FileType type )
{
switch( type )
{
case FileType.Word : return new WordType();
case FileType.Pdf : return new PdfType();
default:
throw new NotImplementedException();
}
}
}
要添加到其他帖子中,通常有一个工厂,该工厂给定一个指示符(如表示用户选择的文件类型的枚举值),生成相应类的实例并将其作为接口类型返回。
您的基类型可以是类,也可以是接口。假设它是一个接口:
interface IFileProcessor { void CompileThis(); }
class PdfProcessor : IFileProcessor { public void CompileThis() { /* ... implementation omitted ... */ }
class WordProcessor : IFileProcessor { public void CompileThis() { /* ... implementation omitted ... */ }
然后:
private enum ProcessorType
{
Undefined,
Word,
Pdf
}
public void Main(string[] args)
{
ValidateArgs(args); // implementation omitted
ProcessorType requestedProcessor = GetRequestedProcessorFromArgs(args); // implementation omitted
IFileProcessor processor = GetProcessor(requestedProcessor);
processor.CompileThis();
}
private IFileProcessor GetProcessor(ProcessorType requestedProcessorType)
{
switch (requestedProcessorType)
{
case ProcessorType.Pdf:
return new PdfProcessor();
case ProcessorType.Word:
return new WordProcessor();
default:
throw new ArgumentException("requestedProcessorType");
}
}