У меня есть проект, который добавляет элементы к чертежу AutoCad.Я заметил, что начинаю писать одни и те же десять строк кода несколькими способами (для простоты показаны только две).
Первоначальная реализация: Вы заметите, что единственное, что действительно меняется, - это добавление линии вместо круга.
[CommandMethod("Test", CommandFlags.Session)]
public void Test()
{
AddLineToDrawing();
AddCircleToDrawing();
}
private void AddLineToDrawing()
{
using (DocumentLock lockedDocument = Application.DocumentManager.MdiActiveDocument.LockDocument())
{
using (Database database = Application.DocumentManager.MdiActiveDocument.Database)
{
using (Transaction transaction = database.TransactionManager.StartTransaction())//Start the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for write
BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
Line line = new Line(new Point3d(0, 0, 0), new Point3d(10, 10, 0));
blockTableRecord.AppendEntity(line);
transaction.AddNewlyCreatedDBObject(line, true);
transaction.Commit();
}
}
}
}
private void AddCircleToDrawing()
{
using (DocumentLock lockedDocument = Application.DocumentManager.MdiActiveDocument.LockDocument())
{
using (Database database = Application.DocumentManager.MdiActiveDocument.Database)
{
using (Transaction transaction = database.TransactionManager.StartTransaction())//Start the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for write
BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
Circle circle = new Circle(new Point3d(0, 0, 0), new Vector3d(0, 0, 0), 10);
blockTableRecord.AppendEntity(circle);
transaction.AddNewlyCreatedDBObject(circle, true);
transaction.Commit();
}
}
}
}
Инъекция: Этот подход убрал дублирование кода, но я думаю, что читаемость плохая.
[CommandMethod("Test", CommandFlags.Session)]
public void Test()
{
PerformActionOnBlockTable(new CircleDrawer());
PerformActionOnBlockTable(new LineDrawer());
}
public interface IDraw
{
DBObject DrawObject(BlockTableRecord blockTableRecord);
}
public class CircleDrawer : IDraw
{
public DBObject DrawObject(BlockTableRecord blockTableRecord)
{
Circle circle = new Circle(new Point3d(0, 0, 0), new Vector3d(0, 0, 0), 10);
blockTableRecord.AppendEntity(circle);
return circle;
}
}
public class LineDrawer : IDraw
{
public DBObject DrawObject(BlockTableRecord blockTableRecord)
{
Line line = new Line(new Point3d(0, 0, 0), new Point3d(10, 10, 0));
blockTableRecord.AppendEntity(line);
return line;
}
}
private void PerformActionOnBlockTable(IDraw drawer)
{
using (DocumentLock lockedDocument = Application.DocumentManager.MdiActiveDocument.LockDocument())
{
using (Database database = Application.DocumentManager.MdiActiveDocument.Database)
{
using (Transaction transaction = database.TransactionManager.StartTransaction())//Start the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for write
BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
DBObject newObject = drawer.DrawObject(blockTableRecord);
transaction.AddNewlyCreatedDBObject(newObject, true);
transaction.Commit();
}
}
}
}
Injecting Func <>: Это, похоже, дало мне аналогичный результат с лучшей читаемостью.
[CommandMethod("Test", CommandFlags.Session)]
public void Test()
{
PerformActionOnBlockTable(AddLineToDrawing);
PerformActionOnBlockTable(AddCircleToDrawing);
}
private void PerformActionOnBlockTable(Func<BlockTableRecord, DBObject> action)
{
using (DocumentLock lockedDocument = Application.DocumentManager.MdiActiveDocument.LockDocument())
{
using (Database database = Application.DocumentManager.MdiActiveDocument.Database)
{
using (Transaction transaction = database.TransactionManager.StartTransaction())//Start the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for write
BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
DBObject newObject = action(blockTableRecord);
transaction.AddNewlyCreatedDBObject(newObject, true);
transaction.Commit();
}
}
}
}
private DBObject AddLineToDrawing(BlockTableRecord blockTableRecord)
{
Line line = new Line(new Point3d(0, 0, 0), new Point3d(10, 10, 0));
blockTableRecord.AppendEntity(line);
return line;
}
private DBObject AddCircleToDrawing(BlockTableRecord blockTableRecord)
{
Circle circle = new Circle(new Point3d(0, 0, 0), new Vector3d(0, 0, 0), 10);
blockTableRecord.AppendEntity(circle);
return circle;
}
Я могу честно сказать, что я не так много сделал с DI, так что я довольно новичок в этом.Может ли кто-нибудь из вас, более опытных разработчиков, дать мне «за» / «против» двух разных подходов?Есть ли в последнем подходе что-нибудь, что является красным флагом?Кажется, это более читабельно, чем второй подход.Может быть, я даже не совсем понимаю инъекцию ... Заранее спасибо за ваш вклад!