C#限制类的使用
下面的代码就是我希望它做的。Main方法中的代码的外观和行为完全符合要求。但是,如果类UserMenu、Home和DropdownMenu2只能由HeaderVigationMenu使用,以保护其他开发人员不尝试在HeaderVigationMenu类之外使用它们,则更可取。此外,大多数文章都不赞成把一切公之于众 问题: 下面使用的设计模式是否合适,或者在这种情况下是否有更好、更可接受的方法C#限制类的使用,c#,design-patterns,architecture,C#,Design Patterns,Architecture,下面的代码就是我希望它做的。Main方法中的代码的外观和行为完全符合要求。但是,如果类UserMenu、Home和DropdownMenu2只能由HeaderVigationMenu使用,以保护其他开发人员不尝试在HeaderVigationMenu类之外使用它们,则更可取。此外,大多数文章都不赞成把一切公之于众 问题: 下面使用的设计模式是否合适,或者在这种情况下是否有更好、更可接受的方法 编辑:此设计的原因 我希望HeaderNavigationMenu的最终用户能够使用点符号来获得可用选
编辑:此设计的原因
限制对类构造函数的访问。如果它们被声明为“内部”然后,类可能只能由您的代码创建。我不太了解您的用例是什么,我从来没有这样编写过代码,但只公开
HeaderNavigationMenu
所需行为的一种方法是将类设为内部类,并将变量设为私有类,然后只公开SelectOption3()
方法,如下所示
如果您取消对该行的注释
//Home home = new Home();
您将得到一个编译器错误
class Program
{
static void Main(string[] args)
{
HeaderNavigationMenu navigationMenu = new HeaderNavigationMenu();
navigationMenu.DropdownMenu2SelectOption3();
// The following code is an example of undesired capability;
// prefer if Home class could only be
// used by HeaderNavigationMenu class
//Home home = new Home();
}
}
public class HeaderNavigationMenu
{
UsersMenu usersMenu;
Home home;
DropdownMenu2 dropdownMenu2;
public HeaderNavigationMenu()
{
usersMenu = new UsersMenu();
home = new Home();
dropdownMenu2 = new DropdownMenu2();
}
public void DropdownMenu2SelectOption3()
{
dropdownMenu2.SelectOption3();
}
class UsersMenu
{
}
class Home
{
}
class DropdownMenu2
{
public void SelectOption3()
{
}
}
}
您可以创建
用户菜单
,主页
,以及下拉菜单2
公共摘要
类。然后在HeaderNavigationMenu
中嵌套private
类,这些类扩展了public abstract
版本
公共抽象类用户菜单
{
}
公共抽象类主页
{
}
公共抽象类下拉菜单2
{
public void SelectOption3()
{
//选择选项3的代码。。。
}
}
公共类标题激活菜单
{
公共标题激活菜单()
{
UsersMenu=新的UsersMenuImpl();
Home=新的HomeImpl();
DropdownMenu2=新的DropDownMenuImpl();
}
公共用户菜单用户菜单{get;}
公共住宅{get;}
公共下拉菜单2下拉菜单2{get;}
私有类UsersMenuImpl:UsersMenu
{
}
私有类HomeImpl:Home
{
}
私有类DropDownMenuImpl:DropdownMenu2
{
}
}
其他开发人员可以查看和使用用户菜单
、主页
、和下拉菜单2
抽象
类,但不能创建它们的实例。只有headernavigation菜单
当然,另一个开发人员总是可以从
公共抽象
类派生出他们自己的类,但是你能做的只有这么多UsersMenu
、Home
和DropdownMenu2
必须是public
,才能成为public
属性。如果您希望防止UsersMenu
的实例化,DropdownMenu2
,和Home
从外部HeaderNavigationMenu
但仍在与HeaderNavigationMenu
相同的项目中,那么有一个巧妙的技巧可以实现这种行为。可以将公共嵌套类与私有构造函数一起使用,私有构造函数静态初始化它们自己的工厂方法。这方面的基本模板是:
公共类外部{
私有静态函数内部工厂;
公共内部公开器{get;private set;}
公共图书馆{
//强制运行静态初始值设定项。
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(内部).TypeHandle);
//调用新创建的工厂方法,而不是常规构造函数。
ExposedInner=_innerFactory();
}
公共阶级内部{
静态内部(){
//初始化外部的静态工厂方法。
_innerFactory=()=>新内部();
}
//内部无法实例化(无反射),因为其构造函数是私有的。
私有内部(){}
//此方法现在公开给任何人使用。
public void DoStuff(){Console.WriteLine(“Did stuff”);}
}
}
在您的示例中实现了以下概念:
类程序
{
静态void Main(字符串[]参数)
{
HeaderNavigationMenu导航菜单=新建HeaderNavigationMenu();
导航菜单。下拉菜单2。选择选项3();
//此行将不再工作,因为构造函数
//因为内部类是私有的。
HeaderNavigationMenu.homeempl home=新建HeaderNavigationMenu.homeempl();
Console.ReadKey();
}
}
公共类标题激活菜单
{
//静态初始化的私有工厂方法
私有静态函数创建用户;
私有静态函数创建下拉列表;
私有静态函数_createHome;
公共标题激活菜单()
{
//强制静态构造函数运行
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(UsersMenuImpl.TypeHandle);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(HomeImpl.TypeHandle));
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(DropDownMenuImpl.TypeHandle);
UsersMenu=_createUsers();
主页=_createHome();
DropdownMenu2=_createDropdown();
}
public UsersMenuImpl UsersMenu{get;set;}
公共HomeImpl Home{get;set;}
公共DropdownMenu2Impl DropdownMenu2{get;set;}
公共类UsersMinImpl
{
//创建类工厂方法的静态构造函数
静态UsersMenuImpl()
{
_createUsers=()=>new UsersMinImpl();
}
私有用户smenuimpl(){}
}
公共类HomeImpl
class Program
{
static void Main(string[] args)
{
HeaderNavigationMenu navigationMenu = new HeaderNavigationMenu();
navigationMenu.DropdownMenu2SelectOption3();
// The following code is an example of undesired capability;
// prefer if Home class could only be
// used by HeaderNavigationMenu class
//Home home = new Home();
}
}
public class HeaderNavigationMenu
{
UsersMenu usersMenu;
Home home;
DropdownMenu2 dropdownMenu2;
public HeaderNavigationMenu()
{
usersMenu = new UsersMenu();
home = new Home();
dropdownMenu2 = new DropdownMenu2();
}
public void DropdownMenu2SelectOption3()
{
dropdownMenu2.SelectOption3();
}
class UsersMenu
{
}
class Home
{
}
class DropdownMenu2
{
public void SelectOption3()
{
}
}
}