【问题标题】:What is this design principle called?这个设计原则叫什么?
【发布时间】:2011-08-02 22:13:38
【问题描述】:

我正在寻找一个设计原则的名称,它实质上是“客户端代码永远不必记住有关使用接口的方式的任何特殊内容”。

例如,假设您有两个方法,loginAttempted() - 检查发布的 u/p 数据 - 和 loginValid() - 验证 u/p。现在说你总是应该在调用 loginValid() 之前调用 loginAttempted() -- 如果你调用 loginValid() 并且没有发布 u/p,你将试图访问未定义的变量并得到一个错误。所以这个例子违反了有问题的原则,因为客户端代码必须记住在调用 loginValid() 之前使用 loginAttempted()。

那么,这个设计原则的名称是什么?

【问题讨论】:

    标签: design-patterns


    【解决方案1】:

    更高级别的抽象可能会“解决”这个问题。但是您展示的这种特定模式称为sequential coupling,在大多数情况下,我会认为它是“反模式”。

    【讨论】:

    • 感谢 Paul,是的,这肯定是一种反模式。
    • +1 这确实是答案 :) 不过,我将把我的作为临时评论留下。
    • +1 有没有办法解决这个问题?我的意思是使用委托来确保在 method1 或类似的东西之后调用 method2。
    • @Sandeep 没有细节很难说。我不认为有一些抽象的解决方法,因为它可以通过多种方式引起。我从看到对象上没有构造函数的设计中了解到这一点,并且您必须以正确的顺序设置所有属性。解决方案是创建一个构造函数,从客户端代码中隐藏这种必要性。
    • @sandeep:正如 wiki 链接所解释的,这通常可以使用模板方法修复。
    【解决方案2】:

    我只能将其描述为缺少Information Hiding

    客户端代码必须对另一个对象了解太多。在这种情况下,methodA 会以某种方式影响对象的内部,使得之后调用methodB 成为可能。

    我必须说你给的描述敲响了(遥远的)钟声,所以也许实际上有一个更正式的名称。但这肯定是信息隐藏不佳的一种变体。

    【讨论】:

    • Pablo,我同意这违反了某种意义上的信息隐藏,但 Paul 的答案正是我想要的
    • 确实,这是正确的名称。我将把它作为关于该主题的其他 cmets 留下,谁知道它可能会对某人有所帮助:)
    【解决方案3】:

    具体例子

    有没有办法解决这个问题?我的意思是使用委托来确保 在 method1 或类似的东西之后调用 method2。 ——

    准点。但我在想abstract。无论哪种方式,您的整体需求的细节都可以推动它。但我们还必须添加另一条评论:

    更高级别的抽象可能会“解决”这个问题。

    大图

    • 公共 Login() 方法(用于客户端代码),...
    • 依次调用 LoginAttempted() 和 LoginValid()。
    • 此外,这两个子方法是abstract(可以是委托)
    • 因此客户端代码只能调用 Login() 和 ...
    • 登录实现可以自定义这些登录功能的工作方式...
    • 他们的通话顺序是永久的。

    顺便说一句,在方法调用的有序列表中具有可替换的方法是 模板设计模式

    这个例子是用 C# 编写的(我希望它有效!)

    public abstract class LogOnBase {
    
        // add comments here so we know what these are supposed to do
        protected abstract void LogInValid(string, string);
        protected abstract void LogInAttempted (string, string);
    
        public bool Logon(string userName, string Password) {
            LogInAttempted (userName, Password);
            LogInValid (userName, Password);
        }
    }
    
    // concrete implementation
    public class LogOnConcrete : LogOnBase {
        protected override void LoginValid (string UName, string PW) {
            // do concrete stuff
        }
    
        protected override void LogInAttempted (string UName, string PW) {
            // do concrete stuff
        }
    }
    
    // Using the LogOn class
    public class LogOnExample {
        string whoAmI;
        string passWord;
        LogOnConcrete LogMeIn;
    
        public LogOnExample (string me, string pw) {
            whoAmI = me;
            passWord = pw;
        }
    
        public static void Main (string[] args) {
            LogOnExample driver = new LogOnExample (bubba, mySecretPW);
            LogMeIn = new LogOnConcrete();
            LogMeIn.Logon(driver.whoAmI, driver.passWord);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 2015-08-17
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      • 2016-11-06
      相关资源
      最近更新 更多