Refactoring an existing abstract class and its parameters

I have an abstract class A which declares an abstract method doStuff. Currently there are many classes that inherit from A and implement doStuff.

The class’ instances are initialized at run-time via AFactory based on user input.
Originally all the classes had the same single parameter (the user input). But now I have an additional parameter that only a new class that inherits A needs.

So breaking it down I though of the following logic:

  • The interpreter class that generates instances based on user input(using AFactory of course) was not aware of this extra parameter.

    • Trying to push it into the class interpreter class would be really awkward because then I would have to know when to pass it to the factory which defeats the whole purpose of having a factory in the first place.
    • Sending it blindly into the Factory hoping it might do something with it seems quite ugly as well.
  • My current solution: Meanwhile I’ve decided to refactor A.doStuff(Param param) into A.doStuff(AParams params).

    AParams can hold what ever parameters needed and doStuff can ignore then if they’re not interested in them. This also seems a bit awkward to me , and remids me of sending structs in WIN32API that can hold a lot of ugly useless parameters and I’m not fond of it.

Is there a more elegant way to approach this problem ? Or some design pattern that I’ve overlooked and solves this?

Notes :

  • We’re using Java 1.7
  • The class’ names are silly in order to emphasize the theoretical design issue they do have normal indicative, meaningful names in reality 🙂
  • I did search quite a lot but having figured out that it’s quite hard to search the web for specific abstract theoretical issues (as opposed to why is X throwing Exception in this code) I’ve decided to ask anyway so I’m sorry if this is a duplicate.

Edit 1:

  • Clarification: I need to pass a subclass-specific argument to the doStuff method.

EDIT 2:

  • I did not fully understand Kilian Foth’s intention so I’ve written some Java-pseudo-code to help me better explain the problem/understand your solution. So:

    This is a skeleton of my problem.

    This is a skeleton of my solution.

    This is what I think might be Kilian Foth’s solution, but I’m not sure.

6

The point of a factory is to hide the fact that you may get objects from slightly different classes. Therefore, if some of these objects need certain data and others don’t…

  • Either they aren’t similar enough to be produced by the same factory. Then you need to have more than one factory and make the decision way earlier than you are currently doing.

  • Or they are similar enough that the client isn’t supposed to care which one they get. Then you can’t expect the client to care about whether to send the extra data or not. It follows that they must always be passed, but the factory will sometimes ignore them without bothering the client with that implementation detail. Anything else would burden the client with the very distinction that the factory was supposed to conceal.

1

I handle this by using something like a Builder that contains various factories. The Builder is given hashes that contain the factories to make various types of objects, and it will look into the hash and retrieve the correct factory based on whatever criteria.

For example, I have multiple question types, and all of these can be made by some implementation of an IQuestionFactory. Most of the IQuestionFactory implementations are subclasses of BaseQuestionFactory, and they receive XML that represents one question and parse it according to the rules of the question, returning back some subclass of BaseQuestion.

Some questions need more information, such as if it is a form-filling question there might be a section of the XML that contains the questions that defines the fields that are used in the form. The Factories that make these questions implement IEnhancedQuestionFactory, and the builder will check the Factory that it retrieves from the QuestionFactoryRegistry and check to see if it implements this Interface. If it does, it passes the full XML of the file that contained the questions in addition to the individual XML that goes to the createQuestion method.

To show you how flexible this can get, some of the IQuestionFactory implementations are simply shells that contain multiple question factories, and they can look at the incoming XML and then call an internal factory and return whatever that makes. We use this when an XML file contains multiple question types.

However, it sounds like you need something more like the way we build Exercises (which are essentially Controllers wrapped around a collection of Questions), where the hash (ExerciseFactoryMap) is set up to return a default factory most of the time, but in cases where it has a specific Factory registered, it will return that. And we do have one specific Factory that will create an Exercise subclass that has an additional property, and it has the additionall capability to look at the XML and find the information that it needs to populate that property.

So, I’d agree with Killian Foth that the point of a factory is to hide the implementation details of how the object is being constructed, but there’s nothing that says you can’t combine multiple Factories in creative ways (for example, a Factory that contains other Factories that do the real work).

  • The usual approach in cases like this (Command patternish) is passing additional parameters in the constructor. In your case, that means adding otherArgument to B during construction.

  • Turning the logic around might open up some options. For instance moving doStuff to AParams:

    for (String arg : listOfArgs) {
        AParams p = AParams.create(arg, otherArgument));
        for (A a : listOfA) {
            p.doStuff(a); // Let AParams to the lifting depending on type of A
        }
    }
    
  • Alternatively you can swallow your pride and check with instanceof in the loop and set otherArgument manually before calling doStuff.

If the above is not possible, then you have no choice except doing what you’re doing (broadening the parameter argument). Don’t overanalyze this stuff.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật