Java Spring design: all in one component?










1















Sometimes Spring components may look like this:



@Service
public final class SomeService
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services
@Autowired
private SomeDao someDao;
@Autowired
private SomeDao2 someDao2;
@Autowired
private SomeDao3 someDao3;
// … and many other DAOs




In other words Spring components have plenty services and DAOs that are mostly repeated in other Spring components. IMHO it has the following drawbacks:



  • Unnecessary (boilerplate) code for autowiring most of the same components

  • Sometimes Spring context loading error may occur due to circular references between components

What about to use all-in-one component that combine, say, all services or all DAOs. It will contain only links to Spring components with no any bussiness logic inside:



@Service
public final class AllServices {
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services

// get methods to get some service
public someService getSomeService();


and inject it into other components:



@Service
public final class SomeService {
@Autowired
private AllServices serv;
@Autowired
private AllDaos daos;
@Autowired
private Environment env;

// inside some code

serv.getSomeService().processData();


IMHO it will look more succinct without circular references issues…



What pros and cons of this approach?










share|improve this question



















  • 1





    Both of these are clear examples of consumer services that are performing far too much functionality. You should refactor your services so that each performs a single responsibility.

    – chrylis
    Nov 11 '18 at 5:37











  • Good point, every time you have more than one service (maybe 2, depending on the use case), you should consider refactoring, your class is breaking the single responsibility principle of the 5 SOLID principles. Look into it a bit more

    – Urosh T.
    Nov 11 '18 at 5:43















1















Sometimes Spring components may look like this:



@Service
public final class SomeService
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services
@Autowired
private SomeDao someDao;
@Autowired
private SomeDao2 someDao2;
@Autowired
private SomeDao3 someDao3;
// … and many other DAOs




In other words Spring components have plenty services and DAOs that are mostly repeated in other Spring components. IMHO it has the following drawbacks:



  • Unnecessary (boilerplate) code for autowiring most of the same components

  • Sometimes Spring context loading error may occur due to circular references between components

What about to use all-in-one component that combine, say, all services or all DAOs. It will contain only links to Spring components with no any bussiness logic inside:



@Service
public final class AllServices {
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services

// get methods to get some service
public someService getSomeService();


and inject it into other components:



@Service
public final class SomeService {
@Autowired
private AllServices serv;
@Autowired
private AllDaos daos;
@Autowired
private Environment env;

// inside some code

serv.getSomeService().processData();


IMHO it will look more succinct without circular references issues…



What pros and cons of this approach?










share|improve this question



















  • 1





    Both of these are clear examples of consumer services that are performing far too much functionality. You should refactor your services so that each performs a single responsibility.

    – chrylis
    Nov 11 '18 at 5:37











  • Good point, every time you have more than one service (maybe 2, depending on the use case), you should consider refactoring, your class is breaking the single responsibility principle of the 5 SOLID principles. Look into it a bit more

    – Urosh T.
    Nov 11 '18 at 5:43













1












1








1








Sometimes Spring components may look like this:



@Service
public final class SomeService
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services
@Autowired
private SomeDao someDao;
@Autowired
private SomeDao2 someDao2;
@Autowired
private SomeDao3 someDao3;
// … and many other DAOs




In other words Spring components have plenty services and DAOs that are mostly repeated in other Spring components. IMHO it has the following drawbacks:



  • Unnecessary (boilerplate) code for autowiring most of the same components

  • Sometimes Spring context loading error may occur due to circular references between components

What about to use all-in-one component that combine, say, all services or all DAOs. It will contain only links to Spring components with no any bussiness logic inside:



@Service
public final class AllServices {
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services

// get methods to get some service
public someService getSomeService();


and inject it into other components:



@Service
public final class SomeService {
@Autowired
private AllServices serv;
@Autowired
private AllDaos daos;
@Autowired
private Environment env;

// inside some code

serv.getSomeService().processData();


IMHO it will look more succinct without circular references issues…



What pros and cons of this approach?










share|improve this question
















Sometimes Spring components may look like this:



@Service
public final class SomeService
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services
@Autowired
private SomeDao someDao;
@Autowired
private SomeDao2 someDao2;
@Autowired
private SomeDao3 someDao3;
// … and many other DAOs




In other words Spring components have plenty services and DAOs that are mostly repeated in other Spring components. IMHO it has the following drawbacks:



  • Unnecessary (boilerplate) code for autowiring most of the same components

  • Sometimes Spring context loading error may occur due to circular references between components

What about to use all-in-one component that combine, say, all services or all DAOs. It will contain only links to Spring components with no any bussiness logic inside:



@Service
public final class AllServices {
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
@Autowired
private SomeService4 someService4;
// … and many other services

// get methods to get some service
public someService getSomeService();


and inject it into other components:



@Service
public final class SomeService {
@Autowired
private AllServices serv;
@Autowired
private AllDaos daos;
@Autowired
private Environment env;

// inside some code

serv.getSomeService().processData();


IMHO it will look more succinct without circular references issues…



What pros and cons of this approach?







java spring design-patterns






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 '18 at 6:42







serg kunz

















asked Nov 11 '18 at 5:03









serg kunzserg kunz

1297




1297







  • 1





    Both of these are clear examples of consumer services that are performing far too much functionality. You should refactor your services so that each performs a single responsibility.

    – chrylis
    Nov 11 '18 at 5:37











  • Good point, every time you have more than one service (maybe 2, depending on the use case), you should consider refactoring, your class is breaking the single responsibility principle of the 5 SOLID principles. Look into it a bit more

    – Urosh T.
    Nov 11 '18 at 5:43












  • 1





    Both of these are clear examples of consumer services that are performing far too much functionality. You should refactor your services so that each performs a single responsibility.

    – chrylis
    Nov 11 '18 at 5:37











  • Good point, every time you have more than one service (maybe 2, depending on the use case), you should consider refactoring, your class is breaking the single responsibility principle of the 5 SOLID principles. Look into it a bit more

    – Urosh T.
    Nov 11 '18 at 5:43







1




1





Both of these are clear examples of consumer services that are performing far too much functionality. You should refactor your services so that each performs a single responsibility.

– chrylis
Nov 11 '18 at 5:37





Both of these are clear examples of consumer services that are performing far too much functionality. You should refactor your services so that each performs a single responsibility.

– chrylis
Nov 11 '18 at 5:37













Good point, every time you have more than one service (maybe 2, depending on the use case), you should consider refactoring, your class is breaking the single responsibility principle of the 5 SOLID principles. Look into it a bit more

– Urosh T.
Nov 11 '18 at 5:43





Good point, every time you have more than one service (maybe 2, depending on the use case), you should consider refactoring, your class is breaking the single responsibility principle of the 5 SOLID principles. Look into it a bit more

– Urosh T.
Nov 11 '18 at 5:43












2 Answers
2






active

oldest

votes


















3














The second approach might look appealing, a well-known facade pattern comes to mind at first, so I can totally understand this.



However, I think the first pattern will work better in fact and here is why:




  1. You say that the "all-mighty" service can solve circular dependencies



    Well, circular dependencies usually point on a wrong / bad design and are code smell by there own, so hiding it behind a facade won't improve the system, resolving the circular dependencies will. In addition if from the actual services, called by "AllServices" you'll want to invoke additional service (again, bad design is preserved) then the code will probably pass through AllServices again, and hence the circular dependency is still there.



  2. Using the second design assumes that this "AllServices" class will be used by all the components of the system, but in this case it becomes a "one-central-point" and refactoring in this class can turn to a madness - all the components / their tests might be affected


  3. Initialization of this service can become a mess by itself, since you probably won't want to maintain a constructor that has 20-30 input parameters you'll resort to field injection (like in the example) which is bad by its own because if you want to initialize it somehow, probably from test, or something you want know what should be mocked and what not, in which order, and so forth.






share|improve this answer
































    2














    Second approach may look cleaner, but it will be difficult to know which service is connected to service/DAO and therefore it will be hard to refactor or do/decide on which regression any change will cause. Meaning it effect software flexibility



    This is the important difference which make the difference to choose first option IMHO






    share|improve this answer























    • I don’t think that is so very difficult to find dependencies for a Spring component using the second approach. Besides Spring components should be independent enough to make no big regression to others.

      – serg kunz
      Nov 11 '18 at 5:52











    • @sergkunz in second approach you can have circular dependencies, just with more clutter

      – user7294900
      Nov 11 '18 at 5:58










    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%2f53245990%2fjava-spring-design-all-in-one-component%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    The second approach might look appealing, a well-known facade pattern comes to mind at first, so I can totally understand this.



    However, I think the first pattern will work better in fact and here is why:




    1. You say that the "all-mighty" service can solve circular dependencies



      Well, circular dependencies usually point on a wrong / bad design and are code smell by there own, so hiding it behind a facade won't improve the system, resolving the circular dependencies will. In addition if from the actual services, called by "AllServices" you'll want to invoke additional service (again, bad design is preserved) then the code will probably pass through AllServices again, and hence the circular dependency is still there.



    2. Using the second design assumes that this "AllServices" class will be used by all the components of the system, but in this case it becomes a "one-central-point" and refactoring in this class can turn to a madness - all the components / their tests might be affected


    3. Initialization of this service can become a mess by itself, since you probably won't want to maintain a constructor that has 20-30 input parameters you'll resort to field injection (like in the example) which is bad by its own because if you want to initialize it somehow, probably from test, or something you want know what should be mocked and what not, in which order, and so forth.






    share|improve this answer





























      3














      The second approach might look appealing, a well-known facade pattern comes to mind at first, so I can totally understand this.



      However, I think the first pattern will work better in fact and here is why:




      1. You say that the "all-mighty" service can solve circular dependencies



        Well, circular dependencies usually point on a wrong / bad design and are code smell by there own, so hiding it behind a facade won't improve the system, resolving the circular dependencies will. In addition if from the actual services, called by "AllServices" you'll want to invoke additional service (again, bad design is preserved) then the code will probably pass through AllServices again, and hence the circular dependency is still there.



      2. Using the second design assumes that this "AllServices" class will be used by all the components of the system, but in this case it becomes a "one-central-point" and refactoring in this class can turn to a madness - all the components / their tests might be affected


      3. Initialization of this service can become a mess by itself, since you probably won't want to maintain a constructor that has 20-30 input parameters you'll resort to field injection (like in the example) which is bad by its own because if you want to initialize it somehow, probably from test, or something you want know what should be mocked and what not, in which order, and so forth.






      share|improve this answer



























        3












        3








        3







        The second approach might look appealing, a well-known facade pattern comes to mind at first, so I can totally understand this.



        However, I think the first pattern will work better in fact and here is why:




        1. You say that the "all-mighty" service can solve circular dependencies



          Well, circular dependencies usually point on a wrong / bad design and are code smell by there own, so hiding it behind a facade won't improve the system, resolving the circular dependencies will. In addition if from the actual services, called by "AllServices" you'll want to invoke additional service (again, bad design is preserved) then the code will probably pass through AllServices again, and hence the circular dependency is still there.



        2. Using the second design assumes that this "AllServices" class will be used by all the components of the system, but in this case it becomes a "one-central-point" and refactoring in this class can turn to a madness - all the components / their tests might be affected


        3. Initialization of this service can become a mess by itself, since you probably won't want to maintain a constructor that has 20-30 input parameters you'll resort to field injection (like in the example) which is bad by its own because if you want to initialize it somehow, probably from test, or something you want know what should be mocked and what not, in which order, and so forth.






        share|improve this answer















        The second approach might look appealing, a well-known facade pattern comes to mind at first, so I can totally understand this.



        However, I think the first pattern will work better in fact and here is why:




        1. You say that the "all-mighty" service can solve circular dependencies



          Well, circular dependencies usually point on a wrong / bad design and are code smell by there own, so hiding it behind a facade won't improve the system, resolving the circular dependencies will. In addition if from the actual services, called by "AllServices" you'll want to invoke additional service (again, bad design is preserved) then the code will probably pass through AllServices again, and hence the circular dependency is still there.



