南方优选成长混合c:可选成员对象(optional class features)

关于南方优选成长混合c的问题,在optional class features中经常遇到, 好的,所以你在系统的主类周围撒了很多方法。所以你做了正确的事情,并通过创建一个新类进行重构,并将移动方法执行到一个新类中。新类有一个单一的责任,所有的事情都是正确的:

好的,所以你在系统的主类周围撒了很多方法。所以你做了正确的事情,并通过创建一个新类进行重构,并将移动方法执行到一个新类中。新类有一个单一的责任,所有的事情都是正确的:

class Feature
{
public:
    Feature(){};
    void doSomething();
    void doSomething1();
    void doSomething2();   
};

所以现在你原来的类有一个对象类型的成员变量:

  Feature _feature;

现在,如果你这样做很多次,你将有许多成员对象在你的主类。

现在,根据配置可能需要或不需要这些功能,因此在某种程度上,拥有所有这些可能需要或不需要的对象是昂贵的。

任何人都可以提出一种改进的方法?

编辑:根据建议使用空对象设计模式我想出了这个:

定义功能接口的抽象类:

class IFeature
{
public:
    virtual void doSomething()=0;
    virtual void doSomething1()=0;
    virtual void doSomething2()=0;
    virtual ~IFeature(){}
};

然后,我定义了两个实现接口的类,一个真正的实现和一个空对象:

class RealFeature:public IFeature
{
public:
    RealFeature(){};
    void doSomething(){std::cout<<"RealFeature doSomething()"<<std::endl;}
    void doSomething1(){std::cout<<"RealFeature doSomething()"<<std::endl;}
    void doSomething2(){std::cout<<"RealFeature doSomething()"<<std::endl;}
}; 
class NullFeature:public IFeature
{
public:
    NullFeature(){};
    void doSomething(){std::cout<<"NULL doSomething()"<<std::endl;};
    void doSomething1(){std::cout<<"NULL doSomething1()"<<std::endl;};
    void doSomething2(){std::cout<<"NULL doSomething2()"<<std::endl;};
};

然后我定义一个类,它将根据配置委托给真实对象或空对象:

class Feature:public IFeature
{
public:
    Feature();
    ~Feature();
    void doSomething();
    void doSomething1();
    void doSomething2();
private:
    std::auto_ptr<IFeature> _feature;
};

执行情况:

   Feature::Feature()
    {
        std::cout<<"Feature() CTOR"<<std::endl;
        if(configuration::isEnabled() )
        {
            _feature = auto_ptr<IFeature>( new RealFeature() );
        }
        else
        {
            _feature = auto_ptr<IFeature>( new NullFeature() );
        }
    }
    void Feature::doSomething()
    {
        _feature->doSomething();
    }
    //And so one for each of the implementation methods

然后我在我的主类中使用类(或任何需要的地方):

Feature _feature;
_feature.doSomething();
3

如果缺少一个功能,正确的做法是忽略这个事实,什么也不做,你可以使用Null Object pattern来摆脱你的检查:

class MainThing {
    IFeature _feature;
    void DoStuff() {
        _feature.Method1();
        _feature.Method2();
}
intece IFeature {
    void Method1();
    void Method2();
}
class SomeFeature { /* ... */ }
class NullFeature {
    void Method1() { /* do nothing */ }
    void Method2() { /* do nothing */ }
}

现在,在MainThing中,如果不存在可选功能,则为其提供对NullFeature的引用,而不是实际的null引用。这样,MainThing始终可以安全地假设_feature不是null

3

一个 auto_ptr 本身不会给你买太多。但是有一个指向一个对象的指针,你只有在需要的时候才懒洋洋地加载它。像:

class Foo {
private:
    Feature* _feature;
public:
    Foo() : _feature(NULL) {}
    Feature* getFeature() {
        if (! _feature) {
            _feature = new Feature();
        }
        return _feature;
    }
};

现在,如果您需要有关内存管理的帮助,可以将Feature*包装在智能指针中。但是关键不在内存管理中,而是延迟创建。这样做的好处是,您不必在启动过程中选择性地配置要创建的内容-只需按需付费即可。有时这就是您所需要的。

请注意,这个特定实现的一个缺点是,创建现在是在客户端第一次调用他们认为只是一个 getter 时进行的。如果创建对象很耗时,这可能会给您的客户端带来一些冲击,甚至是一个问题。它还使 getter 非 const,这也可能是一个问题。最后,它假设您拥有按需创建对象所需的一切,这可能是一个棘手的问题。

1

您的问题描述中有一个时刻,实际上会导致失败。如果您的功能不可用,则不应“just return”,应在调用之前检查功能的可用性!

尝试使用不同的方法设计主类。想想你的类的一些抽象描述符叫做FeatureMap或类似的东西,它实际上存储了当前类的可用功能。

当您实现FeatureMap时,一切都变得简单明了。只需确保(在调用之前),您的类具有此功能,然后才调用它。如果您遇到调用不受支持的功能的情况,请引发异常。

还要提一下,这个feature-lookup例程应该很快(我猜是这样),并且不会影响您的性能。

我不知道我是否直接回答你的问题(因为我对你的问题域没有任何想法,好吧,更好的解决方案总是特定于域),但希望这会让你以正确的方式思考。

1

关于您对 Null 对象模式的编辑:如果您已经有一个功能的公共接口 / 私有实现,那么创建一个 null 实现是没有意义的,因为公共接口可以是您的 null 实现,没有任何问题)。

