TL;DR: the title says it all, and a simple answer would be great if the question can be answered simply
Longer Version:
I am using a pre-existing library to build invoices, and the library holds the instantiation of the invoice object and static functions which add items to the invoice. The items on the invoice include breakdowns of sub-items, and it has about a dozen columns. No item uses all the columns, and the column usage and values depends on the item listed and it's depth within a breakdown.
So, the invoice can be built with pseudocode like this:
Invoice customerInvoice = new Invoice();
MainItem widget = new MainItem(); //the entirety of the sale, this is shown as the top-level item
SubItem component = new SubItem(widget, values[]); //a component of widget. The parameters identify the main piece that this attaches to, and a set of values for the other columns.
SubItem piece = new SubItem(widget, values[]); //another component; the values[] will be slightly different but correspond to the same columns.
SubItem bolt = new DeepSubItem(piece, lowestValues[]); //an irreducibly small item which is a part of the "piece" item, with it's own set of values which fill a different arrangement of columns
Components and sub-components are shown on indented lines below their parent object.
I am trying to create a new class structure that can help simplify this. The largest problem is that values[] here represents about 20 individual parameters. Additionally, a maze of conditional statements is necessary due to quirks of individual products, variations based on sale location or time, and many other factors. The only constant is that each function corresponds to a single line on the invoice. The original library was great at nesting objects properly, but it can't handle the logic. The SubItem instantiations of piece, bolt, and component only exist so that they can be broken down. When SubItem() or DeepSubItem() are called, the objects are attached to the object that they include in their parameter.
First question: What is a good plan/design pattern/strategy to build a new structure that can use the existing library, but provide flexible logic?
Second question: If I could create an 'instance' of the static functions, I could use that instance without the great verbosity of the parameters. Is there any way to do this, or something that will have a similar effect?
I've been thinking of creating a new class that will conduct the logic and hold the needed sets of values. That class can then create 'objects' (ideally, instances of the static functions) which I can use in the code we already have, replacing the function calls. That would allow me to separate the verbosity (which rarely needs to change) from the logic (which often needs to change). I can't simply use the object "bolt" because the moment I instantiate it, it is added to the invoice - hence why I want to treat the function like an object.
Your wise input (and/or reality check) is greatly appreciated. Thanks,
One of the ways you could do this would be to use the Func object. This allows you to pass functions by reference. Here's an example:
private static object TestStaticFunction()
{
return "test";
}
public static Func<object> GetStaticFunction
{
get { return TestStaticFunction; }
}
Then, any function that calls GetStaticFunction will get TestStaticFunction returned to it. Likewise, Console.Write(GetStaticFunction()) will display "test".
Note that if you want to pass a method that does not return a value, use Action instead.
Here's the MSDN documentation on Func: http://msdn.microsoft.com/en-us/library/bb549151%28v=vs.110%29.aspx
And another StackOverflow thread with more explanation: What is Func, how and when is it used
As far as your program design, I'm not really sure that I understand the library well enough to point you towards a better pattern. Are you forced to work within this library?
Are you talking about delegates?
class Program
{
static void Main(string[] args)
{
var returnedFunction = TestClass.FunctionToReturnAStaticMethod();
returnedFunction();
}
}
public class TestClass
{
public delegate void TypeOfFunctionToReturn();
public static TypeOfFunctionToReturn FunctionToReturnAStaticMethod()
{
return () => StaticMethod();
}
public static void StaticMethod()
{
Console.WriteLine("\"StaticMethod\" called");
}
}
Related
I have a single object. One of the fields within the object is a list of stats. I'm trying to order by one of the fields within the stats. So I have a server, server has a name, worker count, and worker stats... Worker stats has a list of multiple stats like, DA, Server, Client... I want to order those Worker stats by client but still leave the entire object as one Server. I'm trying to do it like this.
SvcProxy.Server refreshedServer = SvcProxy.GetServer(serverName);
var tempServer = refreshedServer.WorkerStats.OrderBy(ws => ws.Client);
But when I do this, tempServer is turned into an Ordered IEnumerable. When I want to leave it as an SvcProxy.Server except with the stats within, ordered by the clients. Is this possible?
There's sensitive data where idk if I could get legally in trouble so I'll post what I can about the class. WorkerStats is an IEnumerable.
public IEnumerable<WorkerStatsDisplay> WorkerStats
{
get {
if (String.IsNullOrEmpty(ServerName) || !Active)
{
return Enumerable.Empty<WorkerStatsDisplay>();
}
}
}
What you can do is use extension methods:
public static class ServerExtensions
{
public static IEnumerable<WorkerStatsDisplay> GetSortedWorkerStats(this Server server)
{
return server.WorkerStats.OrderBy(ws => ws.Client);
}
}
Then use it like this:
SvcProxy.Server refreshedServer = SvcProxy.GetServer(serverName);
var ordered = refreshedServer.GetSortedWorkerStats();
Make sure to wrap this guy in the same namespace as the original class. You don't have to, but it's SOP and it makes it easier as your extension method is imported by virtue of using the class (since it will live in the same namespace).
While it amounts to the same thing you are doing now, it makes it reusable and available to everyone without having to modify the original class.
I whipped this out real quick. Please check the code for consistency.
Good luck!
I am having trouble figuring out the best way to refactor a very large C# class and specifically how to pass shared properties/values from the large class into the extracted classes and have those modified values available in the main class.
At the start, this class was 1000 lines long and is very procedural – it involves calling methods and performing work in a specific sequence. Along the way things are persisted into the database. During the process there are multiple Lists of items that are worked on and shared in the methods. At the end of this process, there are a bunch of statistics that are presented to the user. These statistics are calculated in various methods as the processing is taking place. To give a rough outline – the process involves a bunch of random selection and at the end of the process the user sees how many random items, how many invalid records were picked, how many items came from this sub-list etc.
I have been reading Uncle Bob’s “Clean Code” and am trying to make sure as I refactor that each class does only 1 thing.
So I have been able to extract methods and classes in order to keep the file smaller (have it down to 450 lines now) but the problem I am having now is that these broken out classes require values from the main parent class to be passed to them and updated – these values will be used for other methods/class methods as well.
I am torn as to which is the cleanest approach:
1) Should I create a bunch of private member variables to store the statistical values and Lists in the main class and then after calling into the main class' dependnat class methods, receive back a complex result class and then extract these values out and populate / update the private member variables? ( lots of boiler plate code this way)
OR
2) Is it better to create a DTO or a some sort of container class that holds the Lists and statistical values and just pass it to the various class methods and child class methods by reference in order to build up the list of values? In other words I am just passing this container class and since it's an object the other classes and methods will be able to directly manipulate the values in there. Then at the end of the process, that values DTO/container/whatever you want to call it will have all of the final results in it and I can just extract them from the container class (and in that case there really is no need to extract them and populate the main class’ private member variables. )
The latter is the way I have it now but I am feeling that this is a code smell – it all works but it just seems “fragile”. I know large classes are not great but at least with everything in 1 large file it does seem clearer as to which properties I am updating etc.
-- UPDATE --
Some more info:
Unfortunately I can't post any of the actual code as it is propriatary - will try to come up with dummy example and paste it in if I get some time. One of the comments below mentioned refactoring the code into steps and that is exactly what I've done. The purpose of the class is ultimately 1 thing - to create a random list of things - so in the only public method that gets called for this class - I have refactored this down to 1 level of abtraction for each "step". Each step, whether that is a method in the same class, or if it makes sense to break it out into a helper class to do the substeps - it still requires access to the lists that get built up during the process and the simple counter variables that keep track of the statistics.
-- UPDATE --
Here is an attempt at showing something similar in code:
public class RandomList(){
public int Id{get; set;}
public int Name{get; set;}
public int NumOfInvalidItems {get; set;}
public int NumOfFirstChunkItems{get; set;}
public int NumOfSecondChunkItems{get; set;}
public ICollection<RandomListItem> Items{get; set;}
}
public class CreateRandomListService(){
private readonly IUnitOfWork _unitOfWork;
private readonly ICreateRandomListValidator _createRandomListValidator;
private readonly IRandomSubProcessService _randomSubProcessService;
private readonly IAnotherSubProcessService _anotherSubProcessService;
private RandomList _randomList;
public CreateRandomListService(IUnitOfWork unitOfWork,
ICreateRandomListValidator createRandomListValidator,
IRandomFirstChunkFactory randomFirstChunkFactory,
IRandomSecondChunkFactory randomSecondChunkFactory){
_unitOfWork = unitOfWork;
_createRandomListValidator = createRandomListValidator;
_randomFirstChunkService = randomFirstChunkFactory.Create(_unitOfWork);
_randomSecondChunkService = randomSecondChunkFactory.Create(_unitOfWork);
}
public CreateResult CreateRandomList(CreateRandomListValues createValues){
// validate passed in model before proceeding
if(_createRandomListValidator.Validate(createValues))
return new CreateResult({HasErrors:true});
InitializeValues(createValues); // fetch settings from db etc and build up
ProcessFirstChunk();
ProcessSecondChunk();
SaveWithStatistics();
createResult.Id = _randomList.Id;
return createResult;
}
private InitializeValues(CreateRandomListValues createValues){
_createValues = createValues;
_createValues.ImportantSetting = _unitOfWork.SettingsRepository.GetImportantSetting();
// etc.
_randomList = new RandomList(){
// set initial properties etc. some come from the passed in createValues, some from db
}
}
private void ProcessFirstChunk(){
_randomFirstChunkService.GetRandomFirstChunk(_createValues);
}
private void ProcessSecondChunk(){
_randomSecondChunkService.GetRandomSecondChunk(_createValues);
}
private void SaveWithStatistics(){
_randomList.Items _createValues.ListOfItems;
_randomList.NumOfInvalidItems = _createValues.NumOfInvalidItems;
_randomList.NumOfItemsChosen = _createValues.NumOfItemsChosen;
_randomList.NumOfFirstChunkItems = _createValues.NumOfFirstChunkItems;
_randomList.NumOfSecondChunkItems = _createValues.NumOfSecondChunkItems;
_unitOfWork.RandomThingRepository.Add(_randomList);
_unitOfWork.Save();
}
}
public class RandomFirstChunkService(){
private IUnitOfWork _unitOfWork;
public RandomFirstChunkService(IUnitOfWork unitOfWork){
_unitOfWork = unitOfWork;
}
public void GetRandomFirstChunk(CreateRandomListValues createValues){
// do processing here - build up list collection and keep track of counts
CallMethodThatUpdatesList(creatValues);
// how to return this to calling class? currently just updating values in createValues by reference
// can also return a complex class here and extract the values back to the main class' member
// variables
}
private void CallMethodThatUpdatesList(createRandomListValues createValues){
// do work
}
}
The brutal answer is that it depends... of course. It is hard to work out a answer without reading the code, but I would say that once you have created new classes (with one purpose) those classes and interfaces should define what data objects you need to pass around to solve your problems. And in that case it is strange for a method to return the same type as pass into it, I also think that manipulation one object through a seriers of methods is fragile. Imagine if each of you classes was a REST service; then how would those interfaces look like.
I wouldn't "pass stuff around". Nor would I break it up into separate classes just because its 1000 lines. You'll end up making it much messier and much more of a maintenance headache.
You didn't post your code (duh), so its hard to critique it. If you really go over it, I suspect you might have duplicate code in there that can be refactored into methods, etc.
If you've already gotten rid of the duplicate code, I'd next pull out all the database stuff into a DAL layer.
If you really want to make it smaller (based on what little info you provided), I'd next refactor it into "steps" and make a workflow type parent container class.
Again, hard to say without knowing the code.
I don't know how exactly you have managed to refactor the class this far, but from your explanation it sounds to me like the "statistic" is the concept that should become an object, something like:
interface IStatistic<TOutput>
{
IEnumerable<TOutput> Calculate(IEnumerable<input-type>);
}
When you wish to display some statistic, you just use the appropriate statistic:
return new MySpecial().Calculate(myData);
In case that statistics objects are not that easy to construct, e.i. they ask for some parameters and so, then you may supply a Func delegate which creates them:
void DoSomething(Func<IStatistic<string>> factory)
{
string[] inputData = ...
foreach (string line in factory().Calculate(inputData))
{
// do something...
}
}
As you are mentioning multiple lists, I suppose that input-type would actually be a couple of input types. If that is so, then it might really make sense to supply a kind of a DTO to just hold the lists:
class RawData
{
public IEnumerable<type1> Data1 { get; }
public IEnumerabel<type2> Data2 { get; }
...
}
Observe, however, that this is not a DTO "by the book". First, it is immutable - only getters are there. Second, it only exposes sequences (IEnumerable), rather than raw lists. Both measures are taken to disallow statistic objects to manipulate data.
I have a design problem,
Basically, I have a class called Currency
public class Currency
{
public int ID;
public string Name;
public int RoundingValue;
public Currency() { }
public void GetData() { // Some SQL query code // }
}
Sometimes it is necessary to fetch all the currencies that there are in the system to make a decision concering exchange rates, compatability of payment, etc.
I see two ways of doing that (fetching data):
1) To make a static method inside Currency class to do it. That involves creating SQL connection instance inside it(not sure if that is the right thing to do), creating List<Currency> instance to store the collection, and then pass it outside the class.
2) Create collection of the class via extending Collections.BaseCollection class, make instance of it, doing the same SQL query, and then return the result. But that class will provide no additional functionality, and probably won't ever (the same for Currency itself.
In other cases, I used extended collections, because they needed to store additional info, based on the contents of the collection.
But in this case, no additional info is created or functionality provided.
So, what design would be more practical?
If there is an alternative to the these solutions, I would be more than happy to hear it.
I would suggest simply populating a List<Currency> then returning it as IList<Currency>. That way if you change it in future to use a custom collection, you won't break any consumers.
I am developing a space shooter game with customizable ships. You can increase the strength of any number of properties of the ship via a pair of radar charts*. Internally, i represent each ship as a subclassed SpaceObject class, which holds a ShipInfo that describes various properties of that ship.
I want to develop a relatively simple API that lets me feed in a block of relative strengths (from minimum to maximum of what the radar chart allows) for all of the ship properties (some of which are simplifications of the underlying actual set of properties) and get back a ShipInfo class i can give to a PlayerShip class (that is the object that is instantiated to be a player ship).
I can develop the code to do the transformations between simplified and actual properties myself, but i would like some recommendations as to what sort of architecture to provide to minimize the pain of interacting with this translator code (i.e. no methods with 5+ arguments or somesuch other nonsense). Does anyone have any ideas?
*=not actually implemented yet, but that's the plan.
What about the Builder pattern? You could have a static FillDefaults method on your ShipInfo class and then assign each property of the ShipInfo via an instance method that returns the instance that you're working with, like this:
ShipInfo.FillDefaults().CalculateSomething(50).AssignName("Testing...").RelativeFiringPower(10).ApplyTo(myShip);
Within ShipInfo, this would look something like:
public static ShipInfo FillDefaults()
{
ShipInfo newInstance = ...;
// Do some default setup here
return newInstance;
}
public ShipInfo CalculateSomething(int basis)
{
// Do some calculation
// Assign some values internally
return this;
}
// Keep following this pattern of methods
public void ApplyTo(SpaceObject obj)
{
// Some checks here if you want
obj.ShipInfo = this;
}
I would say the Facade pattern is perfect for that kind of problem. If you have 5+ arguments on your methods, consider encapsulating at least part of them in a new type.
Seems like you want to set some properties but not the others, but not in a particular order of importance so that you could define overloads with incrementally more arguments.
You could implement a constructor with minimum required values that sets default values for the other, and then use object initializer to set the remaining relevant values:
// Didn't set properties 2 3 and 6, only set the ones needed in this case.
SpaceObject ship = new SpaceObject(someRequiredValue) {
Property1 = 50,
Property4 = Game.Settings.Ships.Armor.Strong,
Property5 = new PropertySet1{
Prop51 = "Enterprise",
Prop53 = true,
Prop57 = false
};
To me this looks like a case for the decorator pattern.
I need to display some stats, numbers, and graphs about various game objects on the screen.
(examples: camera position, field of view, frames per second, fill rate, number of objects culled, etc... )
Currently any object which wants to be graphed or displayed implements an interface along these lines:
public interface IGraphable
{
float GraphableValue { get; set; }
}
Then that object can be sent to a graph component to be displayed. This has some obvious drawbacks like not being able to graph 2 different pieces of data which belong to the same class.
What I want is a way to pass a pointer to where the data is located or a pointer to a function which knows how to return the data instead of passing the object to the display component.
I believe that this is what delegates are for but I don't understand how to use them in this context (Actually I don't understand them very well at all). Also, is there another (smarter/better) way to do this?
Thanks!
Why not invert the control like this:
public interface IGraphable
{
void BuildGraphable( IGraph g );
}
interface IGraph {
void AddValue( double value );
}
this is a preferred option in OO anyway as it hides details of the IGraphable implementation. Additionally you can now extend IGraph for added functionality without breaking compatibility.
Depending on how you're doing things, you could possibly use Reflection (attributes on accessors), although that can be relatively confusing at first too. But it's a very useful tool in your arsenal, so it's well worth spending the time on. Here is a great tutorial on how to use them:
http://www.brainbell.com/tutors/C_Sharp/Attributes.htm
But then, learning delegates is also very useful, and that does sound like a good solution. I haven't looked deeply into it, but this tutorial on the same site might be useful:
http://www.brainbell.com/tutors/C_Sharp/Delegates_and_Event_Handlers.htm
I have decided to do the following:
public class GraphComponent
{
private Func<flaot> _function;
public GraphComponent(Func<flaot> function, ...)
{ ... }
}
This allows me to specify how the data is retrieved by writing something like this:
FPSComponent fpsc = new FPSComponent();
GraphComponent fpsg = new GraphComponent(delegate() { return fpsc.ApproximateFPS; }, ...);
What I want is a way to pass a pointer to where the data is located or a pointer to a function which knows how to return the data instead of passing the object to the display component.
If you don't want to add your objects to your graph component BECAUSE
This has some obvious drawbacks like not being able to graph 2 different pieces of data which belong to the same class.
Maybe a list will solve your problem ?
public interface IGraphable
{
List<float> GraphableValues { get; }
}