有什么设计模式可以解决仅向某些类公开几种方法的问题? [英] What is the design pattern to address the problem of exposing few methods to only certain classes?

查看:103
本文介绍了有什么设计模式可以解决仅向某些类公开几种方法的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我知道朋友的概念在OOP设计中是不可以的.
但是,有时在某些情况下,只有在类之间相互缠绕在一起的情况下,才允许某些朋友类访问某个类的某些方法.

例如,CGridCtrl的朋友类是CGridCellBase.要了解我在说哪个示例,请查看Chris Maunder撰写的与代码项目中CGridCtrl相关的文章.

因此,如果我要用不支持friend关键字的语言开发类似的东西,我如何确定CGridCtrl的某些方法只能由CGridCellBase类访问?解决方案

看看 [ http://www.cprogramming.com/tutorial/friends.html [ http://www.exforsys.com/tutorials/c- plus-plus/c-plus-plus-friend-functions.html [ http://www.devarticles. com/c/a/Cplusplus/C-plus-Tricks-of-Trade:-Friend-Functions/2/ [
祝你好运!


适配器或Bridge可以解决问题.确切的做法取决于您要适应或桥接的内容.如果您只是尝试公开一些方法,并且它们已经有了正确的界面,那么桥接就可以很好地工作.如果要公开某些方法,并且它们的签名不正确,请使用适配器.

正如埃里克(Eric)所说,代理服务器也可以正常工作-尽管通常认为代理服务器是通过某种敌对的"或非本机调用方式导出接口的一种方式.它就像一座桥梁,但跨越了外部沟通机制.

无论如何:

-bridge引入了另一个接口,其中仅包含您要从对象中导出的方法.然后,您可以从该接口派生实现,并将对该接口的引用传递给使用对象

-适配器通过您要使用的接口引入了一个具体的类.您可以使用要修改的类来实现该接口.您可以引入一个接口类,以真正将适应的类与使用的类隔离开来-是否执行实际上是一个品味问题,以及您愿意在消费者/适配器边界上泄漏多少实现的知识

使用bridge,您将不得不更改您要桥接的类.使用适配器,您将不会.通常,我会说您想要的是适配器,但桥接器将帮助您在代码中引入一个新概念,从而使分解变得更容易.

呃,对不起,这真的是意识流,不是吗?如果我可以(或者您希望我澄清),请大声喊叫.

干杯,



PS:我对这类事情的大部分经验都来自于C ++,所以我的注释可能不适用于一般的OO术语.

PPS:针对以下评论,这是我关于如何使用网桥的意思.假设我有一个类A,它使用类B的对象的接口的一部分:

class B
{
    public:
        void b_a();
        void b_b();
        void b_c();
};

class A
{
    public:
        void a_a( B &b )
        {
            b.b_a();
            b.b_c();
        }
};


因此您可以看到A不使用B :: b_b().实际上,它不需要B接口的某些部分.

因此,为了限制B A使用的位,我们可以定义一个新接口(桥接解决方案):

class I
{
    public:
        virtual void b_a() = 0;
        virtual void b_c() = 0;
};



从I派生B:

class B : public I
{
    public:
        void b_a();
        void b_b();
        void b_c();
};


然后将A转换为I,而不是B:

class A
{
    public:
        void a_a( I &i )
        {
            i.b_a();
            i.b_c();
        }
};


因此,每次调用A :: a_a时,仍可以将其传递给B,但是A不能使用B :: b_b(),因为它不是接口的一部分.

使用适配器是类似的,如果有任何里程,我可以补充一下.


Hi,

I know friend concept is a no no in OOP design.
But, sometimes there are cases where you''d allow access of certain methods of a class by certain friend classes only given the classes are very inter-twined to each other.

For example, CGridCtrl''s friend class is CGridCellBase. To understand, which example I am talking about, please have a look at the article by Chris Maunder related to CGridCtrl in code project.

So, if I were to develop something similar in a language which doesn''t support the friend keyword, how would I make sure, CGridCtrl''s certain methods are only accessible by CGridCellBase class only?

Have a look at "Is there a way to simulate the C++ friend concept in Java?"[^] at stackoverflow.
:)


As you can see the friend is declared for a certain type. This automatically closes this friend for other types. Like in the link below:

http://www.cprogramming.com/tutorial/friends.html[^]

To guarantee the same for certain methods you can define friend functions that have access to certain data, like:

http://www.exforsys.com/tutorials/c-plus-plus/c-plus-plus-friend-functions.html[^]

The same can be done for operators. Like this:
http://www.devarticles.com/c/a/Cplusplus/C-plus-Tricks-of-the-Trade:-Friend-Functions/2/[^]

Please study the above links very good and maybe try to find extra information about it. Sometimes it''s hard to see how this friend construction does the trick. It''s therefore considered a no no with a good reason because if you do not understand it completely, the code is unsafe and a big mess. (and c++ errors aren''t the most kind ones to understand).

Good luck!


Adapter or Bridge will do the trick. Exactly how you do it depends on what you''re trying to adapt or bridge. If you''re trying to just expose a few methods and they''ve got the right interface already then bridge works pretty well. If you want to expose some methods and their signatures are not quite the right shape then use an Adapter.

As Eric said proxy will work as well - although that''s usually regarded as a way of exporting an interface over some "hostile" or non-native way of calling it. It''s like a bridge but across an external communication mechanism.

Anyway:

- bridge introduces another interface with just the methods in you want to export from the object. You then derive your implementation from the interface and pass a reference to that interface to the consuming object

- adapter introduces a concrete class with the interface you want to consume. You implement that interface using the class to be adapted. You can introduce an interface class to really isolate the adapted class from the consuming class - whether you do that or not is really a matter of taste and how much knowledge of the implementation you''re willing to leak across the consumer/adapter boundary

With bridge you''ll have to change the class you''re bridging to. With adapter you won''t. Generally I''d say what you want is an adapter BUT a bridge will help introduce a new concept into your code which will make it easier to factor.

Er, sorry, that''s really stream of consciousness isn''t it? Please shout if I can (or rather if you''d like me to) clarify anything.

Cheers,

Ash

PS: Most of my experience of this sort of thing has been with C++ so my comments might not be appropriate in general OO terms.

PPS: In response to the comment below, here''s what I mean about how to use a bridge. Say I''ve got a class, A, that uses part of the interface of object of class B:

class B
{
    public:
        void b_a();
        void b_b();
        void b_c();
};

class A
{
    public:
        void a_a( B &b )
        {
            b.b_a();
            b.b_c();
        }
};


so you can see that A doesn''t use B::b_b(). Effectively it doesn''t need some part of the interface of B.

So to restrict what bits of B A uses we can define a new interface (the bridge solution):

class I
{
    public:
        virtual void b_a() = 0;
        virtual void b_c() = 0;
};



derive B from I:

class B : public I
{
    public:
        void b_a();
        void b_b();
        void b_c();
};


and convert A to use I, not B:

class A
{
    public:
        void a_a( I &i )
        {
            i.b_a();
            i.b_c();
        }
};


So everytime you call the A::a_a you can still pass it a B, but A can''t use B::b_b() as it''s not part of the interface.

Using an adapter is similar, I can add that if there''s any milage.


这篇关于有什么设计模式可以解决仅向某些类公开几种方法的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