在我参与了多年的项目中,我逐渐发展了一种设计模式,事实证明该模式对我非常有用。有时我觉得我应该对此有些福音,但是如果我尝试发现它只是我那顶旧帽子的版本,我会有些尴尬。我已经遍历了Design Patterns徒劳地寻找它,并且没有遇到其他谈论它的人,但是我的搜索还没有穷尽。

核心思想是拥有一个管理一组定义对象的代理对象,每个定义对象构成某些复杂属性的可能值。举例来说,您可能有所有具有EngineType的Car,Plane和Generator类。 Car不存储自己的EngineType对象,而是存储某种类型的引用键,该键说明其具有的Engine类型(例如整数或字符串ID)。当我们想要查看EngineType的属性或行为时,例如WankelEngine,我们向EngineTypeBroker单例对象请求WankelEngine的定义对象,并向其传递引用键。该对象封装了有关EngineType的所有有趣知识,可能只是一个属性列表,但也可能加载了行为。

因此,它促进了一种共享的,松耦合的聚合,其中许多汽车可能具有WankelEngine,但只有一个WankelEngine定义对象(而EngineTypeBroker可以替换该对象,利用松耦合来增强运行时态)。

在我使用该模式时,该模式的一些元素(继续使用EngineType作为示例):

  • 始终存在IsEngineType(x)和EngineType(x)函数,分别用于确定给定值是否是EngineType的有效引用键,以及分别检索与引用键对应的EngineType定义对象。
  • 我始终为给定的EngineType允许多种形式的引用键,至少始终是字符串名称和定义对象本身,通常是整数ID,有时还包括聚合EngineType的对象类型。这有助于调试,使代码更灵活,并且在我的特定情况下,相对于较旧的做法,可以缓解许多向后兼容的问题。 (在该项目的上下文中,人们通常使用的所有方法都是为EngineType可能具有的每个属性定义哈希,然后通过引用键查找这些属性。)
  • 通常,每个定义实例都是该定义类型的通用类的子类(即WankelEngine继承EngineType)。定义对象的类文件保存在/ Def / EngineType之类的目录中(即WankelEngine的类为/ Def / EngineType / WankelEngine)。因此,相关的定义被分组在一起,并且类文件类似于EngineType的配置文件,但是具有定义代码的能力(通常在配置文件中找不到)。

  • 一些简单说明性的示例伪代码:
    class Car {
    
        attribute Name;
        attribute EngineTypeCode;
    
        object GetEngineTypeDef() {
            return EngineTypeBroker->EngineType(this->GetEngineTypeCode());
        }
    
        string GetDescription() {
            object def = this->GetEngineTypeDef();
            return "I am a car called " . this->GetName() . ", whose " .
                def->GetEngineTypeName() . " engine can run at " .
                def->GetEngineTypeMaxRPM() . " RPM!";
        }
    
    }
    

    那么,为此有一个名字吗?

    最佳答案

    SingletonRegistry

    信不信由你。今天早上我在想同样的事情。

    我以前使用过这种模式,但从未找到它的参考,也不知道如何命名。

    我认为是一种“键控”单例,其中实例存储在某个位置,并使用键获得它们。

    我上次使用它是从不同来源检索数据。

    我有大约50个数据库表(使之成为10),还有一个前端“表”,用于显示数据,但是数据可以来自任何这些来源,并且每个来源都需要不同的逻辑(查询,联接,键)等)

    该前端是“可配置的”,因此我不知道要显示哪些值,而其他将不显示。

    解决方案是将columnName(位于前端)作为键,并获取正确的实例以创建正确的查询。

    它在一开始就安装在哈希图中,后来从数据库表中检索出来。

    代码是这样的:

    class DataFetcher {
        abstract Object getData( Object id );
    }
    
    class CustomerNameDataFetcher extends DataFetcher {
        Object getData( Object customerId ) {
            // select name from customer where id = ?
         }
    }
    
    class CompanyAdressDataFetcher extends DataFetcher {
         Object getData( Object customerId ) { // don't ask why.
              // select name from company , customer where customer.co = company.co and cu = ?  etc.
         }
    }
    
    class ProductColor extends DataFetcher {
         Object getData( Object x ) {
         // join from customer to color, to company to season to a bunch of table where id = ?
    }
    
    // And the list goes on.
    

    每个子类使用不同的逻辑。

    在运行时,用户配置了它的视图,然后选择要查看的内容。

    当用户选择要查看的列时,我使用了列名和ID来获取数据。

    DataFetchers都安装在类方法的父类中(我不想为此创建一个单独的类)。
    class DataFetcher {
        abstract Object getData( Object id );
    
        private static final Map fetchers = new HashMap();static {
            fetchers.put("customer.name", new CustomerNameDataFetcher() );
            fetchers.put("company.address", new CompanyAdressDataFetcher () );
            fetchers.put("product.color", new ProductColor () );
            ...
        }
        public static DataFetcher getFetcher( String id ) {
            return fetchers.get( id );
        }
    
    }
    

    在填充前端表的最后,我只是这样称呼它:

    伪码
     for each row in table
          for each column in row
              column.text = DataFetcher.getFetcher( column.id ).getData( row.id )
           end
     end
    

    这样吗还是我误读了您的描述,而我的描述却大不相同。

    最后,我认为这称为SingletonRegistry或类似的名称。我(可能)像您一样,是出于必要而创建的。这是一种常见的模式。

    关于design-patterns - “残破的定义集”设计模式-以其他名称闻名吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/401720/

    10-10 19:12