6

If I want to create a conceptual model for my new application, and during the analysis, I found that some objects like employee, department ..etc are a part of another system. and all the data related to them like employee name or number exist in that system.

My questions here:

  • How to handle this case in my conceptual model? Should I include these objects and their responsibilities in my conceptual model?
  • How to implement them in my application (Hint: I'm going to use asp.net MVC and EF6 code-first)
  • I think you woul dneed to give some information about what your concept is – Ewan Apr 4 '18 at 11:16
  • @Ewan : Could you explain what the needed info please ? – Anyname Donotcare Apr 4 '18 at 11:17
  • well if your app takes employees and moves them between departments depending on their address for example. then yeah its going to be hard to explain your idea without including those concepts – Ewan Apr 4 '18 at 11:19
  • @Ewan: Well I'll try to explain in concise statements, I create time and attendance system to set employees in specific schedules which consist of shifts, and from another point of view I have main roles in that system: system admin, HR employee, department managers...etc who interact with my system. objects like employee,department, contract, camp ...etc are objects which i need data from. and these objects are in another system. – Anyname Donotcare Apr 4 '18 at 11:28
6

IMHO you should model those objects to exactly the degree you need them in your application, no less, no more. For example, don't model all available attributes, just model the attributes which are required by your program. If there is an external entity where you need only one or two attributes in your system, you may consider to add those attributes to an existing internal entity. If you need more, consider to model the external entity with the required attributes, but try to keep naming identical or at least consistent.

This is valuable information for implementing the code of your application. If you would exclude the objects from your model, writing a cohesive description would become much harder.

If you think it is helpful for the audience of your conceptual model, use a consistent way of tagging the entities or attributes as external entities. For example, in UML you could introduce a special stereotype for this. Or you use some kind of comments or annotations, depending on the notation you are using for your model.

Later, when you are going to implement this, you will probably need some kind of proxy-like objects for accessing the external entities, containing exactly the attributes you modeled above. So in this sense, the objects are also part of your system, at least to a certain degree.

How you implement them exactly depends heavily on the details. For example,

  • if your system needs only read-only access to those external entities or also write access,

  • if there are immutable keys in those entities which allows your system to create references (or not),

  • if there are some inconsistencies tolerable between the proxies in your system and the external system (at least for a certain period of time)

  • what kind of API the external system provides

Depending on such details, you may decide between

  • implementing proxy tables for those objects with some kind of synchronisation strategy, or just

  • implementing them as database views, or

  • with no database representation at all, just by pulling the attributes into your client objects using some code.

  • Thanks a lot for your great answer. I have three questions please. 1- Do you mean by proxy the Proxy pattern? 2-Could you clarify what did you mean by immutable keys? 3-This question is a big one. Could you help me how to get the required knowledge in real world for subjects like this. I mean I want to know how to architect my app well, How to take a decision in situations like the above, Are there any Courses or books you recommend for me :D – Anyname Donotcare Apr 11 '18 at 14:21
  • 1
    @AnynameDonotcare: 1- no, I just tend to call them that way since they probably shadow the "real" objects in the external system. 2. If, for example, employees in that external system expose an ID which is guaranteed to never change, your system can try to utilize these and store this IDs instead of the employees data. If there are no such IDs, your system may need to store a copy of the employees data. 3- I obviously cannot teach you conceptual modeling in a comment here ;-). Popular books are "Domain Driven Design" by Evans and "Analysis patterns" by Fowler. – Doc Brown Apr 12 '18 at 19:16
  • I’m so grateful for you ☺️ I’ve learned a lot from your answer, thanks for patience 🎈 – Anyname Donotcare Apr 12 '18 at 19:40
4
+100

OK so! your application is a "shift management app"

In essence this app doesn't really care about employees and departments. It will care about when the business day starts and ends, how many people are working at the company, how long a shift is etc.

So you should exclude them from your conceptual model. It will only complicate it. Perhaps for example, sometimes a shift is not filled by an 'Employee' as defined by the other system. Perhaps its a contract worker or some such.

Create new models for the object you do need Shift, Person, BusinessDay etc and describe the system in those terms.

When you actually come to make the system use those same objects, so that it is flexible enough to work with any data, but link them up to the other systems with a separate export or mapping layer.

For example. Imagine instead of writing your own Shift Management App you have decided to buy one 'off the shelf'. You wouldn't expect the off the shelf app to be able to connect directly to your existing employee models. Its got to be able to work with many possible sources of data.

You would however expect there to be an API or Import/Export function that would allow you to link your existing systems to it. Using your Employee data to populate its ShiftWorker data.

Writing your own in house product will allow you to tie the two models more closely than an off the shelf product would. But you should still respect the separation of concerns between the two systems and provide a Mapping or Anti-Corruption Layer abstraction between them.

