У меня есть проект, который добавляет элементы к чертежу 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();
}
}
}
}
Injection: Это подошел извлекал дублирования кода, но я думаю, что читаемость беден.
[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();
}
}
}
}
Инъекционное 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, поэтому я совершенно новичок в этом. Может ли кто-нибудь из вас более опытных разработчиков дать мне Pro/Con двух разных подходов? Есть ли что-нибудь в последнем подходе, это красный флаг? Это кажется более читаемым, чем второй подход. Может быть, я даже не совсем понимаю инъекцию ... Спасибо заранее за вход!
Да, это тоже сработает! Полностью пропустил этот подход, +1 за его уловку :) Это затруднило бы логику добавления элемента, если это необходимо. Спасибо, что нашли время ответить! – JSprang
Я уточню ответ для специальной обработки логики. –