C # project, but it may apply to any OO languages. 3 Interface Interacting:
Public Interface IPublicData {} Public / * Internal * / Interface IInternalDataProducer {string GetData (); } Public Interface IPublicWorker {IPublicData DoWork (); IInternalDataProducer GetInternalProducer (); } Public class engine {engine (IPublicWorker worker) {} IPublic data run () {DoSomethingWith (worker.GetInternalProducer (.) GetData ()); Return worker DoWork (); }}
Clearly the engine
is the parametric in the real worker who makes the job. Another source of parametrations is how we make "internal data" through IInternalDataProducer
for this implementation, the public need to be IInternalDataProducer
because it is public The interface is part of the announcement of IPublicWorker
However, I should have it internal because it is used only by the engine.
The internal data itself creates a solution IPublicWorker
, but it is not very beautiful there are only a few ways to create it (while there are too many employees implementations), so some It is good to assign different concrete sections. In addition, IInternalDataProducer
is used in more places inside the engine, so it is good for the engine to cross the real object.
Apart from this, there is not an option (obviously) to pass an example of IInternalDataProducer
directly to the engine
constructor. We do not want users of the library ( engine
) to learn about data generators. It is the responsibility of the worker to declare this figure (production) which data producer should be used.
Cheers: -)
Edit: Based on Jeff's answer, there is a solution here:
I'm looking for elegant, type-safe, ideas / patterns :
This is not correct, because the interface is still 'dirty' code> gatedata () which the user should not need to see (but my original interface was too dirty ), And because it 'interface duplication' ( GetData ()
is declared in 2 interface) - all you have Uc can not be.
The next problem is that to get rid of GetData ()
from the IPublicWorker
interface:)
public Interface IP_HTMLData {} Internal / *! * / Interface IInternalDataProducer {string GetData (); } Public Interface IPublicWorker {IPublicData DoWork (); String GetData (); } Public class APublicWorker: IPublicWorker {Private IInternalDataProducer Data Generator; Public AP Worker () {dataProducer = New SomeDataProducer (); } IPublicData DoWork () {...} string GetData () {/ * delegation! * / Refunding Data Provider GateData (); / * ********* *}} Public class engine {engine (IPublicWorker worker) {} IPublic data run (DoSomethingWith (worker.GetData ()); Return worker DoWork (); }}
You can solve it by covering the data producer within the worker:
Public Interface IPublicWorker {IPublicData DoWork (); // Callers do not care how a worker receives this data string GetData (); }
Calling in the engine looks like this:
Run IPlicData () {DoSomethingWith (worker.GetData ()); Return worker DoWork (); }
Comments
Post a Comment