Getting past Open-Closed Principle

大憨熊 提交于 2019-12-05 04:49:50

It begs for a factory but not just the factory but factory with injectable workers.

public class Context {
   public Point BeginPoint;
   public Point EndPoint;
   public List Points;

   whatever else
}

public class ShapeFactory {

   List<FactoryWorker> workers;

   public Shape CreateShape( string ShapeName, Context context )
   {
      foreach ( FactoryWorker worker in workers )
         if ( worker.Accepts( ShapeName ) )
             return worker.CreateShape( context );
   }

   public void AddWorker( FactoryWorker worker ) {
      workers.Add( worker );
   }
 }

 public abstract class FactortWorker {
    public abstract bool Accepts( string ShapeName );
    puboic Shape CreateShape( Context context );
 }

 public class PolyLineFactoryWorker : FactoryWorker {

    public override bool Accepts( string ShapeName ) {
       return ShapeName == "polyline";
    }

    public Shape CreateShape( Context context ) { ... }

 }

This way the code is open for extensions - new factory workers can be created freely and added to the factory.

When you need to create objects that all derive from a single class or implement the same interface, one common approach is to use a factory. In your case, however, a simple factory may not be sufficient, because the factory itself needs to be extensible.

One way to implement it is as follows:

interface IShapeMaker {
    IShape Make(IList<Point> points);
}
class RectMaker : IShapeMaker {
    public Make(IList<Point> points) {
        // Check if the points are good to make a rectangle
        ...
        if (pointsAreGoodForRectangle) {
            return new Rectangle(...);
        }
        return null; // Cannot make a rectangle
    }
}
class PolylineMaker : IShapeMaker {
    public Make(IList<Point> points) {
        // Check if the points are good to make a polyline
        ...
        if (pointsAreGoodForPolyline) {
            return new Polyline(...);
        }
        return null; // Cannot make a polyline
    }
}

With these Maker classes in hand, you can make a registry of makers (a simple List<IShapeMaker>) go through the makers passing them the points, and stopping when you get back a non-null shape.

This system remains extensible, because you can add a pair of NewShape and NewShapeMaker, and "plug them in" into the existing framework: once NewShapeMaker gets in the registry, the rest of the system instantly becomes ready to recognize and use your NewShape.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!