enter image description here

  • Thanks a lot, I'll be grateful if you explain more, because I need some general tips not just for this specific project. What I've understood from your answer that, you want me to create two models one for my original objects like shift,schedule,working hours,...etc and another one for the external entities like employee, department, ...etc . I'm so confused :( – Anyname Donotcare Apr 4 '18 at 11:53
  • 3
    I think Ewan is trying to say that these models employee, department, ... might (or might not) to have the same representation and meaning that they have in their respective systems. For example, what you call employee maybe is a mere "user" or "person" with half of the attributes that the former representation. Perspective. To my boss, I'm a Senior Software Engineer with a set of skills. For HR I'm a name, an age, a married status, etc. At the moment of getting paid, I'm just an account in a bank somewhere. So, conceptualise these models you need under the needs of the project in play – Laiv Apr 10 '18 at 8:03
  • @AnynameDonotcare added a bit more. does that make it clearer? – Ewan Apr 15 '18 at 14:14
  • @Ewan Thanks a lot, Could you illustrate more about the implementation please – Anyname Donotcare Apr 16 '18 at 9:17
  • @AnynameDonotcare added a diagram – Ewan Apr 16 '18 at 9:45
2

I believe that the answer from @Ewan covers the specific scenario provided, so this will follow a more generic/general route, where possible. (Note that the below examples are only used to show a similar perspective)

The first thing that comes to mind to help with your confusion is to show some relatable issues seen when dealing with differing namespaces, for this case we can look at enums. For instance, if we have an object in some data layer to act as a "Master" enumeration that defines the typing for a given entry. (EX: PersonEnum { Employee = 1, Manager = 2, Contractor = 3, CEO = 4, Vendor = 5, ...})

When coming up to some use case, there could be an instance where an enum (ValidPersonEnum) is defined to state which of the PersonEnum values are valid for the use case. For example, employees and managers can only be shown in a salary report, contractors can be shown in both salary report and project cost summary, and vendors on show in the project cost summary.

When checking these values against each other (is the given entry of the type Employee?), an error occurs, where the namespace is used to define the type of the enum. With this in mind, we can approach a high-level standpoint using your example.

For the external system Employee, it is defined within that system as part of its concept. For your system, you can use Employee, via data or methods, but that Employee is essentially changed to YourSystem.Employee rather than ExternalSystem.Employee.

For your model, Employee could then be shown in respect of how the current application uses it rather than how the external system does. To branch on @Ewan's point, this confusion could be cleared up via some form of abstraction. This could be used in your application as a concept of Person as a base, and Employee as some implementation of Person.

With being general, I would like to note that there can be times, where you would/could want to include the concept from the external system. These would fall more under extension type applications, where the new application will manipulate (create/modify) data within the external system.

So for your first question, you would not necessarily be stating the responsibilities of Employee in respect to the external system. Employee should be stated for its responsibilities in your model, and there could be similar methods depending on what is needed. This model would then be in respect to the target application. If you tried designing the model around another system, then it may end up looking more like an addition to that existing system rather than a separate application.

Also, if a model depended on how an object is used in a separate system, then it could become more difficult to get some new applications off of the ground, since the object(s) can change at anytime for any reason(s) outside of the new application (during and after designing a concept model).

If you decide to state the data source of each item, then you could include the path (file, database server, etc.) or some named process dependencies (nightly refresh or some other external data processing).

As far as the implementation question, this is where you have different levels to review. The concept will give you a road map for your application (X class holds a list of Y class to determine if action Z can execute, or M class cannot exist without L class). When implementing the concept, the data source can be defined, since the concept may not have the opportunity to have defined a source. These implementation step(s) would end up being the place that defines the interactions with other systems (Employee data is retrieved based on the external system).

Again, the above examples were only given as an attempt to show a similar perspective, and I think @Ewan's answer covers the same points in respect to your example. I hope that my examples help bridge the provided concepts.

1

Those entities are not really yours and can be changed outside of your "system" but you can provide linkage to them.

For example, here is your Employee model entity (which will also be the EF code first class):

public class Employee
{
    // Your key and anything else besides whatever the external entity provides
    public int Id { get; set; }        

    // 1-to-1 relationship to the external entity
    public virtual ExternalEmployee ExternalEmployee { get; set; }
}

And here is the ExternalEmployee model entity (and code first class) which provides you with whatever properties you want from the external entity by mapping to a database view (see the DbContext below):

public class ExternalEmployee
{
    public int Id { get; set; }
    public string Name { get; set; }

    // 1-to-1 relationship to your Employee
    public virtual Employee Employee { get; set; }
}

The EF DbContext (vw_ExternalEmployees is a database view providing all data to ExternalEmployee):

public partial class MySystemContext : DbContext
{
    // ...

    public virtual DbSet<Employee> Employees { get; set; }
    public virtual DbSet<ExternalEmployee> vw_ExternalEmployees { get; set; }
}

Your EmployeeRepository is responsible only for your Employee, of course. As a consequence, in your service layer (e.g. EmployeeService) if changes need to be made to the external data they must be delegated to the corresponding services responsible for the external entities.

  • you are recommending EF and linked databases? – Ewan Apr 15 '18 at 14:08
  • @Ewan EF was originally hinted by the author of the question. Whether there is one or more databases is another topic altogether beyond the scope of this discussion. FWIW, my answer does not depend on or otherwise suggests linked databases. – dpant Apr 16 '18 at 4:14

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.