Let's say you have a collection of objects that are part of a class:
[A, B, C, D]
But the order they are in means something. There are a finite number of orderings that you want to be able to delegate at runtime. For example [C, A, B, D], [B, D, A, C], etc. How would you go about encapsulating the notion of order in such a way that allows you to change the ordering at runtime, and add new orderings later on without changing existing code?
The language doesn't matter, but an explanation in Java or C++ is preferred.
Related
Say I have 2 #RestController and a bunch of WebFilters.
Now I'd like to:
Apply WebFitler A, B, C to controller X
Apply WebFilter A, D, E, F to controller Y
How am I supposed to do that?
Thanks
Leon
You can't do that; WebFilter is the equivalent of ServletFilter, so at that point, the request is not aware of the handler it's about to be dispatched to.
For use cases like this, a #ControllerAdvice is a better choice; you can apply it to a single controller, or all controllers in a package, or all controllers annotated with a specific annotation, etc.
So, suppose I'm working in the world of discrete mathematics and I have some function
f: A x B x C -> D.
With this function I can make computations like f(a,b,c) = d. (I'm being vague here on purpose).
Now suppose I want to implement this computation explicitly in some modern OO programming language. So I initialize a variable called a of class ClassA and so on with b and c. Then what? Which object should own the computation? Or could it be an initializer. Could it be a static function?
I could have:
d = a.f_1(b,c),
d = b.f_2(a,c),
d = c.f_3(a,b),
d = new ObjD(a,b,c),
d = ZStatic.f_4(a,b,c)
all as plausible options, couldn't I?
Given the situation, should symmetry demand I implement all of these options?
I'd prefer to avoid the constructor approach completely, but beyond that I don't know what progress could be made other than the assumption of essentially arbitrary information.
So, what object should own the function $f$, if any?
To give the best answer, it is important to know what kind of variables you use.
A very important metric in oop is to achieve high cohesion. Cohesion is the degree to which the elements of a module belong together. If your variables a,b and c belong together in a specific context, then it should be the best solution to put them in exactly one class. And if they are in one class you should not worry about, which class should own the computation (your fourth solution).
Your last suggestion, to use a static function is also conceivable. This approach is often used in mathematic librarys in different kind of languages (e.g. Java: Math class)
I'm not sure where to ask this this but I don't know how to google this. When class A inherits class B, A is child and B is Parent (or Base). If class C is composed of D(s), i.e. if C has D(s), what are the terms for C and D?
I think you are talking about either "has-a" or "use-a" relationship. for example, in simple,if C has D as class property (like embedded property in C++) then it is called as "C has D",and if C only has pointer of D as property, it is called "C uses D".
Lets say I am given an object O on some method.
This object O is derived from a base Object BaseClass and as such has a part whose type is BaseClass.
How can I access this part when I am in this method, which means super wont work because I am not in the context of the object.
Thanks!
Let me re-phrase your question to make sure I understand it. You have a class O containing a method (say "test"). In that method, you want to access an instance variable belonging to the superclass BaseClass.
If this is correct, then you can already access that instance variable directly. You just need to provide the name of the variable. Your subclass has access to all of the instance variables visible to the superclass.
You should consider creating get and set methods for the variable and accessing the variable by calling those methods from the subclass, but it's optional.
Let me provide another answer, which could be useful for cases where the question refers to behavior (methods) rather than shape (instance variables.)
Assume you have two classes C and D and an instance c of C. Now assume C inherits from C' and you would like to invoke a method m defined in C' that has been overridden in C. The expression c m will activate the implementation in C rather than the one in C' because c class == C, not C'. As you said, there is no "remote" version of super that you could use from D.
If what you want is to activate the method in C', then you should move the source code of m in C' to another method, say m0, and redefine m in C' so that it just delegates to m0 (^self m0). Keep the method m in C unchanged and then call from D using m0 (c m0) instead of m (c m).
Note that the other way around will not work: if you define m0 in C' as ^self m, the expression c m0 will activate the version of m found in C, not C'.
You could also define m0 in C as ^super m and that way c m0 will activate C'>>m. However, the usage of super with a different selector is not considered a good practice, and you should chose not to do that.
Having the SOLID principles and testability in mind, consider the following case:
You have class A and class B which have some overlapping properties. You want a method that copies and/or converts the common properties from class A to class B. Where does that method go?
Class A as a B GetAsB() ?
Class B as a constructor B(A input)?
Class B as a method void FillWithDataFrom(A input)?
Class C as a static method B ConvertAtoB(A source)?
???
It depends, all make sense in different circumstances; some examples from Java:
String java.lang.StringBuilder.toString()
java.lang.StringBuilder(String source)
void java.util.GregorianCalender.setTime(Date time)
ArrayList<T> java.util.Collections.list(Enumeration<T> e)
Some questions to help you decide:
Which dependency makes more sense? A dependent on B, B dependent on A, neither?
Do you always create a new B from an A, or do you need to fill existing Bs using As?
Are there other classes with similar collaborations, either as data providers for Bs or as targets for As data?
I'd rule out 1. because getter methods should be avoided (tell, don't ask principle).
I'd rule out 2. because it looks like a conversion, and this is not a conversion if A and B are different classes which happens to have something in common. At least, this is what it seems from the description. If that's not the case, 2 would be an option too IMHO.
Does 4. implies that C is aware of inner details of B and/or C? If so, I'd rule out this option too.
I'd vote for 3. then.
Whether this is correct OOP theory or not is up for debate, but depending upon the circumstances, I wouldn't rule C out quite so quickly. While ti DOES create a rather large dependency, it can have it's uses if the specific role of C is to manage the interaction (and copying) from A to B. The dependency is created in C specifically to avoid creating such dependency beteween A and B. Further, C exists specifically to manage the dependency, and can be implemented with that in mind.
Ex. (in vb.Net/Pseudocode):
Public Class C
Public Shared Function BClassFactory(ByVal MyA As A) As B
Dim NewB As New B
With B
.CommonProperty1 = A.CommonProperty1
.CommonProperty2 = A.CommonProperty2
End With
Return B
End Function
End Class
If there is a concrete reason to create, say, a AtoBConverterClass, this approach might be valid.
Again, this might be a specialized case. However I have found it useful on occasion. Especially if there are REALLY IMPORTANT reasons to keep A and B ignorant of eachother.