首页 新闻 赞助 找找看

【Refactoring】帮忙重构一个C#程序

0
悬赏园豆:50 [已关闭问题]

我有一个画图演示程序:在不同的表面上画不同的形状

----------------------------------------------------------

表面:Surface(表面)、EtchASketch(浮雕表面)

形状:Shape(形状)、Ploygon(多边形)、Quadrilateral(四边形)、Parallelogram(平行四边形)、Rectangle(矩形)

----------------------------------------------------------

下面的代码,显然违反了OCP原则:

如果要添加一个新Surface的话,我必须要在所有的Shape里添加新方法!

我想请高手们看看,应该如何重构这段程序,以及说说为什么

非常感谢!

class Surface
{
public virtual void Draw(Shape shape)
{
shape.Draw(
this);
}
}

class EtchASketch : Surface
{
public override void Draw(Shape shape)
{
shape.Draw(
this);
}
}

class Shape
{
public virtual void Draw(Surface surface)
{
Console.WriteLine(
"A shape is drawn on the surface with ink.");
}

public virtual void Draw(EtchASketch etchASketch)
{
Console.WriteLine(
"The knobs are moved in attempt to draw the shape.");
}
}

class Polygon : Shape
{
public override void Draw(Surface surface)
{
Console.WriteLine(
"A polygon is drawn on the surface with ink.");
}

public override void Draw(EtchASketch etchASketch)
{
Console.WriteLine(
"The knobs are moved in attempt to draw the polygon.");
}
}

class Quadrilateral : Polygon
{
public override void Draw(Surface surface)
{
Console.WriteLine(
"A quadrilateral is drawn on the surface with ink.");
}

public override void Draw(EtchASketch etchASketch)
{
Console.WriteLine(
"The knobs are moved in attempt to draw the quadrilateral.");
}
}

class Parallelogram : Quadrilateral
{
public override void Draw(Surface surface)
{
Console.WriteLine(
"A parallelogram is drawn on the surface with ink.");
}

public override void Draw(EtchASketch etchASketch)
{
Console.WriteLine(
"The knobs are moved in attempt to draw the parallelogram.");
}
}

class Rectangle : Parallelogram
{
public override void Draw(Surface surface)
{
Console.WriteLine(
"A rectangle is drawn on the surface with ink.");
}

public override void Draw(EtchASketch etchASketch)
{
Console.WriteLine(
"The knobs are moved in attempt to draw the rectangle.");
}
}

class Program
{
static void Main(string[] args)
{
Surface surface
= new Surface();
Surface etchASketch
= new EtchASketch();

var shapes
= new List<Shape>
{
new Shape(),
new Polygon(),
new Quadrilateral(),
new Parallelogram(),
new Rectangle()
};

foreach (Shape shape in shapes)
{
surface.Draw(shape);
etchASketch.Draw(shape);
}

Console.ReadLine();
}
}

 

!defined的主页 !defined | 初学一级 | 园豆:10
提问于:2010-07-21 18:25
< >
分享
其他回答(1)
0

有什么样的表面是形状的一种属性,一般情况下一种形状对应一种表面,所以表面是形状的属性,在实例化中指定,不知道我这样说有没有明白。

dege301 | 园豆:2825 (老鸟四级) | 2010-07-22 09:01
0

关键还是回归到需求。

 

现在的情况是一组表面+形状,需要一个绘图实现,不管你将代码放在表面,还是形状,结果都是不可避免要添加“乘数级别”的新实现。 比如 m * n  你m+1 你要实现n个新实现。 n+1你要实现m个新实现。

但是你却想增加一个子类,也就是增加一个实现,就解决问题,这是不可能的。

 

这种情况,也许根本就不应该分成两个类。

诺贝尔 | 园豆:37 (初学一级) | 2010-11-11 02:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册