Добро пожаловать в Golang и Stack Overflow!
Похоже, это общий вопрос разработки программного обеспечения о том, как проектировать структуры данных и операции в вашем проекте и их зависимости.
Как вы обнаружили, круговой импорт плох. Есть много способов изменить дизайн, чтобы отделить вещи. Один из них - прозрачные слои - например, Bank
, вероятно, должен зависеть от Human
, а не наоборот. Однако, если вы хотите предоставить удобную функциональность для перевода денег из Human
в Human
, вы могли бы сделать одну вещь - определить интерфейс, который будет реализован объектом Bank
.
Однако для простоты я бы порекомендовал строгие слои. Нет реальной причины, по которой Human
должно зависеть от Bank
. В пределе это может оказаться слишком громоздким, поскольку Human
нужно больше услуг (вы бы поставили зависимость Human
от Bus
, чтобы Bus
могли перемещать Human
с?]
Чтобы ответить на комментарий и обновленный вопрос, я бы сказал, что это просто:
package main
import (
"fmt"
"log"
)
type Human struct {
ID int64
Name string
}
type Account struct {
ID int64
// Note: floats aren't great for representing money as they can lose precision
// in some cases. Keeping this for consistency with original.
Cash float64
DaysSinceActive int64
}
type Bank struct {
Accounts map[int64]Account
}
// Not checking negatives, etc. Don't use this for real banking :-)
func (bank *Bank) Transfer(src int64, dest int64, sum float64) error {
srcAcct, ok := bank.Accounts[src]
if !ok {
return fmt.Errorf("source account %d not found", src)
}
destAcct, ok := bank.Accounts[dest]
if !ok {
return fmt.Errorf("destination account %d not found", dest)
}
// bank.Accounts[src] fetches a copy of the struct, so we have to assign it
// back after modifying it.
srcAcct.Cash -= sum
bank.Accounts[src] = srcAcct
destAcct.Cash += sum
bank.Accounts[dest] = destAcct
return nil
}
func main() {
gary := Human{19928, "Gary"}
sam := Human{99555, "Sam"}
bank := Bank{Accounts: map[int64]Account{}}
bank.Accounts[gary.ID] = Account{gary.ID, 250.0, 10}
bank.Accounts[sam.ID] = Account{sam.ID, 175.0, 5}
fmt.Println("before transfer", bank)
if err := bank.Transfer(gary.ID, sam.ID, 25.0); err != nil {
log.Fatal(err)
}
fmt.Println("after transfer", bank)
}
Этот код использует слабую связь, как упоминалось в моем первоначальном ответе. Все, что банку нужно знать о человеке, - это его удостоверение личности (может быть SSN или что-то, рассчитанное по имени, дате рождения и другим вещам), чтобы идентифицировать их однозначно. Люди должны держать банки (что, если у человека есть счета в нескольких банках?). Банки не должны содержать людей (что делать, если счета принадлежат нескольким лицам, корпорациям, виртуальным объектам?) И так далее. Здесь нет необходимости в интерфейсах, и вы можете безопасно поместить каждый тип данных в свой собственный пакет, если вам действительно нужно.
И теперь я обновил свою утилиту (упомянутую выше) для поддержки создания папок решений: http://bloggingabout.net/blogs/vagif/archive/2009/12/03/utility-to-generate-solution-files-can-now-create-solution-folders.aspx
Создайте пустое решение, затем перетаскивание все Ваши проекты в него сразу?
У меня есть программно созданные файлы решения управления текстом использования для .vcproj файлов (но cs/vb будет работать все равно). Не действительно трудно выяснить, как сделать это, если Вы открываете файл решения в блокноте или что бы то ни было.
К сожалению, я не могу предоставить код, поскольку это является собственным.
Можно попробовать это (код ниже прибывает из этого сайта всех сайтов..)
Но если бы это не работает, и потребовалось бы слишком много времени для отладки, я предложил бы идти для боли добавления их вручную однажды. Просто поместите немного хорошей музыки и пойдите для нее... :)
@oefe я не думаю VS.NET, позволяет Вам проектам D&D в решения, я попробовал это однажды.
Imports EnvDTE
Imports EnvDTE80
-----------------------------------------------------------------------------------
Private Shared Sub DoStuff()
Dim filePath As String = "c:\temp"
Dim fileName As String = "bld_TestApp.sln"
Dim fullName As String = Path.Combine(filePath, fileName)
Dim objType As Type
Dim objDTE As EnvDTE.DTE
objType = Type.GetTypeFromProgID("VisualStudio.DTE.8.0")
objDTE = DirectCast(System.Activator.CreateInstance(objType), EnvDTE.DTE)
Console.WriteLine(objDTE.Name + ":" + objDTE.Version)
objDTE.Solution.Create(filePath, fileName)
objDTE.Solution.AddFromFile("C:\Common.vbproj")
objDTE.Solution.SaveAs(fullName)
End Sub
Проверьте nAnt, порт.NET Муравья. Это имеет способность сделать материал как это или создать без него.
Вагиф Абилов написал замечательную утилиту, которая генерирует файл решения из файлов проекта. Это замечательно, если вы работаете с людьми, которые не «верят» в файлы решений. тьфу.
GenerateSolutionFile.exe
Использование: GenerateSolutionFile / p / s [/ i includeFilter] [/ e excludeFilter]