我无法访问Powershell中的同级方法
$group.search.has_member(search)
一经获得成员便相同,但是
$group.retrieve.Members()
获取的365个组和本地组的成员不同
因此,我试图通过.search.has_member(search)
调用.retrieve.Members()
来最大程度地减少代码重复(IRL大约有15个不同的版本,其中一些具有独特的检索方法,而某些具有共享的方法)。但是我在访问兄弟姐妹的方法时遇到了麻烦
我的主要目标是尝试构建一个界面外观,以统一您如何与Exchange邮件对象进行交互。 365 mailboxes
,local mailboxes
,365 groups
和local groups
(以及其他)都可以具有Members
,MemberOf
,Email Addresses
和{ {1}},但Distinguished Name
是所有对象的属性,而DN
属性在365与本地组(影响Email addresses
)上的格式不同,并检索.MatchesSMTP($search)
365组与本地组的区别在于,无论是365组还是本地的,邮箱和邮件联系人都应返回null,并且对于每种对象类型,MemberOf的检索都是唯一的。
这导致相当大的复杂性。 Originally我试图先使用基于Type(邮箱与组)的继承,然后再基于Server(Members()
,mailbox_365
等)进行继承,但最终导致重复过多码。交换订单时出现相同的问题(mailbox_local
,365_mailbox
等)。
因此,现在我正在尝试基于行为实现抽象,以便在可能的情况下更好地共享代码,并针对需要更独特方法的版本分别选择样式/策略。但是365_group
无法访问.Searches
。
我想我可以像将.Retrievals
一样将retrievals
作为参数传递给searches
构造函数,但是如果我开始以更多的结尾,这种方法就无法很好地扩展具有隔行扫描依存关系的行为类别。另外,如果我可以使兄弟姐妹访问正常,那么我可以停止将config作为参数传递,而直接直接访问它们,这应该会清理代码更多。
下面是一个简化的示例供您参考(是的,尽管它很复杂,但已大大减少了,我上一次计算的最终版本大约有26个课)
config
这会吐出以下错误(我用Class Mail_Factory
{
static [Mail_Interface] BuildExample1()
{
$mail_object = "Pretend 365 group"
return [Mail_Factory]::Build($mail_object)
}
static [Mail_Interface] BuildExample2()
{
$mail_object = "Pretend Local Group"
return [Mail_Factory]::Build($mail_object)
}
static [Mail_Interface] Build($mail_object)
{
[Mail_Interface] $interface = [Mail_Interface]::new()
$interface.config = [Mail_Config]::new($mail_object)
$interface.retrieve = [Mail_Retrieve]::new($interface.config)
$interface.search = [Mail_Search]::new($interface.config)
[Mail_Retrieve_Members_Style] $members_style = switch ($mail_object)
{
("Pretend 365 group") { [Mail_Retrieve_Members_365Group]::new($interface.config) }
("Pretend Local Group") { [Mail_Retrieve_Members_LocalGroup]::new($interface.config) }
}
# notice that we're setting a specific retreival strategy for "members" depending on object type
$interface.config.members_style = $members_style
return $interface
}
}
Class Mail_Interface
{
Mail_Interface(){}
[Mail_Config] $config
[Mail_Retrieve] $retrieve # This is a facade to unify the way we call different kinds of retreivals (directly from settings, derived from settings, shared based on type, or unique to a specific combination of settings)
[Mail_Search] $search # This is a facade for the same reasons as $retreive
[bool] has_member($search) {return $this.search.has_member($search)}
[object] members() {return @($this.retrieve.members())}
}
Class Mail_Config
{
Mail_Config($mail_object) {$this.mail_object = $mail_object}
[Mail_Retrieve_Members_Style] $members_style # set by factory
[object] $mail_object
}
Class Mail_Retrieve
{
Mail_Retrieve($config){$this.config = $config}
[Mail_Config] $config
[object] Members(){return $this.config.members_style.Members()}
}
Class Mail_Retrieve_Members_Style
{
Mail_Retrieve_Members_Style($config){$this.config = $config}
[Mail_Config] $config
[object] Members(){throw("Syle not yet selected")}
}
Class Mail_Retrieve_Members_365Group : Mail_Retrieve_Members_Style
{
Mail_Retrieve_Members_365Group($config) : base($config) {}
# inherited: [Mail_Config] $config
[object] Members(){return "member of 365 group"}
}
Class Mail_Retrieve_Members_LocalGroup : Mail_Retrieve_Members_Style
{
Mail_Retrieve_Members_LocalGroup($config) : base($config) {}
# inherited: [Mail_Config] $config
[object] Members(){return "member of local group"}
}
Class Mail_Search
{
Mail_Search($config){$this.config = $config}
[Mail_Config] $config
[bool] has_member($search)
{
$members = $this.parent.retrieve.members() # !!! Problem exists here !!!
if ($members -contains "$search") {return $true}
else {return $false}
}
}
function TestExample1()
{
# from
# $a.search.has_member()
# we're trying to access
# $a.retrieve.Members()
$a = [Mail_Factory]::BuildExample1()
$member_a = $a.members()[0]
if ($a.has_member($member_a))
{"Success!"}
else
{"Failed, member match incorrect"}
}
function TestExample2()
{
# from
# $b.search.has_member()
# we're trying to access
# $b.retrieve.Members()
$b = [Mail_Factory]::BuildExample2()
$member_b = $b.members()[0]
$b.has_member($member_b)
if ($b.has_member($member_b))
{"Success!"}
else
{"Failed, member match incorrect"}
}
$result_a = TestExample1
$result_b = TestExample2
$result_a
$result_b
标记了这一行)
!!! Problem exists here !!!
我对此项目拥有完全的控制权,如果我以错误的方式进行操作,目前我愿意完全重构为其他方法。我很喜欢使用链式构造函数,特别是如果它们提高了可读性。 而且我一直在探索G4G上的设计模式,但是我对它们的经验仍然是新手
答案 0 :(得分:0)
我最终用对父级(Config
)的引用替换了对Interface
的引用。虽然这可能会导致意外递归,但这似乎是唯一的方法(我已经发现)
我还弄平了方法,删除了.search
和.retrieve
,因为现在看来它们并不需要。
Class Mail_Factory
{
static [Mail_Interface] BuildExample1()
{
$mail_object = "Pretend 365 group"
return [Mail_Factory]::Build($mail_object)
}
static [Mail_Interface] BuildExample2()
{
$mail_object = "Pretend Local Group"
return [Mail_Factory]::Build($mail_object)
}
static [Mail_Interface] Build($mail_object)
{
[Mail_Interface] $interface = [Mail_Interface]::new()
$interface.config = [Mail_Config]::new($mail_object)
#$interface.retrieve = [Mail_Retrieve]::new($interface)
#$interface.search = [Mail_Search]::new($interface)
[Mail_Members_Style] $members_style = switch ($mail_object)
{
("Pretend 365 group") { [Mail_Members_365Group]::new($interface) }
("Pretend Local Group") { [Mail_Members_LocalGroup]::new($interface) }
}
# notice that we're setting a specific retreival strategy for "members" depending on object type
$interface.members_style = $members_style
$interface.has_member_style = [Mail_HasMember_Default]::new($interface)
return $interface
}
}
Class Mail_Interface
{
Mail_Interface(){}
[Mail_Config] $config
# set by factory #
[Mail_HasMember_Style]$has_member_style
[Mail_Members_Style]$members_style
# set by factory #
[bool] HasMember($search) {return $this.has_member_style.HasMember($search)}
[object] members() {return @($this.members_style.Members())}
}
Class Mail_Config
{
Mail_Config($mail_object) {$this.mail_object = $mail_object}
# IRL we store a lot more in here
[object] $mail_object
}
Class Mail_Members_Style
{
Mail_Members_Style($interface){$this.interface = $interface}
[Mail_Interface] $interface
[object] Members(){throw("Syle not yet selected")}
}
Class Mail_Members_365Group : Mail_Members_Style
{
Mail_Members_365Group($interface) : base($interface) {}
# inherited: [Mail_Interface] $interface
[object] Members(){return "member of 365 group"}
}
Class Mail_Members_LocalGroup : Mail_Members_Style
{
Mail_Members_LocalGroup($interface) : base($interface) {}
# inherited: [Mail_Interface] $interface
[object] Members(){return "member of local group"}
}
Class Mail_HasMember_Style
{
Mail_HasMember_Style($interface){$this.interface = $interface}
[Mail_Interface] $interface
[bool] HasMember($search){throw("Syle not yet selected")}
}
Class Mail_HasMember_Default : Mail_HasMember_Style
{
Mail_HasMember_Default($interface) : base($interface) {}
# inherited: [Mail_Interface] $interface
[bool] HasMember($search)
{
$members = $this.interface.members()
if ($members -contains "$search") {return $true}
else {return $false}
}
}
function TestExample1()
{
# from
# $a.has_member_style.has_member()
# we're trying to access
# $a.members_style.Members()
$a = [Mail_Factory]::BuildExample1()
$member_a = $a.members()[0]
if ($a.HasMember($member_a))
{"Success!"}
else
{"Failed, member match incorrect"}
}
function TestExample2()
{
# from
# $b.has_member_style.hasmember()
# we're trying to access
# $b.members_style.Members()
$b = [Mail_Factory]::BuildExample2()
$member_b = $b.members()[0]
if ($b.HasMember($member_b))
{"Success!"}
else
{"Failed, member match incorrect"}
}
function TestExample3()
{
# Verifying HasMember is actually checking stuff
$b = [Mail_Factory]::BuildExample1()
if ($b.HasMember("Not A Member"))
{"Failed, HasMember is incorrectly returning true"}
else
{"Success!"}
}
$result_a = TestExample1
$result_b = TestExample2
$result_c = TestExample2
$result_a
$result_b
$result_c
测试结果
Success!
Success!
Success!