I *think* this was an attempt to make a singleton



  • Names changed to protect the inept.

    namespace Initech.ObjectModel.DataObjects.Server
    {
        public abstract class FooDataProvider
        {
            // <SNIP> lots of abstract methods
           
            private static ConstructorInfo _contructor;

            internal static FooDataProvider Instance()
            {
                if (_contructor == null)
                {
                    try
                    {
                        _contructor = ReflectionHelper.GetDefaultConstructor("Initech.Providers.FooDataProvider", "Initech.Providers");
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to load provider", e);
                    }
                }

                // Load the configuration settings
                object[] paramArray = new object[0];
                return (FooDataProvider)(_contructor.Invoke(paramArray));
            }
        }
    }

     In a separate project in the solution, there is something like this:

    namespace Initech.Providers
    {
        public class FooDataProvider : Initech.ObjectModel.DataObjects.Server
        {
            public FooDataProvider()
            {
            }

                // <SNIP> implementation of abstract methods from above
        }
    }

    Short list of WTFs:
    - Both classes have the same name.
    - "Instance" creates a new instance each time it is called.
    - Using reflection to call a public constructor



  • P.S. This is commercial/production code.



  • @fourchan said:

    - "Instance" creates a new instance each time it is called.
    - Using reflection to call a public constructor

     

    Obviously they just learned about DRY...and reflection.



  • Reflection is the new regular expressions in the old "now you have two problems" joke.

    Particularly in Java.  I don't think I have ever seen a use of reflection in Java that was not a hideous hack used to patch over a serious design flaw.

    (Yes, even annotations.  Those are a hideous hack used to patch over serious design flaws in the Java language itself.)

    ((And yes, I know the WTF code is not Java.))



  • @Iago said:

    (Yes, even annotations.  Those are a hideous hack used to patch over serious design flaws in the Java language itself.)

    Hmm, I think I have to disagree with you. Just the other day, I used annotations to great affect in mapping some custom ${interpolation-strings} to methods which returned their values.

    I was building a mini template-like system to send emails about certain problems found in the environment. So that the messages could be easily altered in the future, they're softcoded in a config file. In order to make the variable substitutions easy, I just hooked up an interpolator from Apache Commons (StrSubstitutor).

    As an example, a message in the config would look this: "Old file found: ${file-name}. The file is from ${file-timestamp}. It should have already been processed! This is the ${times-happened-ordinal} time this has happened! Wtf! Go fix it!"

    Now, string lookups are trivial to do if the results are fairly static (or static-ish), you can just pass the interpolator a [code]Map<String, String>[/code]. However, if you want dynamic (or dynamic-ish) results each time the interpolations are processed, then using a dictionary lookup is going to be annoying to keep track of, not to mention create a lot of unnecessary work as you'd have to pre-compute all possible lookup results. Alternatively, you can use the interpolator's SPI to register your own variable resolver. The primary interface for custom variable lookups (StrLookup) simply contains method [code]String lookup(String key)[/code]. It passes you the "file-timestamp" string, and in return you give it the String "two freaking hours ago".

    Rather than a cascade of [code]if ("file-name".equals(key)) {...} else if ("file-timestamp".equals(key)) {...} else if (...) ...[/code] -- or the equivalent in [code]case[/code] statements if the language designers weren't masochistic -- I just created an Annotation to attach to a String-returning method, like [code]@StrLookupMethod("file-timestamp")[/code], then find and cache the methods as a [code]Map<String, Method>[/code] at static init time. This solutions is a million times easier for me to code, much easier to extend and maintain, and far cleaner all around.

    The code to grab the annotations is easy breezy, too. Just ask the containing class for its methods, then ask each method if it has the StrLookupMethod Annotation, then if so grab its variable interpolation name. It's like 10 lines of code, and half of those are just closing braces.

    Is the lack of a built-in templating system a design flaw in the Java language itself? I wouldn't argue it's not an annoying gap, but I'd hardly call it serious. Nevertheless, even if there was one available, the use of annotations makes it super easy to hook up arbitrary string aliases to arbitrary methods.

    Without the use of reflection/annotations, how would you go about assigning arbitrary string aliases to potentially nontrivial dynamic lookups? (Mapping the string to a method in an external XML file? Blech)


Log in to reply