Should I try it straight or should I first check if it can be done?

I have a set of items, and each item in the set must be unique. Item are composed from multiple properties and each property of each item can be changed. But after each change every item in the set must still be unique.

Should I simply try to change the property:

int err = setOfItems.SetPropertyOfItem( item, property, newValue )
if ( err != 0 ) {
    MessageBox( "You cannot change property to this value" );      
    return;
}
// ( ...or similar exception based code )

Or should I first check if the property can be changed and only then change it:

if ( !setOfItems.CanBePropertyChanged( item, property, newValue ) ) {
    MessageBox( "You cannot change property to this value" );      
    return;
}
setOfItems.SetPropertyOfItem( item, property, newValue );

Which approach is better and why?

3

As long as the SetPropertyOfItem method reliably doesn’t change the property when it detects a conflict, I would always choose the first way of doing things. Separating checks from actions can work, but it’s prone to misuse by callers who perform the action without performing the check. And folding the check into the action method can lead to wasted effort if you also have a separate check method that a confused caller might call without need.

One problem with returning error codes is that the caller might forget to check it, and falsely assume that a change has occurred when it hasn’t. If this is likely to be a problem, raising exceptions instead of error codes is an option.

(There are also people who advocate that you should never return anything from a method with side effects. I consider that short-sighted extremism, like claiming that the 100% pure functional style is the right choice for everything. I think design decisions always have to be made considering the pressures and context in the current situation.)

1

It depends on domain and UI requirements. Should a site/programs warn a user about possible problems? If so, you need a method to check.

bool CanBeChanged(item, property, newValue);

An usual setter must be an usual. It’s void, i.e. it raises an exeption:

void Change(item, property, newValue);

What if a user doesn’t want an exception, he wants the return code:

bool TryChange(item, property, newValue);

The “Try” word tells to a user of class, that the method doesn’t raise any exceptions.

Since a check for uniqueness can be a long operation, TryChange can lead to error in multithreading app. A user may be in doubt: is your method thread-safe?

bool TryChangeConcurrently(item, property, newValue);

In general it’s a bad practice to disclose details of the implementation in names of domain’s classes and methods, so TryChange is still preferable. Consider, domain classes must be thread-safe as possible.

Of course, all of this are general considerations.

In C++ can_be_changed should be declared as const. Declaration of change in Java should contain throws clause, while canBeChanged and tryChange shouldn’t. In C# any setter method has a form set[item, property] = value. Each language offers its own idioms and we can best follow them.

Summary: I would leave all three methods, and I’d try to make the class thread-safe.

(disclaimer: use of Java knowledge below)

In your second solution, I presume one of the two approaches will take place for CanBePropertyChanged:

  1. Loop through all the other entries of your Set to make sure none contain oldProperty1, oldProperty2newPropertyN.
  2. Construct a temporary object temp with oldProperty1, oldProperty2newPropertyN and using a standard method, e.g. Set.contains(temp), check that the method returns false.

If there are no matches, then your SetPropertyOfItem will apply the new property without further checks.

In your first solution, I presume it is doing something similar to the approaches for CanBePropertyChanged, just that this is done as the first step within SetPropertyOfItem. If the Item cannot be modified, then you return a non-zero ‘error code’.

The problem I see with (1) above is that you will be duplicating your class’s equivalence checking, which may not be future-proof if your Items gain new properties or constraints that affects how this equivalence is done. For both solutions, concurrency, should you choose to implement that, introduces the small possibility that the actual modification of your Item object is not in sync with other concurrent read/write operations on either the Set or Item object.

Alternatives?

Therefore, I’ll approach this by asking this question: How costly is it to re-construct a new updatedItem with oldProperty1, oldProperty2newPropertyN? If that is a relatively cheap operation (e.g. you don’t need to send these properties to a database to retrieve data that needs further parsing), why not consider making Item an immutable class? This will be similar to using approach (2), just that you will be adding the non-temporary (permanent till the next modification) new updatedItem into your Set, and removing the old originalItem from it. If it helps, you can even introduce a bit of syntactic sugar:

Item updatedItem = oldItem.createWithUpdate( property, newValue ); // creates a new object
if ( set.add( updatedItem ) ) {
    set.remove(oldItem);
} else {
    log.warn( "You cannot change property to this value" );
}

Your code can be simpler as a result. Also, a Set by definition does not contain duplicate values, so the statement

But after each change every item in the set must still be unique

Is practically a given after an add() operation (which, in Java, returns true if the Set did not already contain the specified element). Also, when your class is immutable, there is less cause for worry introducing concurrency, since objects themselves wouldn’t be mutated out-of-sync. You will only need to code defensively against concurrent operations on your Set object.


To answer the question directly

Ok, if Item is in fact already immutable, or you prefer not to make the proposed changes above, and I have to take my pick from either two approaches, I will go with the first solution. However, instead of an int-based return code, I will either return a boolean or use exception-handling. I will favor the first solution because it opens up the possibility in the future to change the implementation of SetPropertyOfItem, broadly speaking. @Kilian Foth’s answer says it better in this regard.

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