Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I've searched google and stackvoverflow to get the answers but it all boils down to: Create methods.
I want my code to be reusable. I don't want to create other methods in the same class. This class already contains a lot of code. How can I reduce the complexity while have a readable class?
I thought about creating another class and having all the new methods there.
The code
public Issue GetIssue(int issueId, IssueOption issueOption)
{
string resource = "issues/{id}.xml?";
if (issueOption.IncludeRelation)
{
resource += "include=relations&";
}
if (issueOption.IncludeChildren)
{
resource += "include=children";
}
//To fetch multiple associations use comma (e.g ?include=relations,journals
RestRequest request = new RestRequest(resource);
request.AddParameter("id", issueId, ParameterType.UrlSegment);
Issue issue = Execute<Issue>(request);
if (issueOption.IncludeVersion)
{
issue.Fixed_version = GetVersion(issue.Project.Id);
}
if (issue.Parent != null && issueOption.IncludeParent)
{
issue.Parent = GetIssue(issue.Parent.Id, issueOption);
}
if (issueOption.IncludeUsers)
{
if (issue.Author.Id == issue.Assigned_to.Id)
{
issue.Author = GetUser(issue.Author.Id);
issue.Assigned_to = issue.Author;
}
else
{
issue.Author = GetUser(issue.Author.Id);
if (issue.Assigned_to != null)
{
issue.Assigned_to = GetUser(issue.Assigned_to.Id);
}
}
}
if (issueOption.IncludeProject)
{
issue.Project = GetProject(issue.Project.Id);
}
return issue;
}
The road to readable code is very rough out of legacy code.
First off, you should have tests that fully cover the code you are refactoring otherwise you end up traversing that rough road in a blinding blizzard -- it's possible but not fun and very dangerous.
Once you've covered your butt there, you can start the refactorings. By and large, most of the early refactorings (assuming a lot of similar methods to what you have above) will be Extract Method. From there, some class behaviors should start becoming apparent and you can extract them out then.
I thought about creating another class and having all the new methods there.
This is analogous to cleaning your room by pushing everything under the bed. The room is clean but you've only hidden the mess. Don't do without any thought otherwise you'll end up with a Utility class that's even worse than what you have now.
From an OOP-perspective, working towards a SOLID solution is generally desired. The key tenet to focus on from a legacy standpoint is Single Responsibility for your classes. If you have that, the O-L-I-D tend to just fall into place (from my experience, though I've had way more brownfield development experience than I'd really like).
This class already contains a lot of code.
...
I thought about creating another class and
having all the new methods there.
That is exactly what you should do.
As you mentioned, breaking the code into smaller methods is the way to go. How about organizing your code using static extension methods, seeing as how Issue is the main subject of the code:
// top-down:
RestRequest request = GetRequestForIssueOption(issueId, issueOption);
Issue issue = Execute<Issue>(request);
// make it fluent...
return issue.SetVersion()
.SetParent()
.SetUsers()
.SetProject();
I think static extension methods make sense to use. Personally, I think making the static extensions fluent helps bring further clarity to code, not sure if that's your cup of tea though.
public static Issue SetVersion(this Issue issue_)
{
// code here
}
public static Issue SetParent(this Issue issue_)
{
// code here
}
public static Issue SetUsers(this Issue issue_)
{
// code here
}
public static Issue SetProject(this Issue issue_)
{
// code here
}
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I just found a class named HmeRevisionTracker that a colleague created. It merely contains a List<> of simple objects. CSimCharge, one of the most important classes in this project, contains an HmeRevisionTracker object as a public property declared like this:
public HmeRevisionTracker RevisionTracker { get; private set; }
There is no reason why the object cannot be created in the CSimCharge constructor, since the HmeRevisionTracker is completely hard-coded, and nothing will ever change it. But it isn't created there. Instead, it's initialized to jull. It's not created until it is used:
void CheckForHeatModelRevision()
{
// Find the next revision that needs to be performed
if (RevisionTracker == null && UseModel)
RevisionTracker = new HmeRevisionTracker(ActualBase.CoilLoad, ActualBase.IsHeating);
As far as I know, there's no problem with this, but I'm curious. Is there some disadvantage to this code that I'm not aware of?
Implementation shouldn't matter for this question, but here is some of it anyway:
public class HmeRevisionRule
{
public double CheckPointThreshold { get; private set; }
public bool RevisionNeeded { get; set; }
public bool IsHeatingRule { get; private set; }
public bool IsCoolingRule { get { return !IsHeatingRule; } }
public HmeRevisionRule(double threshold, bool isHeatingRule)
{
CheckPointThreshold = threshold;
RevisionNeeded = true;
IsHeatingRule = isHeatingRule;
}
}
public class HmeRevisionTracker
{
public LinkedList<HmeRevisionRule> CheckPointRules { get; private set; }
public HmeRevisionTracker(CSimCoilGroup coilLoad, bool isHeating)
{
CheckPointRules = new LinkedList<HmeRevisionRule>();
// Default Heating & Cooling Check Points
CheckPointRules.AddLast(new HmeRevisionRule(1.0 / 2.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(3.0 / 4.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(7.0 / 8.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(15.0 / 16.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(63.0 / 64.0, true));
CheckPointRules.AddLast(new HmeRevisionRule(1.0 / 2.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(3.0 / 4.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(7.0 / 8.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(15.0 / 16.0, false));
CheckPointRules.AddLast(new HmeRevisionRule(63.0 / 64.0, false));
Initialize(coilLoad, isHeating);
}
Initialization sets individual rules depending on the state of the charge. Other methods of the class retrieve the required rule or change settings of a rule.
This is called Lazy Initialization, and is a common practice to improve performance. Labeling it "good" or "bad" is subjective, and dependent on the context in which it's being used.
In your example, it's possible that the HmeRevisionTracker class may be expensive to initialize and therefore it should only be done when it's actually needed. There also may be some other implications when RevisionTracker is null that other code may rely on (i.e. it may indicate that other methods have not been called yet, describing some internal state).
There is an article on the topic of lazy initialization topic here, which states, in part:
Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirements. The most common scenarios are:
When you have an object that is expensive to create, and the program might not use it.
When you have an object that is expensive to create, and you want to defer its creation until after other expensive operations have been completed.
As mentioned in the article, there is a Lazy<T> class that was introduced in .NET 4.0 which could be used to make this more intentional and possibly reduce lines of code.
Finally, in regards to your statement:
There is no reason why the object cannot be created in the CSimCharge constructor
Microsoft's Member Design Guidelines on Constructor Design state:
✓ DO minimal work in the constructor.Constructors should not do much work other than capture the constructor parameters. The cost of any other processing should be delayed until required.
(thanks #madreflection for this part!)
It is my personal opinion that an object should be "ready to use" when the constructor finishes with it: that the List object should therefore be built in the constructor. The handful of nanoseconds required to do this, today, do not matter. But the unexpected runtime errors and resulting (production?) application crashes could cost a lot of money. Construct all the necessary things in the constructor, even if they are not used, and tear them down in the destructor.
If the attribute is private and might not actually be used, expressly initialize it to null. The single most-important thing is that the value is not unpredictable. ("It isn't zero, and yet it isn't any good.")
This question already has answers here:
Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?
(12 answers)
Closed 8 years ago.
Background:
Similar to this question, I am looking to use IDisposable for something other than what it was designed for.
The goal:
The application for this isn't terribly relevant, but just for a good example: I have a Windows Forms application where I implement an Undo design pattern. Typically that is done by intercepting "Value Changed" sorts of events from UI elements. For a DataGridView, CellEndEdit and so forth. However there are cases in which I programmatically change data, and I want to do the things each Undo action tracks, without tracking them.
So far:
I have a way to do all that, but I manage my "Should I Undo" logic on a count:
private int _undoOverrides = 0;
public bool ShouldUndo { get { return _undoOverrides < 1; } }
public void DoNotUndo() { ++_undoOverrides; }
public void ResumeUndo() { --_undoOverrides; }
Now, this works well but you have to remember to call ResumeUndo() at the end of such business logic that begins with DoNotUndo(). And I thought:
Maybe I'm not too much of an idiot to screw that up, but what if I had to expose this interface in code I pass down? I would like if the compiler could take care of this for me, if possible.
The idea:
I am considering using a class implementing IDisposable for this. That way, a user of my code could use a using block and never worry about housekeeping chores. This is what I have so far:
private static int _refCount = 0;
public static int ReferenceCount { get { return _refCount; } }
class HallPass : IDisposable
{
protected bool bActive;
public HallPass()
{
++Program._refCount;
bActive = true;
Console.WriteLine("Acquired hallpass!");
}
public void Dispose()
{
if (bActive)
--Program._refCount;
bActive = false;
Console.WriteLine("Hallpass expired!");
}
}
I included a boolean so that I'm sure I don't double-count back down on Dispose(). So all you have to do to use a HallPass is:
using (new HallPass())
{
// do things...
}
The question is:
Is this a good idea? Why might this be a bad idea? Any gotchas I should know about?
Also, and I feel stupid for this, but I'm pretty sure reference count is not the right term for it. It's like a reference count, but there's no reference to manage or memory to free. Edit: It could be, it's just not right now.
It's like a mutex or a critical section in that you're trying to make an exception (another misnomer, because I don't mean the kind you throw) to a rule during a section of code, but it's not either of those because they're meant to be mutually exclusive within a scope--this is designed to be done in a nested fashion if you wish. That's why it's a count, not a boolean.
The first concern of mine is Program._refCount can be accessed from more than one threads and it is not being synchronized. But you can argue that your application is single threaded.
The next and bigger concern is you are not really using the disposable pattern in the way it is supposed to be used. I personally believe that using a pattern in the way it should be used is important, especially when you are not the only person who is working on the code.
Instead of remembering to call ResumeUndo(), now you need to keep in mind that you must call Dispose(). Question is: will it be natural for your team members to realize that they need to call Dispose () when they want to use the HallPass? (using statement is nice, but it cannot be used in every scenario. If there is a HallPass who lives longer than the scope of a single method, you cannot wrap it in a using statement)
Although it is bad to forget call Dispose() on IDisposible, it usually does not affect the correctness of your program - yes, your program will have performance problems, leaks etc., but functionally it usually is still correct. However for your HallPass, if anyone forgets to call Dispose(), I suppose there will be a functional bug. And the bug is hard to trace.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
What are the possible alternatives of global variables and which one is best one?
As I have heard that use of global variable is not good.
I am working on WCF application and there is possibility of multiple instances of WCF and little chances that I will use concurrency.
This WCF service will be deployed to a server and then a client will send a series of request but request one has some unique request which should be maintained in remaining requests.
As mentioned in the comments, there are no global variables but static properties/fields of a class are something that is close to what meant.
Be very careful of using any static properties/fields (static members that hold state) in WCF code. Each WCF call is a separate thread in the same process and as such they will share the values of static properties/fields. This may lead to unpredictable results and hard to debug problems.
...little chances that I will use concurrency
Your code is almost always concurrent if it's running in WCF. Be extremely careful.
You could use a threading mode that would help you in this case (single concurrency mode) but you still need to design your system carefully.
The "more global" a variable is, the easier it is to access it. However, as soon as every component in your application accesses it, your application depends more and more on that variable. You can't change the variable, because it's being used everywhere.
Automated tests become ugly and require modification with each modification to your application, and you can't reuse any component that uses the global variable.
If you do want to use "global variables" (public static members) try to limit its use as much as possible, for instance when you're creating an instance of a class, supply the value of the variable to its constructor, so that class won't depend on the "global" reference.
In more detail, say you have this class:
public class MyUsefulClass
{
public void DoSomethingUseful()
{
Console.WriteLine("The value is: " + MyGlobalVariables.Variable1);
}
}
new MyUsefulClass().DoSomethingUseful();
Then you can only use MyUsefulclass if you can reference MyGlobalVariables.Variable1. You can't reuse MyUsefulclass in a different project that does not have these globals.
Rewriting it to:
public class MyUsefulClass
{
public MyUsefulClass(string valueToWrite)
{
ValueToWrite = valueToWrite;
}
public string ValueToWrite { get; private set; }
public void DoSomethingUseful()
{
Console.WriteLine("The value is: " + ValueToWrite);
}
}
new MyUsefulClass(MyGlobalVariables.Variable1).DoSomethingUseful();
new MyUsefulClass("I don't need globals!").DoSomethingUseful();
In this case, you can reuse MyUsefulClass without requiring the globals to be present in your new project. You still have a "global"-ish variable, but with this modification less code depends on "it being global".
Is it bad to have a lot of methods referring to each other, like the following example?
public void MainMethod()
{
GetProducts();
}
public void GetProducts()
{
var _products = new Products();
var productlist = _products.GetProductList;
GetExcelFile(productlist);
}
public void GetExcelFile(List<product> productlist)
{
var _getExcelFile = new GetExcelFile();
var excelfile = _getExcelFile.GetExcelFileFromProductList(productlist);
//create excel file and so on...
}
So I am creating a new method for every little action. It would be just as easy to call GetProducts from the MainMethod and do all actions in that method, but I think that isn't the way to create re-usable code.
The following tells me that there should be no more than 7 statements in a method:
Only 7 statements in a method
So the advantages of using methods with a minimal amount of code:
Code is re-usable
Every task can get his own method
The disadvantages of using methods with a minimal amount of code:
It's like spaghetti code
You get: refer to refer and so on
My question:
Should my methods be bigger, or should I keep creating small methods, that do little and refer to a lot of other methods?
The guideline is right. Methods should be small and you are doing the right thing be giving not only each operation its own method, but a well defined name. If those methods have a clear name, one responsibility and a clear intention (and don't forget to separate commands from queries), your code will not be spagetti. On top of that, try to order methods like a news article: most important methods on top of the file, methods with the most detail on the bottom. This way anyone else can start reading at the top and stop reading when they're bored (or have enough information).
I can advice you to get a copy of Robert Martin's Clean Code. There's no one in the industry who describes this more clearly than he does.
The guideline is generally a good one, not so much for reuse, but for readability of your code.
Your example, though, is not a good one. What you're doing is basically creating a long list of methods where each one stops when you feel it's too long and calls another one to perform the rest of the operations.
I would follow more this kind of approach, where reading the main method tells you the "story" that your code needs to tell by steps and the detail of each step is in smaller methods.
public void MainMethod()
{
var productlist=GetProducts();
string excelfile=GetExcelFile(productlist);
// do something in the excel file
}
public List<product> GetProducts()
{
var _products = new Products();
return _products.GetProductList;
}
public string GetExcelFile(List<product> productlist)
{
var _getExcelFile = new GetExcelFile();
var excelfile = _getExcelFile.GetExcelFileFromProductList(productlist);
return excelfile;
}
I don't really agree with '7 statements in a method'. A method can have dozens of statements, as long as the method performs a single function and the specific logic will only be used in one place, I don't really see the point of cutting it into parts just because some guyideline says so, it should be seperated based on what makes sense.
Re-use of code is good if it makes sense, but I don't think you should make everything everywhere re-usable, when you have no plans in the near future to actually re-use it. It increases the development time needlessly, it often makes the software more complex and harder to interpret then it needs to be, and (at least in my company) the majority of the code never gets re-used, and even if it is it still needs modifications in new products. Only the most generic parts of our codebase actually gets used in several applications without modifications for each product.
And I think that's fine.
this is mostly opinion based question, but i'll tell you one thing:
if you're not going to use a method from more then one place, it might be better not to create a method for that.
you can use regions for clarity and you might not want a method that is larger then a full page, but not every 2-3 commands should get a method.
Very often it happens that I have private methods which become very big and contain repeating tasks but these tasks are so specific that it doesn't make sense to make them available to any other code part.
So it would be really great to be able to create 'inner methods' in this case.
Is there any technical (or even philosophical?) limitation that prevents C# from giving us this? Or did I miss something?
Update from 2016: This is coming and it's called a 'local function'. See marked answer.
Well, we can have "anonymous methods" defined inside a function (I don't suggest using them to organize a large method):
void test() {
Action t = () => Console.WriteLine("hello world"); // C# 3.0+
// Action t = delegate { Console.WriteLine("hello world"); }; // C# 2.0+
t();
}
If something is long and complicated than usually its good practise to refactor it to a separate class (either normal or static - depending on context) - there you can have private methods which will be specific for this functionality only.
I know a lot of people dont like regions but this is a case where they could prove useful by grouping your specific methods into a region.
Could you give a more concrete example? After reading your post I have the following impression, which is of course only a guess, due to limited informations:
Private methods are not available outside your class, so they are hidden from any other code anyway.
If you want to hide private methods from other code in the same class, your class might be to big and might violate the single responsibility rule.
Have a look at anonymous delegates an lambda expressions. It's not exactly what you asked for, but they might solve most of your problems.
Achim
If your method becomes too big, consider putting it in a separate class, or to create private helper methods. Generally I create a new method whenever I would normally have written a comment.
The better solution is to refactor this method to separate class. Create instance of this class as private field in your initial class. Make the big method public and refactor big method into several private methods, so it will be much clear what it does.
Seems like we're going to get exactly what I wanted with Local Functions in C# 7 / Visual Studio 15:
https://github.com/dotnet/roslyn/issues/2930
private int SomeMethodExposedToObjectMembers(int input)
{
int InnerMethod(bool b)
{
// TODO: Change return based on parameter b
return 0;
}
var calculation = 0;
// TODO: Some calculations based on input, store result in calculation
if (calculation > 0) return InnerMethod(true);
return InnerMethod(false);
}
Too bad I had to wait more than 7 years for this :-)
See also other answers for earlier versions of C#.