When subclassing is it better to “Copy Paste, then Refactor”, or “Refactor, then Implement”

I currently have a class Foo,
i’ve decided I need a second type of Foo where I want to test out a significantly different implementation. It will no doubt share some functionality with Foo so I’ll need to create a Abstract Class parent for both of them.

At the end of the process I want to have:

  • AbstractFoo: an abstract class
  • FooBoo: functionaly identical to the original Foo
  • FooBar: the new subclass of AbstractFoo I’ve created.

There are two ways I could go about this:

Copy Paste, then Refactor

  1. Create a copy of Foo, and name it FooBar and rename Foo to FooBoo
  2. Edit FooBar with the new implementation
  3. Inspect, FooBar and FooBoo, move methods that are the same between them into a abstract class AbstractFoo, which both inherit from

Refactor, then Implement

  1. Rename Foo, FooBoo
  2. Consider what methods are not related to the part of the implementation that FooBoo and FooBaz are going to be different in. Move these to AbstractFoo
  3. Create FooBaz and reimplement all the methods that remain within FooBoo

Which is to be preferred?
*Is there another method?*

Last time I had to do this, it was because the I decided that Foo had 2 different modes, that was determined by a boolean passed into the constructor.

This time (on a different class), it is because I want to try out using a different engine underneath that might be faster.
I want to keep FooBoo around because it has a subclass that I think will be much harder to implement for FooBaz, and I also want to be able to check that in the end they behave the same.

2

I would do it this way:

  1. Rename Foo to AbstractFoo and make it abstract
  2. Create FooBoo that derives from AbstractFoo
  3. Push down all methods from AbstractFoo to FooBoo leaving behind only abstract methods
  4. Implement FooBar

I like this because most of it can be achieved using refactor functions of IDE. This makes sure that you don’t have to manually change code where Foo was used. Also, compiler gives you errors in places where you used Foo‘s constructor, because it cannot instantiate abstract class.

2

Hard to say, it depends on the case, what approach makes the most sense.

If most of the stuff is going into the base class, I’d either use your “Refactor, then Implement” approach, or follow a slightly changed variant of @Euphorics’ approach: I would make sure everything works as before after his Step 3 (completed AbstractFoo and FooFoo) and before moving on to his Step 4 (creating FooBar).

In some cases, it is the other way round. You decide for a common base class, which actually will have only a few methods from old Foo. In that case, rename Foo to FooFoo, create an empty AbstractFoo and move just the few methods into the new base (don’t forget to change FooFoos inheritance).

I have also used the “copy + paste + refactor” approach. It can be useful, when the methods to move to the base compared to the methods that need to stay in FooBoo are around 50:50 distribution. Again, it depends, and sometimes you’ll find during refactoring, that you need another class to extract things from the Foo class family.

0

I would go with the copy+paste approach as a starter, that gives you flexibility to do whatever you want with the new class without bringing any unintended side effects into existing code. This would sort of fall under the “tracer application” pattern since your main intent is to try out a completely new engine.

When you have your successful result(s) from your copy+pasted code you will follow the test driven pattern and refactor out the common bits into your abstract base class etc. This would come close to what is discussed in Kent Becks Test-Driven Development by example as well as the common work patterns discussed in the pragmatic programmer.

IMHO the above is how I would approach this problem most of the times since it leaves room for wild crazy experimentation without affecting the already working and tested code with the least amount of effort (eg. no current tests will be modified or broken etc and logic stays intact). The big effort comes when you have your working tracer to either throw it away and write a clean implementation based on your tracer code or to start integrate it with your actual code base.

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