I have a situation whereby a predecessor has created a class that is designed to handle the creation of Note entities that are added to the database to journal actions that are carried out by the system across the site.
At present, this class has been broken down into several CreateXYZNote methods that take an enum denoting a specific note type, and an instance of the model that drives that area of the site.
My problem is, there are so many types of notes, each used only in one or two places across the system. Each of the methods is huge, consisting of a small amount of common code, and specifics (e.g. the textual content of the note) are held within a series of switch statements based on an enum. Extremely hard to find the code relating to specific notes, and very hard to maintain at present, and it's only going to grow as new types of notes find their way into the system over time.
Has anyone got any advice or patterns that could help with this sort of situation?
The simplest solution I can think of is that I have a set of profiles held outside of this class as a dictionary (keyed by the enum values) that define the title, description, categories etc. for the notes, and this class then becomes just a means of looking up those values and creating the note, but it just feels like I'm moving the problem to another place rather than resolving it.
You could use a NoteFactory that has a INote Create(NoteType type) method. The factory could depend on a Dictionary keyed by NoteType that the factory uses to find and return the appropriate Note. This way you avoid a non-OCP switch statement.
The factory can be injected with the dictionary, using an IoC container helps here, or you can create the dictionary in the constructor.
Related
I have a number of types for which I need to provide custom functions that talk to the external world.
For example, I may have a Widget, and a Sprocket, and when data from the world that I don't control arrives and says "make a Widget," then I need to call a Widget.Create() function.
If the world says "make a Hammer," then I need to return a "Hammer does not exist" error.
However, the mapping between world-representation and type-name is not 1:1, so I can't simply use reflection to find the type name directly -- I need a table. (In fact, "name" may for example be a specific integer value.)
I understand how I can use a pre-defined table (or Dictionary) that maps from world-representation to class-name.
I also understand how to extend/change this table at runtime if the set of possible classes changes. (Because of rules changes, or dynamically loaded parts of the application, or whatever.)
However, all of that requires duplication -- I have to both implement my class, and then, in some other place in the code, remember to add an instance of "this class has this name in the external world."
This is a bit of a code smell, because sometime in the future I will write a new class (or delete an old class) and forget to update the table, and then spend time debugging why it doesn't work right.
I thought I could use a static member in each class which registers itself in a global table:
public static Registration Me = new Registration(typeid(MyClass), "My Name");
Unfortunately, static fields are not initialized until some function in the class is executed/accessed, so this doesn't run at start-up. (Static constructors have similar limitations, plus even more overhead in the runtime!)
The next idea was to decorate the class with a custom attribute that says "register this class in the table."
[Register("My Name")]
class MyClass : .... {
}
Unfortunately, the "Register" attribute doesn't know what class it is attached to -- only the MyClass class knows that it has the Register attribute. (This is infuriating to me, as it would be SO CONVENIENT if attributes knew where they were attached, in many, many cases. But that's an aside!)
So, the least bad implementation I can think of is to iterate all the types of all the assemblies, using reflection, and check whether they have this attribute, and if they do, register them in the table. This is, shall we say, neither elegant nor efficient.
Is there a better way to auto-register classes without having to update some other source file with a central registry?
You could also iterate over all classes matching some criteria and use RuntimeHelpers.RunClassConstructor to ensure the static initializers all get run.
Something like:
var baseType = typeof(MyType);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(baseType));
foreach (var t in types)
{
RuntimeHelpers.RunClassConstructor(t.TypeHandle);
}
This should ensure all your
public static Registration Me = new Registration(typeid(MyClass), "My Name");
functions get called.
I have checked with other resources (that are quite knowledgeable about the internals of the CLR and IL) and it seems that this is a hole in the CLR and the C# language. There simply is no direct way of making things automatically happen on assembly load or appdomain preparation. Walking the types and finding the types that I'm interested in is the least bad way.
In fact, attributes aren't always created until some piece of code asks for them, so I can't use an attribute constructor with a type argument to auto-register, either!
This is of course not great, because if there are eight different pieces of code that each have their own kind of registration they want to do, each of those pieces have to iterate through all of the types and do the inspection on their own. The only way around that would be to give up on modularity, and make all of the different "things" that happen to types be centralized to a single walk-all-types loop at the start of the app. Third party libraries (including the MEF) still wouldn't go inside this loop, though, so there's just an unavoidable chunk of overhead here, OR an unavoidable piece of duplication -- my choice, as developer.
I have a database that contains "widgets", let's say. Widgets have properties like Length and Width, for example. The original lower-level API for creating wdigets is a mess, so I'm writing a higher-level set of functions to make things easier for callers. The database is strange, and I don't have good control over the timing of the creation of a widget object. Specifically, it can't be created until the later stages of processing, after certain other things have happened first. But I'd like my callers to think that a widget object has been created at an earlier stage, so that they can get/set its properties from the outset.
So, I implemented a "ProxyWidget" object that my callers can play with. It has private fields like private_Length and private_Width that can store the desired values. Then, it also has public properties Length and Width, that my callers can access. If the caller tells me to set the value of the Width property, the logic is:
If the corresponding widget object already exists in the database, then set
its Width property
If not, store the given width value in the private_Width field for later use.
At some later stage, when I'm sure that the widget object has been created in the database, I copy all the values: copy from private_Width to the database Width field, and so on (one field/property at a time, unfortunately).
This works OK for one type of widget. But I have about 50 types, each with about 20 different fields/properties, and this leads to an unmaintainable mess. I'm wondering if there is a smarter approach. Perhaps I could use reflection to create the "proxy" objects and copy field/property data in a generic way, rather than writing reams of repetitive code? Factor out common code somehow? Can I learn anything from "data binding" patterns? I'm a mathematician, not a programmer, and I have an uneasy feeling that my current approach is just plain dumb. My code is in C#.
First, in my experience, manually coding a data access layer can feel like a lot of repetitive work (putting an ORM in place, such as NHibernate or Entity Framework, might somewhat alleviate this issue), and updating a legacy data access layer is awful work, especially when it consists of many parts.
Some things are unclear in your question, but I suppose it is still possible to give a high-level answer. These are meant to give you some ideas:
You can build ProxyWidget either as an alternative implementation for Widget (or whatever the widget class from the existing low-level API is called), or you can implement it "on top of", or as a "wrapper around", Widget. This is the Adapter design pattern.
public sealed class ExistingTerribleWidget { … }
public sealed class ShinyWidget // this is the wrapper that sits on top of the above
{
public ShinyWidget(ExistingTerribleWidget underlying) { … }
private ExistingTerribleWidget underlying;
… // perform all real work by delegating to `underlying` as appropriate
}
I would recommend that (at least while there is still code using the existing low-level API) you use this pattern instead of creating a completely separate Widget implementation, because if ever there is a database schema change, you will have to update two different APIs. If you build your new EasyWidget class as a wrapper on top of the existing API, it could remain unchanged and only the underlying implementation would have to be updated.
You describe ProxyWidget having two functions (1) Allow modifications to an already persisted widget; and (2) Buffer for a new widget, which will be added to the database later.
You could perhaps simplify your design if you have one common base type and two sub-classes: One for new widgets that haven't been persisted yet, and one for already persisted widgets. The latter subtype possibly has an additional database ID property so that the existing widget can be identified, loaded, modified, and updated in the database:
interface IWidget { /* define all the properties required for a widget */ }
interface IWidgetTemplate : IWidget
{
IPersistedWidget Create();
bool TryLoadFrom(IWidgetRepository repository, out IPersistedWidget matching);
}
interface IPersistedWidget : IWidget
{
Guid Id { get; }
void SaveChanges();
}
This is one example for the Builder design pattern.
If you need to write similar code for many classes (for example, your 50+ database object types) you could consider using T4 text templates. This just makes writing code less repetitive; but you will still have to define your 50+ objects somewhere.
If my domain object should contain string properties in 2 languages, should I create 2 separate properties or create a new type BiLingualString?
For example in plant classification application, the plant domain object can contain Plant.LatName and Plant.EngName.
The number of bi-lingual properties for the whole domain is not big, about 6-8, I need only to support two languages, information should be presented to UI in both languages at the same time. (so this is not locallization). The requirements will not change during development.
It may look like an easy question, but this decision will have impact on validation, persistance, object cloning and many other things.
Negative sides I can think of using new dualString type:
Validation: If i'm going to use DataAnattations, Enterprise Library validation block, Flued validation this will require more work, object graph validation is harder than simple property validation.
Persistance: iether NH or EF will require more work with complex properties.
OOP: more complex object initialization, I will have to initialize this new Type in constructor before I can use it.
Architecture: converting objects for passing them between layers is harder, auto mapping tools will require more hand work.
While reading your question I was thinking about why not localization all the time but when I read information should be presented to UI in both languages at the same time. I think it makes sense to use properties.
In this case I would go for a class with one string for each languages as you have mentioned BiLingualString
public class Names
{
public string EngName {get;set;}
public string LatName {get;set;}
}
Then I would use this class in my main Plant Class like this
public class Plant: Names
{
}
If you 100% sure that it will always be only Latin and English I would just stick with simplest solution - 2 string properties. It also more flexible in UI then having BiLingualString. And you won't have to deal with Complex types when persisting.
To help decide, I suggest considering how consistent this behavior will be at all layers. If you expose these as two separate properties on the business object, I would also expect to see it stored as two separate columns in a database record, for example, rather than two translations for the same property stored in a separate table. It does seem odd to store translations this way, but your justifications sound reasonable, and 6 properties is not un-managable. But be sure that you don't intend to add more languages in the future.
If you expect this system to by somewhat dynamic in that you may need to add another language at some point, it would seem to make more sense to me to implement this differently so that you don't have to alter the schema when a new language needs to be supported.
I guess the thing to balance is this: consider the likelihood of having to adjust the languages or properties to accommodate a new language against the advantage (simplicity) you gain by exposing these directly as separate properties rather than having to load translations as a separate level.
I've got a class called List_Field that, as the name suggests, builds list input fields. These list input fields allow users to select a single item per list.
I want to be able to build list input fields that would allow users to select multiple items per list, so I have the following dilemma:
Should I do that through implementing a multiple_choice_allowed property into the existing List_Field property, or should I implement a Multiple_Choice_List_Field subclass of the List_Field class?
What's the engineering principle that I should follow when confronted with dilemmas like this one?
Take a look at the SOLID principles. They'll help you in your designs. In particular, the single responsibility principle will tell you not to mix the two concerns in one class, and the Liskov substitution principle will tell you not to create subclasses that break the contract of superclasses, like what you're also proposing.
So what would be the solution in your case? You could create an abstract base class that would be agnostic to the type of selection and then create 2 subclasses, one for single selection and another for multiple selection.
Depends on presence/lack of object evolution - if you want special case, sub-classing or injecting (DI) "select" behaviour (strategy) is good.
But if you also want to allow Field_List to change its behaviour dynamically, then property or mutating method is the only way to go.
Example: Sign-up screen with different "plans" - basic, where you can only select one thing and premium, where you can select as much as you want. Change of plan will switch between drop-down and multiple checkboxes, while still having the very same object including its contents.
I would vote for property/mutate method.
Personally I would go for the Multiple_Choice_List_Field way. I don't think there is a strict standard or an engineering principle that would make you to do it one way instead of another.
The more important thing here is to choose one way to do it and follow it whenever you encounter such a dilemma. You should be consistent, but which way you go is your own choice.
I would choose the subclass because this way you won't have to bloat your List_Field class with additional checks and requirements. Of course there are other considerations such as if you need to switch the multiple choice and single choice at runtime it would be better to go for the boolean property (although subclass will work too, but doesn't feel natural to me).
The other thing is for List_Field you might need more than a single property to handle multiple choices, depending on your current implementation. For example a new property to return an array of the selected items.
Just do it the way it's most comfortable for you to build and maintain (and eventually extend).
Should I do that through implementing
a multiple_choice_allowed property
into the existing List_Field property
If you can do that, I think it's the best solution because this way you avoid class proliferation.
If in doing that you are complicating too much your List_Field class, maybe create a derived class can have some benefits regarding the maintainability of your code.
Personally, I would say neither: instead use a constructor that takes multiple_choice_allowed, and then have a property exposing ListFields as a collection (with just one element when only one is allowed, all of them when more than one is allowed). Make it readonly (which means that you should copy it whenever you return the list).
As an exercise in good OO methods and design, I want to know what is a good way to model inventory control in a company. The problem description is
a. A company can have different types of items, like documents (both electronic and physical), computers etc which may further have their own sub types.
b. The items can be kept in a store, may be circulated to an employee, may be mailed out etc. An electronic document can be emailed to many people at a time.
c. Items may have certain restrictions like a classified document be circulated to only people/places with access (eg, people with classified clearance or a room cleared to store those documents etc)
what is a good class structure(s) that can be used to model this kind of tracking? (pseudo C# class structure or c++ would be helpful) and what kind of design patterns would be good for such a task
Answering your question would need deep investigation of the problem domain. I don't think there is a universally valid approach.
There are some patterns that are likely to appear, though. One of them (and one of the most difficult to implement, by the way), is the type/instance pattern. Based on my experience, I am assuming that the types of the items that your inventory app must keep track of cannot be fixed, and that users of your system must be able to create and modify types at any time. This means that your system needs to handle two levels of classification rather than the usual one; in other words, your system will have classes (in code), instances of those classes (in run-time) and instances of those instances (in run-time too).
For example, if you create the DocumentType class in code, your users would instantiate it a number of times, creating objects such as Report, Memo or Manual. Then, each individual report that your system manages would be an instance of Report. And each individual memo would be an instance of Memo. And so on.
This is easy to implement if subtypes (Report, Memo, Manual in my example) don't carry their own attributes or their own relationships to other pieces of information. However, if they need specific data structures (attributes and/or associations), then the problem becomes much harder, because you'll need to mimic a complete object-oriented type/instance engine within your system.
It's lots of fun, though!
Here's a preliminary suggestion to get you started:
struct Item
{
// The requirements say everything is an item.
};
struct Document
: public Item
{
// There are documents
};
struct Document_Physical
: public Document
{
// Physical documents
};
struct Document_Electronic
: public Document
{
// Electronic documents
};
struct Computer
: public Item
{
};
The contents of the items and their methods depends on the interpretation of the requirements document. This is one schema, there may be others.
Some useful design patterns: Visitor, Factory, Producer-Consumer to name a few. Also research the topic "refactoring".