        2. Using the second design assumes that this "AllServices" class will be used by all the components of the system, but in this case it becomes a "one-central-point" and refactoring in this class can turn to a madness - all the components / their tests might be affected


        3. Initialization of this service can become a mess by itself, since you probably won't want to maintain a constructor that has 20-30 input parameters you'll resort to field injection (like in the example) which is bad by its own because if you want to initialize it somehow, probably from test, or something you want know what should be mocked and what not, in which order, and so forth.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 11 '18 at 6:50

























        answered Nov 11 '18 at 5:49









        Mark BramnikMark Bramnik

        11.5k32445




        11.5k32445























            2














            Second approach may look cleaner, but it will be difficult to know which service is connected to service/DAO and therefore it will be hard to refactor or do/decide on which regression any change will cause. Meaning it effect software flexibility



            This is the important difference which make the difference to choose first option IMHO






            share|improve this answer























            • I don’t think that is so very difficult to find dependencies for a Spring component using the second approach. Besides Spring components should be independent enough to make no big regression to others.

              – serg kunz
              Nov 11 '18 at 5:52











            • @sergkunz in second approach you can have circular dependencies, just with more clutter

              – user7294900
              Nov 11 '18 at 5:58















            2














            Second approach may look cleaner, but it will be difficult to know which service is connected to service/DAO and therefore it will be hard to refactor or do/decide on which regression any change will cause. Meaning it effect software flexibility



            This is the important difference which make the difference to choose first option IMHO






            share|improve this answer























            • I don’t think that is so very difficult to find dependencies for a Spring component using the second approach. Besides Spring components should be independent enough to make no big regression to others.

              – serg kunz
              Nov 11 '18 at 5:52











            • @sergkunz in second approach you can have circular dependencies, just with more clutter

              – user7294900
              Nov 11 '18 at 5:58













            2












            2








            2







            Second approach may look cleaner, but it will be difficult to know which service is connected to service/DAO and therefore it will be hard to refactor or do/decide on which regression any change will cause. Meaning it effect software flexibility



            This is the important difference which make the difference to choose first option IMHO






            share|improve this answer













            Second approach may look cleaner, but it will be difficult to know which service is connected to service/DAO and therefore it will be hard to refactor or do/decide on which regression any change will cause. Meaning it effect software flexibility



            This is the important difference which make the difference to choose first option IMHO







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 11 '18 at 5:30









            user7294900user7294900

            21.7k113258




            21.7k113258












            • I don’t think that is so very difficult to find dependencies for a Spring component using the second approach. Besides Spring components should be independent enough to make no big regression to others.

              – serg kunz
              Nov 11 '18 at 5:52











            • @sergkunz in second approach you can have circular dependencies, just with more clutter

              – user7294900
              Nov 11 '18 at 5:58

















            • I don’t think that is so very difficult to find dependencies for a Spring component using the second approach. Besides Spring components should be independent enough to make no big regression to others.

              – serg kunz
              Nov 11 '18 at 5:52











            • @sergkunz in second approach you can have circular dependencies, just with more clutter

              – user7294900
              Nov 11 '18 at 5:58
















            I don’t think that is so very difficult to find dependencies for a Spring component using the second approach. Besides Spring components should be independent enough to make no big regression to others.

            – serg kunz
            Nov 11 '18 at 5:52





            I don’t think that is so very difficult to find dependencies for a Spring component using the second approach. Besides Spring components should be independent enough to make no big regression to others.

            – serg kunz
            Nov 11 '18 at 5:52













            @sergkunz in second approach you can have circular dependencies, just with more clutter

            – user7294900
            Nov 11 '18 at 5:58





            @sergkunz in second approach you can have circular dependencies, just with more clutter

            – user7294900
            Nov 11 '18 at 5:58

















            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%2f53245990%2fjava-spring-design-all-in-one-component%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

            𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

            How do I collapse sections of code in Visual Studio Code for Windows?

            ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