2
\$\begingroup\$

I am developing an online shopping website.

I have a class Item, which contains all the common attributes of all products (I will explain the interfaces at the end)

// all products common attribues
public class Item: ISearchItem {
        public int? itemId { get; set; }
        public int userId { get; set; }
        public int price { get; set; }
        public string title { get; set; }
        public string description { get; set; }
        public string category { get; set; }
    }

I have Address class similar to Item:

public class Address: ISearchAddress {
    public int? addressId { get; set; }
    public string AddressLine { get; set; }
    public string City { get; set; }
}

And Media Class, which is Similar (except it does not have any interface)

public class Media {
    public int? mediaId { get; set; }
    public string photos { get; set; }
    public string videos { get; set; }
}

Now I have the actual Items that I am selling, which contain the common classes and have their own extra properties:

public class Shirt: ISearchShirt {
    public int? shirtId { get; set; }
    public Item item { get; set; }
    public Address address { get; set; }
    public Media media { get; set; } 

    public string size { get; set; }
    public string color { get; set; }
}

public class Book : ISearchBook{
    public int? bookId { get; set; }
    public Item item { get; set; }
    public Address address { get; set; }
    public Media media { get; set; } 

    public string author { get; set; }
    public int noOfPages { get; set; }
}

Now I want to search the products on my website and I am using Elasticsearch. I need to define one (and only one), ElasticSearchDocument class that contains all Searchable fields of all products. I will use this class to periodically send the searchable fields to ElasticSearch (which maintains it's own copy of my Data, in order to search the data).

public class ElasticSearchDocument : ISearchItem, ISearchAddress, ISearchShirt, ISearchBook
{
    // searchable fields of Item
    public int? itemId { get; set; }
    public int description { get; set; }
    public string title { get; set; }
    public string category { get; set; }

    // searchable fields if Address
    public string city { get; set; }

    // searchable field of Shirt
    public string size { get; set; }
    public string color { get; set; }

    // searchable field of Book
    public string author { get; set; }

    // Media is not needed for search
}

Now, the reason I have defined the interfaces is that, interfaces define the searchable properties of each class (Media does not need to be searched, therefore it has no interface)

public interface ISearchItem {
    int? itemId { get; set; }
    string title { get; set; }
    string description { get; set; }
    string category { get; set; }
    // note: price is not needed for search, hence not here
}

public interface ISearchAddress {
    string city { get; set; }
    // AddressLine is not searchable
}

public interface ISearchShirt {
    string size { get; set; }
    string color { get; set; }
}

public interface ISearchBook {
    string author { get; set; }
    // noOfPages is not searchable
}

I will explain why I have done this and my requirements. So users can create an advertisement for a product to sell on the website. The product could be a Shirt, Book, etc. Each product needs some common properties (which come from Item), an Address (to list the product in the correct region) and Media (photos and videos). In addition each product will have its own extra properties, like Shirt has size and color.

In my, MySQL database, I have these Tables: Item, Address, Media, Shirt, Book.

ElasticSearch is based on NoSQL. I need to have one document of all the searchable properties of each document and periodically send it to Elasticsearch.

The reason I have created the Interfaces is that without them, a developer may change Item but forget to update ElasticSearchDocument...

And the reason I am posting the Code (architecture) for review is to get some feedback if this architecture is good and get some feedback for improvement?

\$\endgroup\$
  • \$\begingroup\$ I will update my question, it is not simplified, I just have not included all of my classes. \$\endgroup\$ – user166431 Apr 18 '18 at 6:49
  • 2
    \$\begingroup\$ You don't have to share your complete project. Just the relevant classes, but you should not simplify what you post. This is what I meant. Currently it reads as if the classes already posted, were simplified. Sorry for the misunderstanding ;-) \$\endgroup\$ – t3chb0t Apr 18 '18 at 6:49
  • 2
    \$\begingroup\$ Instead of different Interfaces, couldn't you include all the searchable properties in one Interface, and only use the relevant ones for each class? \$\endgroup\$ – tinstaafl Apr 18 '18 at 14:13
  • 3
    \$\begingroup\$ I'm not sure what could be reviewed here - the code itself doesn't compile, and if you're looking for feedback on the overall design, then what are the requirements? How are those interfaces going to be used? How are your item classes going to interact with that ElasticSearchDocument class? Why can you only create a single document class? Will you only ever have to support shirts and books, or is it likely that other kinds of products will be added later? Why do those item classes contain an Item rather than inherit from it? What does it mean for a shirt to have an address? \$\endgroup\$ – Pieter Witvoet Apr 18 '18 at 14:25
  • 1
    \$\begingroup\$ It could still implement the interface, just give the properties it doesn't need default values(null?) that the search class can easily filter out. \$\endgroup\$ – tinstaafl Apr 18 '18 at 21:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy