Interface at the class or function level?

I have been falling into a pattern lately where I have been defining routines that rely on an interface defined by a function that is specified as a parameter to the routine. (The language is C#, but this can be applied to any language with first-class functions.)

For example, I have an API that exposes CRUD operations against a backing store. In the case of a GET operation on a particular resource, I can generalize the routine into:

  • get the resource we are looking for
    • return a not found response if resource does not exist
    • return the resource if found

What I ended up doing is defining a routine that accepts a delegate function for finding the resource. It’s this delegate that defines the interface contract.

This happens to work well for my situation because the information required to locate the resource can vary. In my case, it’s looking up data in a database by keys, but the type and number of keys can vary. I can capture these in a closure in the calling routine and satisfy the delegate function interface. For example:

// Locate a simple record that only has one key
public SimpleRecord GetSimpleRecord(int recordID) {
   return getResource(repository => repository.SimpleRecords.Find(recordID));
}

// Locate a complex record that has many keys
public ComplexRecord GetComplexRecord(int recordID, int userID, string token) {
   return getResource(repository => repository.ComplexRecords.Find(recordID, userID, token));
}

This work, but seems like is a mix of OOP and functional style programming. If I need more than one delegate passed, it starts to get a bit messy. Some routines that I need everywhere I ended up defining as abstract methods that all sub-classes need to implement. So I have a hybrid.

Does this type of technique have a name or pattern that I’m missing? Should the delegates be implemented in a defined class interface that gets passed to the caller?

UPDATE with more concrete example:

I’m trying to adhere to the DRY principal. I’m talking about controllers in a C# Web API application. Each and every request has some commonality which I have implemented in a base controller class:

  • Handle all exceptions by returning the correct HTTP status code, (404 for resources that are not found, 201 for created resources, etc.)
  • Map database entities to-and-from data transport objects that the client deals with

I want to express what to do in this base class, and delegate how to the concreate class. The how ends up being implemented by delegate functions. I may need to get a person from the database, by first name and last name, or a purchase order, by an integer id. In both cases, if the resource is not found, a 404 must be returned. One returns a person, one a purchase order. How to look them up and how to map the data to a client object differs.

The base function may look like this:

T getResource<T> (Func<IRepository, T> find) {
    T data = find(getRepository());
    if (data == null) {
        throw new DataNotFoundException();
    }
    return data;
}

Now, in the person controller and purchase order controller, I don’t have to repeat the logic of what do to when the resource is not found–just implement the find delegate. (This is a simple example without mapping, adding, removing or other details that differ resource to resource).

public Person Get(string first, string last) {
   return getResource<Person>(repository => repository.People.Find(first, last));
}

public PurchaseOrder Get(int id) {
   return getResource<PurchaseOrder>(repository => repository.POs.Find(id));
}

Note how the closures above neatly deal with varying number and types of parameters for finding things, but satisfy the interface defined by the delegate find function. Is this possible to do with standard class interfaces?

(And this question is not about the repository. That is resolved with dependency injection and is implemented with Entity Framework.)

4

I immediately think of two patterns that can be of use for your case.

Template method pattern

Everything that is the same for all concrete implementations resides in a single abstract class. All that is more concrete is delegated to subclasses. If I were you, I would first try this one.

Builder pattern

If you need more flexibility, e.g. if using the Template Method Pattern you would have to create a broad hierarchy of abstract classes, you may benefit from the builder pattern. Turning imperative code into a more descriptional object is exactly what you obtain with this pattern. All that remains for client applications is then to create and pass a concrete description of what you want to CRUD from the backing store.

You might have more indirection than you need. For example:

public SimpleRecord GetSimpleRecord(int recordID) {
   return getResource(repository => repository.SimpleRecords.Find(recordID));
}

could simply be:

public SimpleRecord GetSimpleRecord(int recordID) {
   return repository.SimpleRecords.Find(recordID);
}

Assuming that Repository fulfills an interface contract like IRepository, you can simply inject a repository that draws from the correct data source.

public class DataAccess
{
    IRepository repository;

    public DataAccess(IRepository repository)
    {
        this.repository = repository;
    }

    public SimpleRecord Find(int recordID)
    {
        // etc.
    }
}

2

Why not just use assert-like function?

public T Exists<T>(T val) where T : class
{
    if (val == null)
        throw new DataNotFoundException();
    return val;
}

And then use it:

public Person Get(string first, string last) {
   return Exists(repository.People.Find(first, last));
}

But this probably applies only for your simple example. But we don’t know how complex your requirements are if you don’t describe your complex cases. I think you are approaching this problem from bad side. While C# has few functional properties, it is not a functional language. Trying to solve problems in functional way is never going to look nicely.

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