我一直在博客中看到对访客模式的引用,但我必须承认,我只是不明白.我阅读了维基百科文章的模式,我理解它的机制,但我仍然对我何时使用它感到困惑.
作为最近刚刚获得装饰模式的人,现在看到它在任何地方的用途我都希望能够直观地理解这个看似方便的模式.
我对Haskell并不十分精通,所以这可能是一个非常简单的问题.
Rank2Types解决了什么语言限制?Haskell中的函数是否已经支持多态参数?
我很难描述这个问题.也许这就是为什么我很难找到一个好的解决方案(这些话只是不合作).让我通过代码解释:
// original code
enum Fruit
{
Apple,
Orange,
Banana,
}
...
Fruit fruit = acquireFruit();
if (fruit != Fruit.Orange && fruit != Fruit.Banana)
coreFruit();
else
pealFruit();
eatFruit();
Run Code Online (Sandbox Code Playgroud)
现在假装多年的发展与这三种类型.上述逻辑的不同风格在存储过程,SSIS包,Windows应用程序,Web应用程序,Java应用程序,perl脚本等中传播....
最后:
// new code
enum Fruit
{
Apple,
Orange,
Banana,
Grape,
}
Run Code Online (Sandbox Code Playgroud)
大多数时候,"系统"运行正常,直到使用Grapes.然后,当不需要或不需要时,系统的某些部分会不恰当地起作用,剥离和/或取芯葡萄.
你坚持什么样的指导方针,以避免这些混乱?我的偏好是旧代码抛出异常,如果它没有被重构以考虑新的枚举.
我在黑暗中想出了一个镜头:
#1避免像这样"不在逻辑中"
// select fruit that needs to be cored
select Fruit from FruitBasket where FruitType not in(Orange, Banana)
Run Code Online (Sandbox Code Playgroud)
#2需要时使用精心构造的NotIn()方法
internal static class EnumSafetyExtensions
{
/* By adding enums to these methods, you certify that 1.) ALL …Run Code Online (Sandbox Code Playgroud) 我的资源(.resx)文件中有一堆字符串.我试图直接使用它们作为switch语句的一部分(请参阅下面的示例代码).
class Test
{
static void main(string[] args)
{
string case = args[1];
switch(case)
{
case StringResources.CFG_PARAM1: // Do Something1
break;
case StringResources.CFG_PARAM2: // Do Something2
break;
case StringResources.CFG_PARAM3: // Do Something3
break;
default:
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我看了一些解决方案,其中大多数似乎都暗示我需要将它们声明为const string我个人不喜欢的.我喜欢这个问题的最高投票解决方案:在switch语句中使用字符串集合.但后来我需要确保我enum和strings资源文件绑在一起.我想知道一个巧妙的方法.
编辑:在研究如何使用时
也找到了这个很好的答案Action:
public class Song {
public string Genre { get; protected set; }
public string Name { get; protected set; }
public string Band { get; protected set; }
public Song(string name, string band, string genre) {
Name = name;
Genre = genre;
Band = band;
}
}
public interface IMusicVisistor
{
void Visit(List<Song> items);
}
public class MusicLibrary {
List<Song> _songs = new List<Song> { ...songs ... };
public void Accept(IMusicVisitor visitor) {
visitor.Visit(_songs);
}
}
Run Code Online (Sandbox Code Playgroud)
现在这是我做的一位访客:
public class RockMusicVisitor …Run Code Online (Sandbox Code Playgroud) 容器可以包含属于人的自行车和椅子.我想检查,如果容器包含自行车或所述人的椅子.没有使用这可能instanceof吗?
public class Container {
public Map<Person, List<Item>> items = new HashMap<>();
public void add(Person p, Item item) {
items.get(p).add(item);
}
public boolean containsChair(Person owner) {
for(Item i : items.get(owner)) {
if(i instanceof Chair) {
return true;
}
}
return false;
}
public boolean containsBike(Person owner) {
for(Item i : items.get(owner)) {
if(i instanceof Bike) {
return true;
}
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
出于说明的目的,Item,Bike,Chair,Person都是最简单的类存根:
public class Person { public String name; }
public abstract class Item {} …Run Code Online (Sandbox Code Playgroud)