From here: http://www.oodesign.com/proxy-pattern.html
Applicability & Examples
The Proxy design pattern is applicable when there is a need to control
access to an Object, as well as when there is a need for a
sophisticated reference to an Object. Common Situations where the
proxy pattern is applicable are:
Virtual Proxies: delaying the creation and initialization of expensive
objects until needed, where the objects are created on demand (For
example creating the RealSubject object only when the doSomething
method is invoked).
Protection Proxies: where a proxy controls access to RealSubject
methods, by giving access to some objects while denying access to
others.
Smart References: providing a sophisticated access to certain objects
such as tracking the number of references to an object and denying
access if a certain number is reached, as well as loading an object
from database into memory on demand.
Well, can't Virtual Proxies be created by creating an individual function (other than the constructor) for a new object?
Can't Protection Proxies be created by simply making the function private, and letting only the derived classes get the accesses? OR through the friend class?
Can't Smart References be created by a static member variable which counts the number of objects created?
In which cases should the Proxy method be preferred on the access specifiers and inheritance?
What's the point that I am missing?
Your questions are a little bit abstract, and i'm not sure i can answer at all well, but here are my thoughts on each of them. Personally i dont agree that some of these things are the best designs for the job, but that isn't your question, and is a matter of opinion.
Virtual Proxies
I don't understand what you are trying to say here at all. The point of the pattern here is that you might have an object A that you know will take 100MB, and you don't know for sure that you will ever need to use this object.
To avoid allocating memory for this object until it is needed you create a dummy object B that implements the same interface as A, and if any of its methods are called B creates an instance of A, thus avoiding allocating memory until it is needed.
Protection Proxies
Here i think you have misunderstood the use of the pattern. The idea is to be able to dynamically control access to an object. For example you might want class A to be able to access class B's methods unless condition C is true. As i'm sure you can see this could not be achieved through the use of access specifiers.
Smart Referances
Here i think you misunderstand the need for smart pointers. As this is quite a complicated topic i will simply provide a link to a question about them: RAII and smart pointers in C++
If you have never programmed in a language like C where you manage your memory yourself then this might explain the confusion.
I hope this helps to answer some of your questions.
EDIT:
I didn't notice that this was tagged c++ so i assume you do in fact recognize the need to clean up dynamic memory. The single static reference count will only work if you only intend to ever have one instance of your object. If you create 2000 instances of an object, and then deleted 1999 of them none of them would have their memory freed until the last one left scope which is clearly not desirable (That is assuming you had kept track of the locations of all the allocated memory in order to be able to free it!).
EDIT 2:
Say you have a class as follows:
class A {
public:
static int refcount;
int* allocated_memory;
A() {
++refcount;
allocated_memory = new int[100000000];
}
~A() {
if(! --refcount) {
delete [] allocated_memory;
}
}
}
And some code that uses it:
int main() {
A problem_child; // After this line refcount == 1
while(true) {
A in_scope; // Here refcount == 2
} // We leave scope and refcount == 1.
// NOTE: in_scope.allocated_memory is not deleted
// and we now have no pointer to it. Leak!
return;
}
As you can see in the code refcount counts all references to all objects, and this results in a memory leak. I can explain further if you need, but this is really a seperate question in its own right.
I am no expert, but here are my thoughts on Virtual Proxies : If we control the initialization via a separate function say bool Create(); then the responsibility and control of Initialization lies with the client of the class. With virtual proxies , the goal is to retain creation control within the class, without client being aware of that.
Protection Proxies: The Subject being protected might have different kinds of clients, ones which need to get unprotected/unrestricted access to all Subject methods and the others which should be allowed access to a subset of methods hence need for Protection proxy.
A proxy is an object behaving as a different object to add some control/behavior. A smart pointer is a good example: it accesses the object as if you would use a raw pointer, but it also controls the lifetime of that object.
It's good to question whether there are alternatives to standard solutions to problems. Design Patterns represent solutions that have worked for many folks and have the advantage that there's a good chance that an experienced programmer coming to the code will recognize the pattern and so find maintaining the code easier. However, all designs represent trade-offs and patterns have costs. So you are right to challenge the use of patterns and consider alternatives.
In many cases design is not just about making code work, but considering how it is structured. Which piece of code "knows" what. You proposal for an alternative for Virtual Prozy moves (as fizzbuzz says) knowledge of creation from the proxy to the client - the client has to "know" to call Create() and so is aware of the life-cycle of the class. Whereas with the proxy he just makes an object that he treats as the worker, then invisibly creation happens when the proxy decides it makes sense. This refactoring of responsibility into the proxy is found to valuable, it allows us in the future to change those life-cycle rules without changing any clients.
Protection proxy: your proposal requires that clients have an inheritance relationship so that they can use protected methods. Generally speaking that couples client and worker too tightly, so we introduce a proxy.
Smart reference: no, a single static count is no good. You need to count references to individual instances.
If you carefully work through each case you will find there are merits to the design patterns. If you try to implement an alternative you start with some code that sems simpler that the design pattern and then discover that as you start to refactor and improve the code, removing deuplicationand so on you end up reinventing the design pattern - and that's a really nice outcome.
Related
I've taken over some legacy C++ code (written in C++03) which is for an application that runs on an RTOS. While browsing the codebase, I came across a construct like this:
...
new UserDebug(); ///<User debug commands.
...
Where the allocation done using new isn't stored anywhere so I looked a bit deeper and found this
class UserDebug
{
public:
///Constructor
UserDebug()
{
new AdvancedDebug();
new CameraCommand();
new CameraSOG();
new DebugCommandTest();
new DebugCommand();
// 30 more new objects like this
};
virtual ~UserDebug(){};
};
I dug deeper into each of the class definitions and implementations mentioned and couldn't find any reference to delete anywhere.
This code was written by the principal software engineer (who has left our company).
Can anyone shed some ideas on why you would want to do something like this and how does it work?
Thanks
If you look into the constructors of those classes you’ll see that they have interesting side effects, either registering themselves with some manager class or storing themselves in static/global pointer variables á la singletons.
I don’t like that they’ve chosen to do things that way - it violates the Principle of Least Surprise - but it isn’t really a problem. The memory for the objects is probably (but not necessarily) leaked, but they’re probably meant to exist for the lifetime of the executable so no big deal.
(It’s also possible that they have custom operator news which do something even odder, like constructing into preallocated static/global storage, though that’s only somewhat relevant to the ‘why’.)
If these objects created once they might be expected to have the lifetime of the application (similar to singletons) and thus should never be deleted.
Another way to capture pointer is through overloaded operator new: both global and class specific. Check if there are any overloads that implement some sort of garbage collection.
I've got some code that is using shared_ptr quite widely as the standard way to refer to a particular type of object (let's call it T) in my app. I've tried to be careful to use make_shared and std::move and const T& where I can for efficiency. Nevertheless, my code spends a great deal of time passing shared_ptrs around (the object I'm wrapping in shared_ptr is the central object of the whole caboodle). The kicker is that pretty often the shared_ptrs are pointing to an object that is used as a marker for "no value"; this object is a global instance of a particular T subclass, and it lives forever since its refcount never goes to zero.
Using a "no value" object is nice because it responds in nice ways to various methods that get sent to these objects, behaving in the way that I want "no value" to behave. However, performance metrics indicate that a huge amount of the time in my code is spent incrementing and decrementing the refcount of that global singleton object, making new shared_ptrs that refer to it and then destroying them. To wit: for a simple test case, the execution time went from 9.33 seconds to 7.35 seconds if I stuck nullptr inside the shared_ptrs to indicate "no value", instead of making them point to the global singleton T "no value" object. That's a hugely important difference; run on much larger problems, this code will soon be used to do multi-day runs on computing clusters. So I really need that speedup. But I'd really like to have my "no value" object, too, so that I don't have to put checks for nullptr all over my code, special-casing that possibility.
So. Is there a way to have my cake and eat it too? In particular, I'm imagining that I might somehow subclass shared_ptr to make a "shared_immortal_ptr" class that I could use with the "no value" object. The subclass would act just like a normal shared_ptr, but it would simply never increment or decrement its refcount, and would skip all related bookkeeping. Is such a thing possible?
I'm also considering making an inline function that would do a get() on my shared_ptrs and would substitute a pointer to the singleton immortal object if get() returned nullptr; if I used that everywhere in my code, and never used * or -> directly on my shared_ptrs, I would be insulated, I suppose.
Or is there another good solution for this situation that hasn't occurred to me?
Galik asked the central question that comes to mind regarding your containment strategy. I'll assume you've considered that and have reason to rely on shared_ptr as a communical containment strategy for which no alternative exists.
I have to suggestions which may seem controversial. What you've defined is that you need a type of shared_ptr that never has a nullptr, but std::shared_ptr doesn't do that, and I checked various versions of the STL to confirm that the customer deleter provided is not an entry point to a solution.
So, consider either making your own smart pointer, or adopting one that you change to suit your needs. The basic idea is to establish a kind of shared_ptr which can be instructed to point it's shadow pointer to a global object it doesn't own.
You have the source to std::shared_ptr. The code is uncomfortable to read. It may be difficult to work with. It is one avenue, but of course you'd copy the source, change the namespace and implement the behavior you desire.
However, one of the first things all of us did in the middle 90's when templates were first introduced to the compilers of the epoch was to begin fashioning containers and smart pointers. Smart pointers are remarkably easy to write. They're harder to design (or were), but then you have a design to model (which you've already used).
You can implement the basic interface of shared_ptr to create a drop in replacement. If you used typedefs well, there should be a limited few places you'd have to change, but at least a search and replace would work reasonably well.
These are the two means I'm suggesting, both ending up with the same feature. Either adopt shared_ptr from the library, or make one from scratch. You'd be surprised how quickly you can fashion a replacement.
If you adopt std::shared_ptr, the main theme would be to understand how shared_ptr determines it should decrement. In most implementations shared_ptr must reference a node, which in my version it calls a control block (_Ref). The node owns the object to be deleted when the reference count reaches zero, but naturally shared_ptr skips that if _Ref is null. However, operators like -> and *, or the get function, don't bother checking _Ref, they just return the shadow, or _Ptr in my version.
Now, _Ptr will be set to nullptr (or 0 in my source) when a reset is called. Reset is called when assigning to another object or pointer, so this works even if using assignment to nullptr. The point is, that for this new type of shared_ptr you need, you could simply change the behavior such that whenever that happens (a reset to nullptr), you set _Ptr, the shadow pointer in shared_ptr, to the "no value global" object's address.
All uses of *,get or -> will return the _Ptr of that no value object, and will correctly behave when used in another assignment, or reset is called again, because those functions don't rely upon the shadow pointer to act upon the node, and since in this special condition that node (or control block) will be nullptr, the rest of shared_ptr would behave as though it was pointing to nullptr correctly - that is, not deleting the global object.
Obviously this sounds crazy to alter std::pointer to such application specific behavior, but frankly that's what performance work tends to make us do; otherwise strange things, like abandoning C++ occasionally in order to obtain the more raw speed of C, or assembler.
Modifying std::shared_ptr source, taken as a copy for this special purpose, is not what I would choose (and, factually, I've faced other versions of your situation, so I have made this choice several times over decades).
To that end, I suggest you build a policy based smart pointer. I find it odd I suggested this earlier on another post today (or yesterday, it's 1:40am).
I refer to Alexandrescu's book from 2001 (I think it was Modern C++...and some words I don't recall). In that he presented loki, which included a policy based smart pointer design, which is still published and freely available on his website.
The idea should have been incorporated into shared_ptr, in my opinion.
Policy based design is implemented as the paradigm of a template class deriving from one or more of it's parameters, like this:
template< typename T, typename B >
class TopClass : public B {};
In this way, you can provide B, from which the object is built. Now, B may have the same construction, it may also be a policy level which derives from it's second parameter (or multiple derivations, however the design works).
Layers can be combined to implement unique behaviors in various categories.
For example:
std::shared_ptr and std::weak_ptrare separate classes which interact as a family with others (the nodes or control blocks) to provide smart pointer service. However, in a design I used several times, these two were built by the same top level template class. The difference between a shared_ptr and a weak_ptr in that design was the attachment policy offered in the second parameter to the template. If the type is instantiated with the weak attachment policy as the second parameter, it's a weak pointer. If it's given a strong attachment policy, it's a smart pointer.
Once you create a policy designed template, you can introduce layers not in the original design (expanding it), or to "intercept" behavior and specialize it like the one you currently require - without corrupting the original code or design.
The smart pointer library I developed had high performance requirements, along with a number of other options including custom memory allocation and automatic locking services to make writing to smart pointers thread safe (which std::shared_ptr doesn't provide). The interface and much of the code is shared, yet several different kinds of smart pointers could be fashioned simply by selecting different policies. To change behavior, a new policy could be inserted without altering the existing code. At present, I use both std::shared_ptr (which I used when it was in boost years ago) and the MetaPtr library I developed years ago, the latter when I need high performance or flexible options, like yours.
If std::shared_ptr had been a policy based design, as loki demonstrates, you'd be able to do this with shared_ptr WITHOUT having to copy the source and move it to a new namespace.
In any event, simply creating a shared pointer which points the shadow pointer to the global object on reset to nullptr, leaving the node pointing to null, provides the behavior you described.
What is a good way to share an instance of an object between several classes in a class hierarchy? I have the following situation:
class texture_manager;
class world {
...
std::vector<object> objects_;
skybox skybox_;
}
I currently implemented texture_manager as a singleton, and clients call its instancing method from anywhere in the code. texture_manager needs to be used by objects in the objects_ vector, by skybox_, and possibly by other classes as well that may or may not be part of the world class.
As I am trying to limit the use of singletons in my code, do you recommend any alternatives to this approach? One solution that came to mind would be to pass a texture_manager reference as an argument to the constructors of all classes that need access to it. Thanks.
The general answer to that question is to use ::std::shared_ptr. Or if you don't have that, ::std::tr1::shared_ptr, or if you don't have that, ::boost::shared_ptr.
In your particular case, I would recommend one of a few different approaches:
One possibility is, of course, the shared_ptr approach. You basically pass around your pointer to everybody who needs the object, and it's automatically destroyed when none of them need it anymore. Though if your texture manager is going to end up with pointers to the objects pointing at it, you're creating a reference cycle, and that will have to be handled very carefully.
Another possibility is just to declare it as a local variable in main and pass it as a pointer or reference to everybody who needs it. It won't be going away until your program is finished that way, and you shouldn't have to worry about managing the lifetime. A bare pointer or reference is just fine in this case.
A third possibility is one of the sort of vaguely acceptable uses of something sort of like a singleton. And this deserves a detailed explanation.
You make a singleton who's only job is to hand out useful pointers to things. A key feature it has is the ability to tell it what thing to hand out a pointer to. It's kind of like a global configurable factory.
This allows you to escape from the huge testing issues you create with a singleton in general. Just tell it to hand out a pointer to a stub object when it comes time to test things.
It also allows you to escape from the access control/security issue (yes, they create security issues as well) that a singleton represents for the same reason. You can temporarily tell it to pass out a pointer to an object that doesn't allow access to things that the section of code you're about to execute doesn't need access to. This idea is generally referred to as the principle of least authority.
The main reason to use this is that it saves you the problem of figuring out who needs your pointer and handing it to them. This is also the main reason not to use it, thinking that through is good for you. You also introduce the possibility that two things that expected to get the same pointer to a texture manager actually get pointers to a different texture manager because of a control flow you didn't anticipate, which is basically the result of the sloppy thinking that caused you to use the Singleton in the first place. Lastly, Singletons are so awful, that even this more benign use of them makes me itchy.
Personally, in your case, I would recommend approach #2, just creating it on the stack in main and passing in a pointer to wherever it's needed. It will make you think more carefully about the structure of your program, and this sort of object should probably live for your entire program's lifetime anyway.
I know what is the difference and how they both work but this question is more about coding style.
Whenever I'm coding I make many classes, they all have variables and some of them are pointers and some are normal variables. I usually prefer variables to pointers if that members lasts as long as the class does but then my code becomes like this:
engine->camera.somevar->x;
// vs
engine->camera->somevar->x;
I don't like the dot in the middle. Or with private variables:
foo_.getName();
// vs
foo_->gatName();
I think that dot "disappears" in a long code. I find -> easier to read in some cases.
My question would be if you use pointers even if the variable is going to be created in the constructor and deleted in the destructor? Is there any style advice in this case?
P.S. I do think that dot is looks better in some cases.
First of all it is bad form to expose member variables.
Second your class should probably never container pointers.
Slight corolary: Classes that contain business logic should never have pointers (as this means they also contain pointer management code and pointer management code should be left to classes that have no business logic but are designed specifically for the purpose of managing pointers (smart pointers and containers).
Pointer management classes (smart pointers/containers) should be designed to manage a single pointer. Managing more than one is much more difficult than you expect and I have yet to find a situation where the extra complexity paid off.
Finally public members should not expose the underlying implementation (you should not provide access to members even via getters/setters). This binds the interface to tightly to the implementation. Instead your public interface should provide a set of actions that can be performed on the object. i.e. methods are verbs.
In C++ it is rare to see pointers.
They are generally hidden inside other classes. But you should get used to using a mixture of -> and . as it all depends on context and what you are trying to convey. As long as the code is clean and readable it does not matter too much.
A personal addendum:
I hate the _ at then end of your identifier it makes the . disapear foo_.getName() I think it would look a lot better as foo.getName()
If the "embedded" struct has exactly the same lifetime as the "parent" struct and it is not referenced anywhere else, I prefer to have it as a member, rather than use a pointer. The produced code is slightly more efficient, since it saves a number of calls to the memory allocator and it avoids a number of pointer dereferences.
It is also easier to handle, since the chance of pointer-related mistakes is reduced.
If, on the other hand, there is the slightest chance that the embedded structure may be referenced somewhere else I prefer to use a separate struct and pointers. That way I won't have to refactor my code if it turns out that the embedded struct needs to be pulled out from its parent.
EDIT:
I guess that means that I usually go with the pointer alternative :-)
EDIT 2:
And yes, my answer is assuming that you really want (or have) to chose between the two i.e. that you write C-style code. The proper object-oriented way to access class members is through get/set functions.
My comments regarding whether to include an actual class instance or a pointer/reference to one are probably still valid, however.
You should not make your choice because you find '->' easier to read :)
Using a member variable is usually better as you can not make mistakes with you pointer.
This said, using a member variable force you to expose your implementation, thus you have to use references. But then you have to initialize then in your constructor, which is not always possible ...
A solution is to use std::auto_ptr or boost::scoped_ptr ot similar smart pointer. There you will get advantage of both solution, with very little drawbacks.
my2c
EDIT:
Some useful links :
Article on std::auto_ptr
boost::scoped_ptr
Pimpl : private implementation
Ideally, you shouldn't use either: you should use getter/setter methods. The performance hit is minimal (the compiler will probably optimize it away, anyway).
The second consideration is that using pointers is a generally dangerous idea, because at some point you're likely to screw it up.
If neither of these faze you, then I'd say all that's left is a matter of personal preference.
This is also a question that I asked in a comment in one of Miško Hevery's google talks that was dealing with dependency injection but it got buried in the comments.
I wonder how can the factory / builder step of wiring the dependencies together can work in C++.
I.e. we have a class A that depends on B. The builder will allocate B in the heap, pass a pointer to B in A's constructor while also allocating in the heap and return a pointer to A.
Who cleans up afterwards? Is it good to let the builder clean up after it's done? It seems to be the correct method since in the talk it says that the builder should setup objects that are expected to have the same lifetime or at least the dependencies have longer lifetime (I also have a question on that). What I mean in code:
class builder {
public:
builder() :
m_ClassA(NULL),m_ClassB(NULL) {
}
~builder() {
if (m_ClassB) {
delete m_ClassB;
}
if (m_ClassA) {
delete m_ClassA;
}
}
ClassA *build() {
m_ClassB = new class B;
m_ClassA = new class A(m_ClassB);
return m_ClassA;
}
};
Now if there is a dependency that is expected to last longer than the lifetime of the object we are injecting it into (say ClassC is that dependency) I understand that we should change the build method to something like:
ClassA *builder::build(ClassC *classC) {
m_ClassB = new class B;
m_ClassA = new class A(m_ClassB, classC);
return m_ClassA;
}
What is your preferred approach?
This talk is about Java and dependency injection.
In C++ we try NOT to pass RAW pointers around. This is because a RAW pointer have no ownership semantics associated with it. If you have no ownership then we don't know who is responsible for cleaning up the object.
I find that most of the time dependency injection is done via references in C++.
In the rare cases where you must use pointers, wrap them in std::unique_ptr<> or std::shared_ptr<> depending on how you want to manage ownership.
In case you cannot use C++11 features, use std::auto_ptr<> or boost::shared_ptr<>.
I would also point out that C++ and Java styles of programming are now so divergent that applying the style of one language to the other will inevitably lead to disaster.
This is interesting, DI in C++ using templates:
http://adam.younglogic.com/?p=146
I think the author is making the right moves as to not translate Java DI into C++ too literally. Worth the read.
I've recently been bitten by the DI bug. I think it solves a lot of complexity problems, especially the automated part. I've written a prototype which lets you use DI in a pretty C++ way, or at least I think so. You can take a look at the code example here: http://codepad.org/GpOujZ79
The things that are obviously missing: no scoping, no binding of interface to implementation. The latter is pretty easy to solve, the former, I've no idea.
I'd be grateful if anyone here has an opinion on the code.
Use RAII.
Handing a raw pointer to someone is the same as handing them ownership. If that's not what you want to do, you should give them some kind of facade that also knows how to clean up the object in question.
shared_ptr<> can do this; the second argument of its constructor can be a function object that knows how to delete the object.
In C++, normally, when you done things right, you don't need to write destructors at all in most cases. You should use smart pointers to delete things automatically. I think, builder don't looks like the owner of the ClassA and ClassB instances. If you don't like to use smart pointers, you should think about objects life time and their owners.
Things get complicated if you don't settle on the question of ownership once and for all. You will simply have to decide in your implementation if it's possible that dependencies live longer than the objects they are injected into.
Personally I'd say no: the object into which the dependency is injected will clean up afterwards. Trying to do it through the builder means that the builder will have to live longer than both the dependency and the object into which it is injected. This causes more problems than it solves, in my opinion, because the builder does not serve any more useful purpose after the construction with the dependency injection has been completed.
Based on my own experience, it is best to have clear ownership rules. For small concrete objects, it is best to use direct copy to avoid cross dependency.
Sometimes cross dependency is unavoidable, and there is no clear ownership. For example, (m) A instances own (n) B instances, and certain B instances can be owned by multiple As. In this case, the best approach is to apply reference counting to B, in the way similar to COM reference counting. Any functions that take possession of B* must increase reference count first, and decrease it when releasing the possession.
I also avoid using boost::shared_ptr as it creates a new type (shared_ptr and B* become two distinct types). I found that it brings more headaches when I add methods.
You can also check the FFEAD Dependency Injection. It provides DI on the lines of Spring for JAVA and has a non-obtrusive way of dealing with things. It also has a lot of other important features like in-built AJAX Support,Reflection,Serialization,C++ Interpreter,Business Components For C++,ORM,Messaging,Web-Services,Thread-Pools and an Application Server that supports all these features.