具体来说,你可以有:

class FeatureImpl
{
public:
    void doSomething() { /*real work here*/ }
};
class Feature
{
    class FeatureImpl * _impl;
public:
    Feature() : _impl(0) {}
    void doSomething()
    {
        if(_impl)
            _impl->doSomething();
        // else case ... here's your null object implementation :)
    }
    // code to (optionally) initialize the implementation left out due to laziness
};

如果它是性能关键的,则此代码仅从 NULL 实现中受益(即使这样,if(_impl)的成本在大多数情况下也可以忽略不计)。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(670)
如何为c盘减肥:C编程:如何为Unicode编程
上一篇
Celebrate英文:如何将Celebrate验证错误记录到Express.js中的控制台
下一篇

相关推荐

  • in class教学反思:如何提高课堂教学的有效性

    in class教学反思是一种教学模式,它旨在提高学习者的学习效果,并使学习者能够更好地理解课程内容。它通过将学习者的思考、探索和反思与课堂教学结合起来,使学习者能够更好地理解课程内容,从而提高学习效果。…

    2023-06-11 08:47:04
    0 10 25
  • classicmug什么意思:经典马克杯,让你的生活更加精彩!

    示例示例是一种特殊的杯子,它有着经典的外观和质地,通常由陶瓷或金属制成。它可以用来装饮料,也可以用作装饰品。代码示例:…

    2023-06-22 07:14:29
    0 78 23
  • class的中文是什么意思:如何利用课堂学习提升学习成绩

    示例示例Class的中文意思是“类”,它是一种用于描述对象属性和行为的数据结构。类可以用来创建对象,并且可以用来定义对象的行为。下面是一个简单的类的示例:…

    2024-03-17 15:35:26
    0 17 22
  • class2青骄第二课堂:如何让学习变得更有效率?

    class2青骄第二课堂是一个全新的在线学习平台,旨在提供给中小学生一个有趣、安全的学习环境。它拥有一个简单易用的界面,支持多种教学模式,包括视频课程、在线测试、虚拟实验室等。它还支持在线互动,可以让学生与老师之间进行实时交流,提高学习效率。…

    2023-07-14 05:14:59
    0 43 63
  • first class是什么意思:享受一流服务,体验不一样的生活!

    First class是一种编程语言中的概念,指的是能够在程序中当作参数传递、返回值返回、变量存储的对象。它们可以被赋值给变量,也可以作为参数传递给函数,也可以作为函数的返回值。…

    2024-03-15 00:39:20
    0 99 34
  • java获取class路径:如何使用Java获取Class路径

    Java获取class路径的方法有多种,下面介绍几种常用的方法。方法一:使用Class类的()方法…

    2023-01-22 02:20:15
    0 35 62
  • rslinx classic授权:RSLinx Classic 许可授权

    RSLinx Classic授权是Rockwell Automation的软件授权,它可以帮助用户连接到Allen-Bradley PLCs,以便编程和监控。它可以从Rockwell Automation的网站上免费下载,但需要授权才能使用。…

    2023-04-09 15:03:50
    0 77 51
  • classd功放:如何选择适合自己的Class D功放

    Class D功放是一种效率很高的功放,它可以有效地将电源转换为声音。它的工作原理是通过开关技术来控制电流,从而实现高效率的转换。…

    2023-02-27 00:35:35
    0 48 26

发表评论

登录 后才能评论

评论列表(33条)