DI: rework dependency-injection configuration in terms of the new DependencyFactory
why is this so damn hard to get right?
This commit is contained in:
parent
88e37d5681
commit
b3d18c1a74
6 changed files with 212 additions and 166 deletions
|
|
@ -160,6 +160,7 @@ namespace lib {
|
|||
|
||||
public:
|
||||
/** configure dependency-injection for type SRV to build a subclass singleton
|
||||
* @note actually a delegation to `Depend<SUB>` is installed into `Depend<SRV>`
|
||||
* @tparam SUB concrete subclass type to build on demand when invoking `Depend<SRV>`
|
||||
* @throws error::Logic (LUMIERA_ERROR_LIFECYCLE) when the default factory has already
|
||||
* been invoked at the point when calling this (re)configuration function.
|
||||
|
|
@ -168,11 +169,14 @@ namespace lib {
|
|||
static void
|
||||
useSingleton()
|
||||
{
|
||||
installFactory ([]{ return & Depend<SUB>{}(); });
|
||||
__assert_compatible<SUB>();
|
||||
installFactory<SUB>();
|
||||
}
|
||||
|
||||
/** configure dependency-injection for type SRV to manage a subclass singleton,
|
||||
* which is created lazily on demand by invoking the given builder function
|
||||
* @note actual Subclass type is determined from the given functor and then
|
||||
* a delegation to `Depend<Subclass>` is installed into `Depend<SRV>`
|
||||
* @param ctor functor to create a heap allocated instance of subclass
|
||||
* @throws error::Logic (LUMIERA_ERROR_LIFECYCLE) when the default factory has already
|
||||
* been invoked at the point when calling this (re)configuration function.
|
||||
|
|
@ -181,11 +185,11 @@ namespace lib {
|
|||
static void
|
||||
useSingleton(FUN&& ctor)
|
||||
{
|
||||
using Fun = typename SubclassFactory<FUN>::Fun;
|
||||
using Sub = typename SubclassFactory<FUN>::Sub;
|
||||
__assert_compatible<Sub>();
|
||||
using Fun = typename SubclassFactoryType<FUN>::Fun;
|
||||
using Sub = typename SubclassFactoryType<FUN>::Sub;
|
||||
|
||||
installFactory (buildCustomSingleton<Sub,Fun> (forward<FUN> (ctor)));
|
||||
__assert_compatible<Sub>();
|
||||
installFactory<Sub,Fun> (forward<FUN> (ctor));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -258,7 +262,7 @@ namespace lib {
|
|||
std::unique_ptr<MOC> mock_;
|
||||
|
||||
SRV* origInstance_;
|
||||
Factory origFactory_;
|
||||
DependencyFactory<SRV> origFactory_;
|
||||
|
||||
public:
|
||||
Local()
|
||||
|
|
@ -270,7 +274,7 @@ namespace lib {
|
|||
Local (FUN&& buildInstance)
|
||||
{
|
||||
__assert_compatible<MOC>();
|
||||
__assert_compatible<typename SubclassFactory<FUN>::Sub>();
|
||||
__assert_compatible<typename SubclassFactoryType<FUN>::Sub>();
|
||||
|
||||
temporarilyInstallAlternateFactory (origInstance_, origFactory_
|
||||
,[=]()
|
||||
|
|
@ -281,7 +285,7 @@ namespace lib {
|
|||
}
|
||||
~Local()
|
||||
{
|
||||
restoreOriginalFactory (origInstance_, origFactory_);
|
||||
restoreOriginalFactory (origInstance_, move(origFactory_));
|
||||
}
|
||||
|
||||
explicit
|
||||
|
|
@ -322,8 +326,17 @@ namespace lib {
|
|||
,"Installed implementation class must be compatible to the interface.");
|
||||
}
|
||||
|
||||
static void
|
||||
__ensure_pristine()
|
||||
{
|
||||
if (Depend<SRV>::instance)
|
||||
throw error::Logic("Attempt to reconfigure dependency injection after the fact. "
|
||||
"The previously installed factory (typically Singleton) was already used."
|
||||
, error::LUMIERA_ERROR_LIFECYCLE);
|
||||
}
|
||||
|
||||
template<typename FUN>
|
||||
struct SubclassFactory
|
||||
struct SubclassFactoryType
|
||||
{
|
||||
static_assert (meta::_Fun<FUN>(),
|
||||
"Need a Lambda or Function object to create a heap allocated instance");
|
||||
|
|
@ -337,49 +350,53 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
template<class SUB, typename FUN>
|
||||
static void
|
||||
installFactory (Factory&& otherFac)
|
||||
installFactory (FUN&& ctor)
|
||||
{
|
||||
Lock guard;
|
||||
if (Depend<SRV>::instance)
|
||||
throw error::Logic("Attempt to reconfigure dependency injection after the fact. "
|
||||
"The previously installed factory (typically Singleton) was already used."
|
||||
, error::LUMIERA_ERROR_LIFECYCLE);
|
||||
Depend<SRV>::factory = move (otherFac);
|
||||
}
|
||||
|
||||
/** wrap custom factory function to plant a singleton instance
|
||||
* @remark call through this intermediary function because we need to capture a _copy_ of the functor,
|
||||
* to invoke it later, on-demand. Especially we need the ability to change the type of this functor,
|
||||
* since sometimes the argument is passed as function reference, which can not be instantiated,
|
||||
* but needs to be wrapped into a std::function. */
|
||||
template<class SUB, class FUN>
|
||||
static Factory
|
||||
buildCustomSingleton (FUN&& ctor)
|
||||
{
|
||||
static std::unique_ptr<SUB> singleton;
|
||||
return ([ctor]() // copy of ctor in the closure
|
||||
{
|
||||
singleton.reset (ctor());
|
||||
return singleton.get();
|
||||
});
|
||||
if (std::is_same<SRV,SUB>())
|
||||
{
|
||||
__ensure_pristine();
|
||||
Depend<SRV>::factory.defineCreatorAndManage (forward<FUN> (ctor));
|
||||
}
|
||||
else
|
||||
{
|
||||
__ensure_pristine();
|
||||
Depend<SRV>::factory.defineCreator ([]{ return & Depend<SUB>{}(); });
|
||||
DependInject<SUB>::useSingleton (forward<FUN> (ctor));
|
||||
} // delegate actual instance creation to Depend<SUB>
|
||||
}
|
||||
|
||||
template<class SUB>
|
||||
static void
|
||||
temporarilyInstallAlternateFactory (SRV*& stashInstance, Factory& stashFac, Factory&& newFac)
|
||||
installFactory ()
|
||||
{
|
||||
if (not std::is_same<SRV,SUB>())
|
||||
{
|
||||
Lock guard;
|
||||
__ensure_pristine();
|
||||
Depend<SRV>::factory.defineCreator ([]{ return & Depend<SUB>{}(); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename FUN>
|
||||
static void
|
||||
temporarilyInstallAlternateFactory (SRV*& stashInstance, Factory& stashFac, FUN&& newFac)
|
||||
{
|
||||
Lock guard;
|
||||
stashFac = move(Depend<SRV>::factory);
|
||||
stashFac = move(Depend<SRV>::factory); //////////////////////////////////////TICKET #1059 : GCC-4.9 stubbornly picks the copy assignment
|
||||
stashInstance = Depend<SRV>::instance;
|
||||
Depend<SRV>::factory = move(newFac);
|
||||
Depend<SRV>::factory.defineCreator (forward<FUN>(newFac)); //////////////////////////////////////TICKET #1059 : GCC-4.9 stubbornly picks the copy assignment
|
||||
Depend<SRV>::instance = nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
restoreOriginalFactory (SRV*& stashInstance, Factory& stashFac)
|
||||
restoreOriginalFactory (SRV*& stashInstance, Factory&& stashFac)
|
||||
{
|
||||
Lock guard;
|
||||
Depend<SRV>::factory = move(stashFac);
|
||||
Depend<SRV>::factory = move(stashFac); //////////////////////////////////////TICKET #1059 : GCC-4.9 stubbornly picks the copy assignment
|
||||
Depend<SRV>::instance = stashInstance;
|
||||
}
|
||||
|
||||
|
|
@ -392,7 +409,7 @@ namespace lib {
|
|||
"but another instance has already been dependency-injected."
|
||||
, error::LUMIERA_ERROR_LIFECYCLE);
|
||||
Depend<SRV>::instance = &newInstance;
|
||||
Depend<SRV>::factory = Depend<SRV>::disabledFactory;
|
||||
Depend<SRV>::factory.disable();
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -400,7 +417,7 @@ namespace lib {
|
|||
{
|
||||
Lock guard;
|
||||
Depend<SRV>::instance = nullptr;
|
||||
Depend<SRV>::factory = Depend<SRV>::disabledFactory;
|
||||
Depend<SRV>::factory.disable();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace lib {
|
|||
*/
|
||||
template<class OBJ>
|
||||
class DependencyFactory
|
||||
: util::MoveOnly
|
||||
// : util::MoveAssign //////////////////////////////////////////////TICKET #1059 : GCC-4.9 stubbornly picks the copy assignment
|
||||
{
|
||||
using Creator = std::function<OBJ*()>;
|
||||
using Deleter = std::function<void()>;
|
||||
|
|
@ -126,11 +126,6 @@ namespace lib {
|
|||
deleter_();
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return bool(creator_);
|
||||
}
|
||||
|
||||
OBJ*
|
||||
operator() ()
|
||||
{
|
||||
|
|
@ -138,15 +133,37 @@ namespace lib {
|
|||
: buildAndManage();
|
||||
}
|
||||
|
||||
OBJ*
|
||||
buildAndManage()
|
||||
template<typename FUN>
|
||||
void
|
||||
defineCreator (FUN&& ctor)
|
||||
{
|
||||
OBJ* obj = buildInstance<OBJ>();
|
||||
atDestruction ([obj]{ delete obj; });
|
||||
creator_ = std::forward<FUN> (ctor);
|
||||
}
|
||||
|
||||
template<typename FUN>
|
||||
DependencyFactory&
|
||||
void
|
||||
defineCreatorAndManage (FUN&& ctor)
|
||||
{
|
||||
creator_ = [this,ctor]
|
||||
{
|
||||
OBJ* obj = ctor();
|
||||
atDestruction ([obj]{ delete obj; });
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
disable()
|
||||
{
|
||||
creator_ = []() -> OBJ*
|
||||
{
|
||||
throw error::Fatal("Service not available at this point of the Application Lifecycle"
|
||||
,error::LUMIERA_ERROR_LIFECYCLE);
|
||||
};
|
||||
}
|
||||
|
||||
template<typename FUN>
|
||||
void
|
||||
atDestruction (FUN&& additionalAction)
|
||||
{
|
||||
if (deleter_)
|
||||
|
|
@ -160,10 +177,24 @@ namespace lib {
|
|||
}
|
||||
else
|
||||
deleter_ = std::forward<FUN> (additionalAction);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
OBJ*
|
||||
buildAndManage()
|
||||
{
|
||||
OBJ* obj = buildInstance<OBJ>();
|
||||
atDestruction ([obj]{ delete obj; });
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<class TAR>
|
||||
static meta::enable_if<std::is_constructible<TAR>,
|
||||
TAR* >
|
||||
buildInstance()
|
||||
{
|
||||
return new TAR;
|
||||
}
|
||||
template<class ABS>
|
||||
static meta::enable_if<std::is_abstract<ABS>,
|
||||
ABS* >
|
||||
|
|
@ -172,21 +203,14 @@ namespace lib {
|
|||
throw error::Fatal("Attempt to create a singleton instance of an abstract class. "
|
||||
"Application architecture or lifecycle is seriously broken.");
|
||||
}
|
||||
template<class TAR>
|
||||
static meta::disable_if<std::is_abstract<TAR>,
|
||||
TAR* >
|
||||
template<class ABS>
|
||||
static meta::disable_if<std::__or_<std::is_abstract<ABS>,std::is_constructible<ABS>>,
|
||||
ABS* >
|
||||
buildInstance()
|
||||
{
|
||||
return new TAR;
|
||||
throw error::Fatal("Desired singleton class is not default constructible. "
|
||||
"Application architecture or lifecycle is seriously broken.");
|
||||
}
|
||||
|
||||
static void
|
||||
destroy (OBJ* obj)
|
||||
{
|
||||
if (obj)
|
||||
delete obj;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -214,11 +238,11 @@ namespace lib {
|
|||
template<class SRV>
|
||||
class Depend
|
||||
{
|
||||
using Factory = std::function<SRV*()>;
|
||||
using Factory = DependencyFactory<SRV>;
|
||||
using Lock = ClassLock<SRV, NonrecursiveLock_NoWait>;
|
||||
|
||||
static std::atomic<SRV*> instance;
|
||||
static Factory factory;
|
||||
static DependencyFactory<SRV> factory;
|
||||
|
||||
friend class DependInject<SRV>;
|
||||
|
||||
|
|
@ -240,75 +264,15 @@ namespace lib {
|
|||
object = instance.load (std::memory_order_relaxed);
|
||||
if (!object)
|
||||
{
|
||||
if (!factory)
|
||||
{
|
||||
object = buildInstance<SRV>();
|
||||
deleter = []{
|
||||
destroy (instance);
|
||||
instance = nullptr;
|
||||
};
|
||||
}
|
||||
else
|
||||
object = factory();
|
||||
factory = disabledFactory;
|
||||
object = factory();
|
||||
factory.disable();
|
||||
factory.atDestruction([]{ instance = nullptr; });
|
||||
}
|
||||
instance.store (object, std::memory_order_release);
|
||||
}
|
||||
ENSURE (object);
|
||||
return *object;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/** @internal preconfigured factory to block any (further) on-demand instance creation */
|
||||
static SRV*
|
||||
disabledFactory()
|
||||
{
|
||||
throw error::Fatal("Service not available at this point of the Application Lifecycle"
|
||||
,error::LUMIERA_ERROR_LIFECYCLE);
|
||||
}
|
||||
|
||||
template<class ABS>
|
||||
static meta::enable_if<std::is_abstract<ABS>,
|
||||
ABS* >
|
||||
buildInstance()
|
||||
{
|
||||
throw error::Fatal("Attempt to create a singleton instance of an abstract class. "
|
||||
"Application architecture or lifecycle is seriously broken.");
|
||||
}
|
||||
template<class TAR>
|
||||
static meta::disable_if<std::is_abstract<TAR>,
|
||||
TAR* >
|
||||
buildInstance()
|
||||
{
|
||||
return new TAR;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy (SRV* obj)
|
||||
{
|
||||
if (obj)
|
||||
delete obj;
|
||||
}
|
||||
|
||||
class Deleter
|
||||
{
|
||||
std::function<void(void)> cleanUp_;
|
||||
|
||||
public:
|
||||
~Deleter()
|
||||
{
|
||||
if (cleanUp_)
|
||||
cleanUp_();
|
||||
}
|
||||
template<typename DEL>
|
||||
void operator= (DEL&& fun)
|
||||
{
|
||||
cleanUp_ = std::forward<DEL> (fun);
|
||||
}
|
||||
};
|
||||
|
||||
static Deleter deleter;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -319,10 +283,7 @@ namespace lib {
|
|||
std::atomic<SRV*> Depend<SRV>::instance;
|
||||
|
||||
template<class SRV>
|
||||
typename Depend<SRV>::Factory Depend<SRV>::factory;
|
||||
|
||||
template<class SRV>
|
||||
typename Depend<SRV>::Deleter Depend<SRV>::deleter;
|
||||
DependencyFactory<SRV> Depend<SRV>::factory;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -58,12 +58,26 @@ namespace util {
|
|||
class MoveOnly
|
||||
{
|
||||
protected:
|
||||
~MoveOnly() = default;
|
||||
MoveOnly() = default;
|
||||
MoveOnly (MoveOnly&&) = default;
|
||||
MoveOnly (MoveOnly const&) = delete;
|
||||
MoveOnly& operator= (MoveOnly&&) = delete;
|
||||
MoveOnly& operator= (MoveOnly const&) = delete;
|
||||
~MoveOnly() = default;
|
||||
MoveOnly() = default;
|
||||
MoveOnly (MoveOnly&&) = default;
|
||||
MoveOnly (MoveOnly const&) = delete;
|
||||
MoveOnly& operator= (MoveOnly&&) = delete;
|
||||
MoveOnly& operator= (MoveOnly const&) = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
* Types marked with this mix-in may be moved and move-assigned
|
||||
*/
|
||||
class MoveAssign
|
||||
{
|
||||
protected:
|
||||
~MoveAssign() = default;
|
||||
MoveAssign() = default;
|
||||
MoveAssign (MoveAssign&&) = default;
|
||||
MoveAssign (MoveAssign const&) = delete;
|
||||
MoveAssign& operator= (MoveAssign&&) = default;
|
||||
MoveAssign& operator= (MoveAssign const&) = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -77,12 +91,12 @@ namespace util {
|
|||
class Cloneable
|
||||
{
|
||||
protected:
|
||||
~Cloneable() = default;
|
||||
Cloneable() = default;
|
||||
Cloneable (Cloneable&&) = default;
|
||||
Cloneable (Cloneable const&) = default;
|
||||
Cloneable& operator= (Cloneable&&) = delete;
|
||||
Cloneable& operator= (Cloneable const&) = delete;
|
||||
~Cloneable() = default;
|
||||
Cloneable() = default;
|
||||
Cloneable (Cloneable&&) = default;
|
||||
Cloneable (Cloneable const&) = default;
|
||||
Cloneable& operator= (Cloneable&&) = delete;
|
||||
Cloneable& operator= (Cloneable const&) = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace test{
|
|||
Interface () : TestTargetObj(cnt) {}
|
||||
virtual ~Interface() {}
|
||||
|
||||
friend class lib::Depend<Interface>;
|
||||
friend class lib::DependencyFactory<Interface>;
|
||||
};
|
||||
|
||||
int Interface::cnt = 0;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace test{
|
|||
protected:
|
||||
TargetObj () : TestTargetObj(cnt) {}
|
||||
|
||||
friend class lib::Depend<TargetObj>;
|
||||
friend class lib::DependencyFactory<TargetObj>;
|
||||
};
|
||||
|
||||
int TargetObj::cnt = 0;
|
||||
|
|
|
|||
|
|
@ -27772,8 +27772,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522200092935" ID="ID_1314237888" MODIFIED="1522200242915" TEXT="Deleter-Behandlung">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522200092935" ID="ID_1314237888" MODIFIED="1522382097329" TEXT="Deleter-Behandlung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1522200102534" ID="ID_284894079" MODIFIED="1522200105025" TEXT="bisher">
|
||||
<node CREATED="1522200106373" ID="ID_1981188993" MODIFIED="1522200226028" TEXT="was die Factory zurückliefert, wird nicht gemanaged">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
|
|
@ -27787,35 +27787,89 @@
|
|||
</node>
|
||||
<node CREATED="1522200147696" ID="ID_929047067" MODIFIED="1522200270431" TEXT="gewünscht">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522200152927" ID="ID_326569334" MODIFIED="1522200261233" TEXT="keine Memory-leaks">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1522200152927" ID="ID_326569334" MODIFIED="1522382081602" TEXT="keine Memory-leaks">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522200167861" ID="ID_908074030" MODIFIED="1522200262177" TEXT="alles soll zerstört werden">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1522200167861" ID="ID_908074030" MODIFIED="1522382083234" TEXT="alles soll zerstört werden">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522200189706" ID="ID_302642427" MODIFIED="1522200262864" TEXT="möglichst alle instance-Pointer zurücksetzen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1522200189706" ID="ID_302642427" MODIFIED="1522382084962" TEXT="möglichst alle instance-Pointer zurücksetzen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522200249626" ID="ID_215336836" MODIFIED="1522200263456" TEXT="Freunschafts-fähig">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1522200249626" ID="ID_215336836" MODIFIED="1522382087401" TEXT="Freunschafts-fähig">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522334796724" ID="ID_1080992734" MODIFIED="1522334873818" TEXT="Funktoren zusammenführen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522334843062" ID="ID_1526236017" MODIFIED="1522334870859" TEXT="DependencyFactory für">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522334796724" ID="ID_1080992734" MODIFIED="1522382015413" TEXT="Funktoren zusammenführen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1522334843062" ID="ID_1526236017" MODIFIED="1522382043115" TEXT="DependencyFactory für">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1522334805635" ID="ID_315782435" MODIFIED="1522334817813" TEXT="Erzeugungs-Funktor"/>
|
||||
<node CREATED="1522334818473" ID="ID_750129060" MODIFIED="1522334821036" TEXT="Deleter"/>
|
||||
<node CREATED="1522334822001" ID="ID_644059909" MODIFIED="1522334935421" TEXT="automatisches Instanz-Management"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522334859291" ID="ID_1496044958" MODIFIED="1522334866755" TEXT="einfach konfigurierbar">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1522334896942" ID="ID_1215786079" MODIFIED="1522334902129" TEXT="default-Fall"/>
|
||||
<node CREATED="1522334903741" ID="ID_1875541619" MODIFIED="1522334911776" TEXT="abstrakte Basisklasse"/>
|
||||
<node CREATED="1522334912412" ID="ID_1391948557" MODIFIED="1522334916463" TEXT="custom-Funktor"/>
|
||||
<node CREATED="1522334917035" ID="ID_259163474" MODIFIED="1522334922006" TEXT="custom-Deleter"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522334859291" ID="ID_1496044958" MODIFIED="1522382005045" TEXT="korrekt handhaben">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1522334896942" ID="ID_1215786079" MODIFIED="1522382047552" TEXT="default-Fall">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1522334903741" ID="ID_1875541619" MODIFIED="1522382049855" TEXT="abstrakte Basisklasse">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1522381984647" ID="ID_136231234" MODIFIED="1522382051295" TEXT="Klasse ohne Default-ctor">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1522334912412" ID="ID_1391948557" MODIFIED="1522382053286" TEXT="custom-Funktor">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1522334917035" ID="ID_259163474" MODIFIED="1522382054565" TEXT="custom-Deleter">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1522367884794" ID="ID_42634215" MODIFIED="1522381896407" TEXT="Analyse der Schritte">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1522367595914" ID="ID_615466863" MODIFIED="1522367600141" TEXT="Use-cases">
|
||||
<node CREATED="1522367601081" ID="ID_1594593457" MODIFIED="1522367603813" TEXT="default">
|
||||
<node CREATED="1522367513966" ID="ID_18197809" MODIFIED="1522381907638" TEXT="nominelle Target-Klasse">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1522367550688" ID="ID_1892572153" MODIFIED="1522381910426" TEXT="Objekt per default ctor erzeugen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1522367555520" ID="ID_1067588123" MODIFIED="1522381912781" TEXT="instanz managen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1522367604945" ID="ID_681132036" MODIFIED="1522367617123" TEXT="Subclass">
|
||||
<node CREATED="1522367701660" ID="ID_381217567" MODIFIED="1522381919492" TEXT="Subklasse feststellen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1522367650099" ID="ID_887791148" MODIFIED="1522381923778" TEXT="nur delegieren an Depend<SUB>">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1522367617999" ID="ID_1310241568" MODIFIED="1522367623762" TEXT="custom-Functor">
|
||||
<node CREATED="1522367712338" ID="ID_1169276081" MODIFIED="1522381927169" TEXT="Functor speichern">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1522367731959" ID="ID_1766531478" MODIFIED="1522381929444" TEXT="Objekt per Funktor erzeugen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1522367749229" ID="ID_1580519177" MODIFIED="1522381931877" TEXT="instanz managen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1522367902872" ID="ID_272084666" MODIFIED="1522367919009" TEXT="grundsätzlich immer">
|
||||
<node CREATED="1522367561111" ID="ID_604859300" MODIFIED="1522381935331" TEXT="instanz-Ptr NULLen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1522367573173" ID="ID_1825315724" MODIFIED="1522381938038" TEXT="Factory sperren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue