Powershell访问同级方法

时间:2019-07-18 00:25:58

标签: powershell class design-patterns siblings

我无法访问Powershell中的同级方法

$group.search.has_member(search)一经获得成员便相同,但是 $group.retrieve.Members()获取的365个组和本地组的成员不同

因此,我试图通过.search.has_member(search)调用.retrieve.Members()来最大程度地减少代码重复(IRL大约有15个不同的版本,其中一些具有独特的检索方法,而某些具有共享的方法)。但是我在访问兄弟姐妹的方法时遇到了麻烦

我的主要目标是尝试构建一个界面外观,以统一您如何与Exchange邮件对象进行交互。 365 mailboxeslocal mailboxes365 groupslocal groups(以及其他)都可以具有MembersMemberOfEmail Addresses和{ {1}},但Distinguished Name是所有对象的属性,而DN属性在365与本地组(影响Email addresses)上的格式不同,并检索.MatchesSMTP($search) 365组与本地组的区别在于,无论是365组还是本地的,邮箱和邮件联系人都应返回null,并且对于每种对象类型,MemberOf的检索都是唯一的。

这导致相当大的复杂性。 Originally我试图先使用基于Type(邮箱与组)的继承,然后再基于Server(Members()mailbox_365等)进行继承,但最终导致重复过多码。交换订单时出现相同的问题(mailbox_local365_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上的设计模式,但是我对它们的经验仍然是新手

1 个答案:

答案 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!