Refactor if statement where i have to initialize different object












0















i'm searching the smartest way of handle this method



public boolean addAccount(String cf, AccountType type) {
String iban = name + cf;
if (bankAccounts.containsKey(iban)) return false;
if (type.name().equals("CHECKINGACCOUNT")) {
CheckingAccount cc = new CheckingAccount(cf, iban, 0);
bankAccounts.put(iban, cc);
return true;
}
if (type.name().equals("DEPOSIT")) {
DepositAccount cd = new DepositAccount(cf, iban, 0);
bankAccounts.put(iban, cd);
return true;
}
if (type.name().equals("WEB")) {
WebAccount cw = new WebAccount(cf, iban, 0);
bankAccounts.put(iban, cw);
return true;
}
return false;
}


AccountType is enum that contains (DEPOSIT,WEB,CHECKINGACCOUNT);
bankAccounts is an HashMap that contains iban (key) & CheckingAccounts OR DepositAccount OR WebAccount;
CheckingAccounts ,DepositAccount,WebAccount are 3 classes that inherit an abstract class called Account.



I'm trying to substitute the if with an HashMap that check the key (Type of account) with the String insert by the user and instantiates one of the three class associated to the key in the HashMap.
The problem is that i can't create the correspondence between the String and the Account because i need to instantiate that (but i don't know the cf in that moment)



Could someone show me some better way to manage it?










share|improve this question



























    0















    i'm searching the smartest way of handle this method



    public boolean addAccount(String cf, AccountType type) {
    String iban = name + cf;
    if (bankAccounts.containsKey(iban)) return false;
    if (type.name().equals("CHECKINGACCOUNT")) {
    CheckingAccount cc = new CheckingAccount(cf, iban, 0);
    bankAccounts.put(iban, cc);
    return true;
    }
    if (type.name().equals("DEPOSIT")) {
    DepositAccount cd = new DepositAccount(cf, iban, 0);
    bankAccounts.put(iban, cd);
    return true;
    }
    if (type.name().equals("WEB")) {
    WebAccount cw = new WebAccount(cf, iban, 0);
    bankAccounts.put(iban, cw);
    return true;
    }
    return false;
    }


    AccountType is enum that contains (DEPOSIT,WEB,CHECKINGACCOUNT);
    bankAccounts is an HashMap that contains iban (key) & CheckingAccounts OR DepositAccount OR WebAccount;
    CheckingAccounts ,DepositAccount,WebAccount are 3 classes that inherit an abstract class called Account.



    I'm trying to substitute the if with an HashMap that check the key (Type of account) with the String insert by the user and instantiates one of the three class associated to the key in the HashMap.
    The problem is that i can't create the correspondence between the String and the Account because i need to instantiate that (but i don't know the cf in that moment)



    Could someone show me some better way to manage it?










    share|improve this question

























      0












      0








      0








      i'm searching the smartest way of handle this method



      public boolean addAccount(String cf, AccountType type) {
      String iban = name + cf;
      if (bankAccounts.containsKey(iban)) return false;
      if (type.name().equals("CHECKINGACCOUNT")) {
      CheckingAccount cc = new CheckingAccount(cf, iban, 0);
      bankAccounts.put(iban, cc);
      return true;
      }
      if (type.name().equals("DEPOSIT")) {
      DepositAccount cd = new DepositAccount(cf, iban, 0);
      bankAccounts.put(iban, cd);
      return true;
      }
      if (type.name().equals("WEB")) {
      WebAccount cw = new WebAccount(cf, iban, 0);
      bankAccounts.put(iban, cw);
      return true;
      }
      return false;
      }


      AccountType is enum that contains (DEPOSIT,WEB,CHECKINGACCOUNT);
      bankAccounts is an HashMap that contains iban (key) & CheckingAccounts OR DepositAccount OR WebAccount;
      CheckingAccounts ,DepositAccount,WebAccount are 3 classes that inherit an abstract class called Account.



      I'm trying to substitute the if with an HashMap that check the key (Type of account) with the String insert by the user and instantiates one of the three class associated to the key in the HashMap.
      The problem is that i can't create the correspondence between the String and the Account because i need to instantiate that (but i don't know the cf in that moment)



      Could someone show me some better way to manage it?










      share|improve this question














      i'm searching the smartest way of handle this method



      public boolean addAccount(String cf, AccountType type) {
      String iban = name + cf;
      if (bankAccounts.containsKey(iban)) return false;
      if (type.name().equals("CHECKINGACCOUNT")) {
      CheckingAccount cc = new CheckingAccount(cf, iban, 0);
      bankAccounts.put(iban, cc);
      return true;
      }
      if (type.name().equals("DEPOSIT")) {
      DepositAccount cd = new DepositAccount(cf, iban, 0);
      bankAccounts.put(iban, cd);
      return true;
      }
      if (type.name().equals("WEB")) {
      WebAccount cw = new WebAccount(cf, iban, 0);
      bankAccounts.put(iban, cw);
      return true;
      }
      return false;
      }


      AccountType is enum that contains (DEPOSIT,WEB,CHECKINGACCOUNT);
      bankAccounts is an HashMap that contains iban (key) & CheckingAccounts OR DepositAccount OR WebAccount;
      CheckingAccounts ,DepositAccount,WebAccount are 3 classes that inherit an abstract class called Account.



      I'm trying to substitute the if with an HashMap that check the key (Type of account) with the String insert by the user and instantiates one of the three class associated to the key in the HashMap.
      The problem is that i can't create the correspondence between the String and the Account because i need to instantiate that (but i don't know the cf in that moment)



      Could someone show me some better way to manage it?







      java if-statement hashmap






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 18:41









      FabioFabio

      94111




      94111
























          3 Answers
          3






          active

          oldest

          votes


















          1














          Why not put the logic for which Account to create right in the enum itself, using a factory pattern? Ever since Java 8, this pattern is really slick, as you can literally pass in the constructor as an implementation of the factory:



          public boolean addAccount(String cf, AccountType type) {
          String iban = name + cf;
          if (bankAccounts.containsKey(iban)) return false;
          Account account = type.createAccount(cf, iban, 0);
          bankAccounts.put(iban, account);
          return true;
          }

          public enum AccountType {
          CHECKING(CheckingAccount::new),
          DEPOSIT(DepositAccount::new),
          WEB(WebAccount::new);

          private final AccountFactory factory;
          AccountType(AccountFactory factory) {
          this.factory = factory;
          }

          public Account createAccount(String cf, String iban, int x) {
          return factory.create(cf, iban, x);
          }
          }

          public interface AccountFactory {
          Account create(String cf, String iban, int x);
          }


          This solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime (instead of compile time)






          share|improve this answer


























          • CHECKING(CheckingAccount::new) should CheckingAccount here be CheckingAccountFactory?

            – Ivan Lymar
            Nov 23 '18 at 19:24











          • @IvanLymar No - CheckingAccount::new is a lambda expression to the CheckingAccount constructor. All classes extend a common base class Account - so the factory is just an AccountFactory, with a single method that has the same signature as the constructors for each of the extensions.

            – Krease
            Nov 23 '18 at 19:29








          • 1





            @Krease what you should mention, IMO, is that this solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime.

            – JB Nizet
            Nov 23 '18 at 19:31











          • Well said @JBNizet :)

            – Krease
            Nov 23 '18 at 19:33



















          0














          I would advise against using any sort of type map as it just increases complexity and runtime cost. A switch statement seems the easiest.
          Here is an example:



          public boolean addAccount(String cf, AccountType type) {
          String iban = name + cf;
          if (bankAccounts.containsKey(iban)) return false;
          Account account;
          switch(type) {
          case CHECKINGACCOUNT:
          account = new CheckingAccount(cf, iban, 0);
          break;
          case DEPOSIT:
          account = new DepositAccount(cf, iban, 0);
          break;
          case WEB:
          account = new WebAccount(cf, iban, 0);
          break;
          default:
          return false;
          }
          bankAccounts.put(iban, account);
          return true;
          }


          However, if you are determined to use a type map:



          static Map<AccountType, Class> TYPE_MAP = new HashMap<>() 
          {
          {AccountType.CHECKINGACCOUNT, CheckingAccount.class},
          {AccountType.DEPOSIT, DepositAccount.class},
          {AccountType.WEB, WebAccount.class}
          };

          public boolean addAccount(String cf, AccountType type) {
          String iban = name + cf;
          if (bankAccounts.containsKey(iban)) return false;
          if (!TYPE_MAP.containsKey(type)) return false;
          Class classType = TYPE_MAP.get(type);
          Account account = (Account)classType
          .getDeclaredConstructor(
          String.class,
          String.class,
          Integer.class)
          .newInstance(cf, iban, 0);
          bankAccounts.put(iban, account);
          return true;
          }





          share|improve this answer
























          • I would suggest to use generic for Class too, Class<? extends Account> , and if constructor uses int use int.class

            – azro
            Nov 23 '18 at 19:00








          • 1





            What's ugly and inefficient is not the use of a Map (which should be an EnumMap, BTW). What's ugly is the use of reflection. If you stored a Factory in the map instead of storing the class, you wouldn't need reflection.

            – JB Nizet
            Nov 23 '18 at 19:01



















          0














          My opinion is that conceptually everything is fine with this method. I would change it a bit though:



             public boolean addAccount(String cf, AccountType type) {
          String iban = name + cf;
          if (bankAccounts.containsKey(iban)) return false;

          Account ac;
          if (type == CHECKING) {
          ac = new CheckingAccount(cf, iban, 0);
          } else if (type == DEPOSIT) {
          ac = new DepositAccount(cf, iban, 0);
          } else if (type == WEB) {
          ac = new WebAccount(cf, iban, 0);
          }
          bankAccounts.put(iban, cc);
          return true;
          }


          I do not see any reasons to make it more complex using reflection or factories to create acount instances. It will not give you any benefit, you will just get more code and new person will spend more time to understand it.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451601%2frefactor-if-statement-where-i-have-to-initialize-different-object%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Why not put the logic for which Account to create right in the enum itself, using a factory pattern? Ever since Java 8, this pattern is really slick, as you can literally pass in the constructor as an implementation of the factory:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account = type.createAccount(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }

            public enum AccountType {
            CHECKING(CheckingAccount::new),
            DEPOSIT(DepositAccount::new),
            WEB(WebAccount::new);

            private final AccountFactory factory;
            AccountType(AccountFactory factory) {
            this.factory = factory;
            }

            public Account createAccount(String cf, String iban, int x) {
            return factory.create(cf, iban, x);
            }
            }

            public interface AccountFactory {
            Account create(String cf, String iban, int x);
            }


            This solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime (instead of compile time)






            share|improve this answer


























            • CHECKING(CheckingAccount::new) should CheckingAccount here be CheckingAccountFactory?

              – Ivan Lymar
              Nov 23 '18 at 19:24











            • @IvanLymar No - CheckingAccount::new is a lambda expression to the CheckingAccount constructor. All classes extend a common base class Account - so the factory is just an AccountFactory, with a single method that has the same signature as the constructors for each of the extensions.

              – Krease
              Nov 23 '18 at 19:29








            • 1





              @Krease what you should mention, IMO, is that this solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime.

              – JB Nizet
              Nov 23 '18 at 19:31











            • Well said @JBNizet :)

              – Krease
              Nov 23 '18 at 19:33
















            1














            Why not put the logic for which Account to create right in the enum itself, using a factory pattern? Ever since Java 8, this pattern is really slick, as you can literally pass in the constructor as an implementation of the factory:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account = type.createAccount(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }

            public enum AccountType {
            CHECKING(CheckingAccount::new),
            DEPOSIT(DepositAccount::new),
            WEB(WebAccount::new);

            private final AccountFactory factory;
            AccountType(AccountFactory factory) {
            this.factory = factory;
            }

            public Account createAccount(String cf, String iban, int x) {
            return factory.create(cf, iban, x);
            }
            }

            public interface AccountFactory {
            Account create(String cf, String iban, int x);
            }


            This solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime (instead of compile time)






            share|improve this answer


























            • CHECKING(CheckingAccount::new) should CheckingAccount here be CheckingAccountFactory?

              – Ivan Lymar
              Nov 23 '18 at 19:24











            • @IvanLymar No - CheckingAccount::new is a lambda expression to the CheckingAccount constructor. All classes extend a common base class Account - so the factory is just an AccountFactory, with a single method that has the same signature as the constructors for each of the extensions.

              – Krease
              Nov 23 '18 at 19:29








            • 1





              @Krease what you should mention, IMO, is that this solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime.

              – JB Nizet
              Nov 23 '18 at 19:31











            • Well said @JBNizet :)

              – Krease
              Nov 23 '18 at 19:33














            1












            1








            1







            Why not put the logic for which Account to create right in the enum itself, using a factory pattern? Ever since Java 8, this pattern is really slick, as you can literally pass in the constructor as an implementation of the factory:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account = type.createAccount(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }

            public enum AccountType {
            CHECKING(CheckingAccount::new),
            DEPOSIT(DepositAccount::new),
            WEB(WebAccount::new);

            private final AccountFactory factory;
            AccountType(AccountFactory factory) {
            this.factory = factory;
            }

            public Account createAccount(String cf, String iban, int x) {
            return factory.create(cf, iban, x);
            }
            }

            public interface AccountFactory {
            Account create(String cf, String iban, int x);
            }


            This solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime (instead of compile time)






            share|improve this answer















            Why not put the logic for which Account to create right in the enum itself, using a factory pattern? Ever since Java 8, this pattern is really slick, as you can literally pass in the constructor as an implementation of the factory:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account = type.createAccount(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }

            public enum AccountType {
            CHECKING(CheckingAccount::new),
            DEPOSIT(DepositAccount::new),
            WEB(WebAccount::new);

            private final AccountFactory factory;
            AccountType(AccountFactory factory) {
            this.factory = factory;
            }

            public Account createAccount(String cf, String iban, int x) {
            return factory.create(cf, iban, x);
            }
            }

            public interface AccountFactory {
            Account create(String cf, String iban, int x);
            }


            This solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime (instead of compile time)







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 23 '18 at 19:33

























            answered Nov 23 '18 at 19:13









            KreaseKrease

            11.6k74160




            11.6k74160













            • CHECKING(CheckingAccount::new) should CheckingAccount here be CheckingAccountFactory?

              – Ivan Lymar
              Nov 23 '18 at 19:24











            • @IvanLymar No - CheckingAccount::new is a lambda expression to the CheckingAccount constructor. All classes extend a common base class Account - so the factory is just an AccountFactory, with a single method that has the same signature as the constructors for each of the extensions.

              – Krease
              Nov 23 '18 at 19:29








            • 1





              @Krease what you should mention, IMO, is that this solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime.

              – JB Nizet
              Nov 23 '18 at 19:31











            • Well said @JBNizet :)

              – Krease
              Nov 23 '18 at 19:33



















            • CHECKING(CheckingAccount::new) should CheckingAccount here be CheckingAccountFactory?

              – Ivan Lymar
              Nov 23 '18 at 19:24











            • @IvanLymar No - CheckingAccount::new is a lambda expression to the CheckingAccount constructor. All classes extend a common base class Account - so the factory is just an AccountFactory, with a single method that has the same signature as the constructors for each of the extensions.

              – Krease
              Nov 23 '18 at 19:29








            • 1





              @Krease what you should mention, IMO, is that this solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime.

              – JB Nizet
              Nov 23 '18 at 19:31











            • Well said @JBNizet :)

              – Krease
              Nov 23 '18 at 19:33

















            CHECKING(CheckingAccount::new) should CheckingAccount here be CheckingAccountFactory?

            – Ivan Lymar
            Nov 23 '18 at 19:24





            CHECKING(CheckingAccount::new) should CheckingAccount here be CheckingAccountFactory?

            – Ivan Lymar
            Nov 23 '18 at 19:24













            @IvanLymar No - CheckingAccount::new is a lambda expression to the CheckingAccount constructor. All classes extend a common base class Account - so the factory is just an AccountFactory, with a single method that has the same signature as the constructors for each of the extensions.

            – Krease
            Nov 23 '18 at 19:29







            @IvanLymar No - CheckingAccount::new is a lambda expression to the CheckingAccount constructor. All classes extend a common base class Account - so the factory is just an AccountFactory, with a single method that has the same signature as the constructors for each of the extensions.

            – Krease
            Nov 23 '18 at 19:29






            1




            1





            @Krease what you should mention, IMO, is that this solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime.

            – JB Nizet
            Nov 23 '18 at 19:31





            @Krease what you should mention, IMO, is that this solution has a huge advantage over the switch or map approach: if you ever add a new subclass and a new type of account, there is no way you can forget to handle this new type. The other solutions will fail, or give incorrect results, at runtime.

            – JB Nizet
            Nov 23 '18 at 19:31













            Well said @JBNizet :)

            – Krease
            Nov 23 '18 at 19:33





            Well said @JBNizet :)

            – Krease
            Nov 23 '18 at 19:33













            0














            I would advise against using any sort of type map as it just increases complexity and runtime cost. A switch statement seems the easiest.
            Here is an example:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account;
            switch(type) {
            case CHECKINGACCOUNT:
            account = new CheckingAccount(cf, iban, 0);
            break;
            case DEPOSIT:
            account = new DepositAccount(cf, iban, 0);
            break;
            case WEB:
            account = new WebAccount(cf, iban, 0);
            break;
            default:
            return false;
            }
            bankAccounts.put(iban, account);
            return true;
            }


            However, if you are determined to use a type map:



            static Map<AccountType, Class> TYPE_MAP = new HashMap<>() 
            {
            {AccountType.CHECKINGACCOUNT, CheckingAccount.class},
            {AccountType.DEPOSIT, DepositAccount.class},
            {AccountType.WEB, WebAccount.class}
            };

            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            if (!TYPE_MAP.containsKey(type)) return false;
            Class classType = TYPE_MAP.get(type);
            Account account = (Account)classType
            .getDeclaredConstructor(
            String.class,
            String.class,
            Integer.class)
            .newInstance(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }





            share|improve this answer
























            • I would suggest to use generic for Class too, Class<? extends Account> , and if constructor uses int use int.class

              – azro
              Nov 23 '18 at 19:00








            • 1





              What's ugly and inefficient is not the use of a Map (which should be an EnumMap, BTW). What's ugly is the use of reflection. If you stored a Factory in the map instead of storing the class, you wouldn't need reflection.

              – JB Nizet
              Nov 23 '18 at 19:01
















            0














            I would advise against using any sort of type map as it just increases complexity and runtime cost. A switch statement seems the easiest.
            Here is an example:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account;
            switch(type) {
            case CHECKINGACCOUNT:
            account = new CheckingAccount(cf, iban, 0);
            break;
            case DEPOSIT:
            account = new DepositAccount(cf, iban, 0);
            break;
            case WEB:
            account = new WebAccount(cf, iban, 0);
            break;
            default:
            return false;
            }
            bankAccounts.put(iban, account);
            return true;
            }


            However, if you are determined to use a type map:



            static Map<AccountType, Class> TYPE_MAP = new HashMap<>() 
            {
            {AccountType.CHECKINGACCOUNT, CheckingAccount.class},
            {AccountType.DEPOSIT, DepositAccount.class},
            {AccountType.WEB, WebAccount.class}
            };

            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            if (!TYPE_MAP.containsKey(type)) return false;
            Class classType = TYPE_MAP.get(type);
            Account account = (Account)classType
            .getDeclaredConstructor(
            String.class,
            String.class,
            Integer.class)
            .newInstance(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }





            share|improve this answer
























            • I would suggest to use generic for Class too, Class<? extends Account> , and if constructor uses int use int.class

              – azro
              Nov 23 '18 at 19:00








            • 1





              What's ugly and inefficient is not the use of a Map (which should be an EnumMap, BTW). What's ugly is the use of reflection. If you stored a Factory in the map instead of storing the class, you wouldn't need reflection.

              – JB Nizet
              Nov 23 '18 at 19:01














            0












            0








            0







            I would advise against using any sort of type map as it just increases complexity and runtime cost. A switch statement seems the easiest.
            Here is an example:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account;
            switch(type) {
            case CHECKINGACCOUNT:
            account = new CheckingAccount(cf, iban, 0);
            break;
            case DEPOSIT:
            account = new DepositAccount(cf, iban, 0);
            break;
            case WEB:
            account = new WebAccount(cf, iban, 0);
            break;
            default:
            return false;
            }
            bankAccounts.put(iban, account);
            return true;
            }


            However, if you are determined to use a type map:



            static Map<AccountType, Class> TYPE_MAP = new HashMap<>() 
            {
            {AccountType.CHECKINGACCOUNT, CheckingAccount.class},
            {AccountType.DEPOSIT, DepositAccount.class},
            {AccountType.WEB, WebAccount.class}
            };

            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            if (!TYPE_MAP.containsKey(type)) return false;
            Class classType = TYPE_MAP.get(type);
            Account account = (Account)classType
            .getDeclaredConstructor(
            String.class,
            String.class,
            Integer.class)
            .newInstance(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }





            share|improve this answer













            I would advise against using any sort of type map as it just increases complexity and runtime cost. A switch statement seems the easiest.
            Here is an example:



            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            Account account;
            switch(type) {
            case CHECKINGACCOUNT:
            account = new CheckingAccount(cf, iban, 0);
            break;
            case DEPOSIT:
            account = new DepositAccount(cf, iban, 0);
            break;
            case WEB:
            account = new WebAccount(cf, iban, 0);
            break;
            default:
            return false;
            }
            bankAccounts.put(iban, account);
            return true;
            }


            However, if you are determined to use a type map:



            static Map<AccountType, Class> TYPE_MAP = new HashMap<>() 
            {
            {AccountType.CHECKINGACCOUNT, CheckingAccount.class},
            {AccountType.DEPOSIT, DepositAccount.class},
            {AccountType.WEB, WebAccount.class}
            };

            public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;
            if (!TYPE_MAP.containsKey(type)) return false;
            Class classType = TYPE_MAP.get(type);
            Account account = (Account)classType
            .getDeclaredConstructor(
            String.class,
            String.class,
            Integer.class)
            .newInstance(cf, iban, 0);
            bankAccounts.put(iban, account);
            return true;
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 23 '18 at 18:58









            AlchemyAlchemy

            4253




            4253













            • I would suggest to use generic for Class too, Class<? extends Account> , and if constructor uses int use int.class

              – azro
              Nov 23 '18 at 19:00








            • 1





              What's ugly and inefficient is not the use of a Map (which should be an EnumMap, BTW). What's ugly is the use of reflection. If you stored a Factory in the map instead of storing the class, you wouldn't need reflection.

              – JB Nizet
              Nov 23 '18 at 19:01



















            • I would suggest to use generic for Class too, Class<? extends Account> , and if constructor uses int use int.class

              – azro
              Nov 23 '18 at 19:00








            • 1





              What's ugly and inefficient is not the use of a Map (which should be an EnumMap, BTW). What's ugly is the use of reflection. If you stored a Factory in the map instead of storing the class, you wouldn't need reflection.

              – JB Nizet
              Nov 23 '18 at 19:01

















            I would suggest to use generic for Class too, Class<? extends Account> , and if constructor uses int use int.class

            – azro
            Nov 23 '18 at 19:00







            I would suggest to use generic for Class too, Class<? extends Account> , and if constructor uses int use int.class

            – azro
            Nov 23 '18 at 19:00






            1




            1





            What's ugly and inefficient is not the use of a Map (which should be an EnumMap, BTW). What's ugly is the use of reflection. If you stored a Factory in the map instead of storing the class, you wouldn't need reflection.

            – JB Nizet
            Nov 23 '18 at 19:01





            What's ugly and inefficient is not the use of a Map (which should be an EnumMap, BTW). What's ugly is the use of reflection. If you stored a Factory in the map instead of storing the class, you wouldn't need reflection.

            – JB Nizet
            Nov 23 '18 at 19:01











            0














            My opinion is that conceptually everything is fine with this method. I would change it a bit though:



               public boolean addAccount(String cf, AccountType type) {
            String iban = name + cf;
            if (bankAccounts.containsKey(iban)) return false;

            Account ac;
            if (type == CHECKING) {
            ac = new CheckingAccount(cf, iban, 0);
            } else if (type == DEPOSIT) {
            ac = new DepositAccount(cf, iban, 0);
            } else if (type == WEB) {
            ac = new WebAccount(cf, iban, 0);
            }
            bankAccounts.put(iban, cc);
            return true;
            }


            I do not see any reasons to make it more complex using reflection or factories to create acount instances. It will not give you any benefit, you will just get more code and new person will spend more time to understand it.






            share|improve this answer




























              0














              My opinion is that conceptually everything is fine with this method. I would change it a bit though:



                 public boolean addAccount(String cf, AccountType type) {
              String iban = name + cf;
              if (bankAccounts.containsKey(iban)) return false;

              Account ac;
              if (type == CHECKING) {
              ac = new CheckingAccount(cf, iban, 0);
              } else if (type == DEPOSIT) {
              ac = new DepositAccount(cf, iban, 0);
              } else if (type == WEB) {
              ac = new WebAccount(cf, iban, 0);
              }
              bankAccounts.put(iban, cc);
              return true;
              }


              I do not see any reasons to make it more complex using reflection or factories to create acount instances. It will not give you any benefit, you will just get more code and new person will spend more time to understand it.






              share|improve this answer


























                0












                0








                0







                My opinion is that conceptually everything is fine with this method. I would change it a bit though:



                   public boolean addAccount(String cf, AccountType type) {
                String iban = name + cf;
                if (bankAccounts.containsKey(iban)) return false;

                Account ac;
                if (type == CHECKING) {
                ac = new CheckingAccount(cf, iban, 0);
                } else if (type == DEPOSIT) {
                ac = new DepositAccount(cf, iban, 0);
                } else if (type == WEB) {
                ac = new WebAccount(cf, iban, 0);
                }
                bankAccounts.put(iban, cc);
                return true;
                }


                I do not see any reasons to make it more complex using reflection or factories to create acount instances. It will not give you any benefit, you will just get more code and new person will spend more time to understand it.






                share|improve this answer













                My opinion is that conceptually everything is fine with this method. I would change it a bit though:



                   public boolean addAccount(String cf, AccountType type) {
                String iban = name + cf;
                if (bankAccounts.containsKey(iban)) return false;

                Account ac;
                if (type == CHECKING) {
                ac = new CheckingAccount(cf, iban, 0);
                } else if (type == DEPOSIT) {
                ac = new DepositAccount(cf, iban, 0);
                } else if (type == WEB) {
                ac = new WebAccount(cf, iban, 0);
                }
                bankAccounts.put(iban, cc);
                return true;
                }


                I do not see any reasons to make it more complex using reflection or factories to create acount instances. It will not give you any benefit, you will just get more code and new person will spend more time to understand it.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 23 '18 at 19:19









                Ivan LymarIvan Lymar

                920315




                920315






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53451601%2frefactor-if-statement-where-i-have-to-initialize-different-object%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Create new schema in PostgreSQL using DBeaver

                    Deepest pit of an array with Javascript: test on Codility

                    Costa Masnaga