So I've been dealing with several APIs recently provided by different software vendors for their products. Sometimes things are lacking, sometimes I just want to make the code more readable, and I'm trying to avoid a ton of static methods where they don't belong to "get what I need" from the APIs. Thus, I've found myself writing quite a few extension methods.
However, because there are many methods, and in the interest of keeping "my" methods separate from those of the API objects in terms of code readability, I came up with this little tidbit:
public class MyThirdPartyApiExtensionClass {
public static MyThirdPartyApiExtensionClass MTPAEC(this ThirdPartyApiClass value) {
return new MyThirdPartyApiExtensionClass(value);
}
private ThirdPartyApiClass value;
public MyThirdPartyApiExtensionClass(ThirdPartyApiClass extendee) {
value = extendee;
}
public string SomeMethod() {
string foo = value.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
public int SomeOtherMethod() {
int bar = value.WowThisAPISucks(null);
//more stuff
return bar;
}
}
Then I can do things like:
string awesome = instanceOfApiObject.MTPAEC.SomeMethod();
and I have a clean separation of my stuff from theirs.
Now my question is.. does this seem like a good practice, improving code readability... or is this a bad idea? Are there any harmful consequences to doing this?
Disclaimer:
The code above is just to demonstrate the concept. Obviously there is better sanity checking and usefulness in the real thing.
I suppose the same level of separation could simply be done like this:
public static class MyThirdPartyApiExtensionClass {
public ThirdPartyApiClass MTPAEC(this ThirdPartyApiClass value) {
return value;
}
public string SomeMethod(this ThirdPartyApiClass value) {
string foo = value.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
public int SomeOtherMethod(this ThirdPartyApiClass value) {
int bar = value.WowThisAPISucks(null);
//more stuff
return bar;
}
}
To answer your direct question, I think that going through the extra trouble to separate out your functionality from the basic functionality is a bad code smell. Don't worry about having your code separate from their code from a usage perspective. First it makes it that much harder to find what you're looking for since now there's two places to look for the same functionality and secondly the syntax makes it look like your extensions are operating on the MTPAEC property and not the core object (which they are).
My suggestion is to use actual Extension methods which allow you to have that but without having the additional constructor.
public static class ApiExtension
{
public static string SomeMethod(this ThirdPartyApiClass value)
{
string foo = value.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
}
used by
var mine = new ThirdPartyApiClass();
mine.SomeMethod();
C# will do the rest.
Looking at your above suggestion you'll have to split the two classes out I think. One for providing extension groups using the extensions mechanism and another for providing each group of logic.
If you need to separate out yours from a glance then use a naming convention to make your look unique. Though upon hovering and through intellisense it will tell you that it is an extension method.
If you just want the separation of content like you have, then you'll need two classes.
public static class ApiExtensionder
{
public static MTPAEC(this ThirdPartyApiClass value)
{
return new MtpaecExtensionWrapper(value);
}
}
public class MtpaecExtensionWrapper
{
private ThirdPartyApiClass wrapped;
public MtpaecExtensionWrapper(ThirdPartyApiClass wrapped)
{
this.wrapped = wrapped;
}
public string SomeMethod()
{
string foo = this.wrapped.SomeCrappyMethodTheProviderGaveUs();
//do some stuff that the third party api can't do that we need
return foo;
}
}
When dealing with an API that you cannot modify, extension methods are a reasonable way to extend the API's expressiveness while staying relatively decoupled, IMHO.
The biggest issue with extension methods has to do with the fact that they are implicitly inferred to be available based on namespace inclusion (the using statements at the top of the file). As a result, if you simply forget to include a namespace, you can end up scratching your head wondering why there's not available.
I would also add that extension methods are not an obvious construct, and as a result developers don't commonly expect or anticipate them. However, with the increased use of LINQ, I would imagine more and more developers would be getting comfortable with their use.
My opinion is that you're adding an extra level of indirection needlessly. You want the extension methods to be available on the original objects... so why not put them there? Intellisense will let you know that the objects are extensions, for the rare case that you actually care.
Related
This is stripped down from a more complex situation.
The goal is to construct several instances of class SubAction, each of which uses an action to alter how it uses its internal data.
Consider:
public class SubAction
{
private Action<SubAction> _DoIt;
public SubAction(Action<SubAction> doIt)
{
_DoIt = doIt;
}
public void DoIt()
{
_DoIt(this);
}
static public Action<SubAction> GetAction1 => (it) => it.DoSomething(it._Data.Value1);
static public Action<SubAction> GetAction2 => (it) => it.DoSomething(it._Data.Value2);
private void DoSomething(string value)
{
// ...
}
// This gets set by code not shown.
protected Data _Data;
}
public class Data
{
public string Value1;
public string Value2;
}
public class SubActionTests
{
static SubActionTests()
{
var actions = new List<SubAction>
{
new SubAction(SubAction.GetAction1),
new SubAction(SubAction.GetAction2),
};
// ... code not shown that calls a method to update each instance's _Data...
foreach (var subAction in actions)
{
subAction.DoIt();
}
}
}
This works, but it seems cumbersome. Specifically:
public Action<SubAction> _DoIt { get; set; }
...
static public Action<SubAction> GetAction1 => (it) => it.DoSomething(it._Data.Value1);
...
new SubAction(SubAction.GetAction1)
If I set DoIt AFTER constructing the object, could simply be:
public Action DoIt { get; set; }
...
public Action GetAction1 => () => DoSomething(_Data.Value1);
...
var it = new SubAction();
it.DoIt = it.GetAction1;
Which has simpler action declarations:
The actions don't need <SubAction>.
`GetAction1,2,3.. declarations are much simpler.
But more verbose instance initialization, because access to it is needed to set DoIt.
Unfortunately it isn't possible to refer to "it" during object initializer, so there doesn't seem to be any way to have BOTH the simpler initialization syntax AND the simpler action-declaration syntax.
Am I overlooking some solution?
ALTERNATIVE: factory method
NOTE: This could be approached quite differently, by using an enum to select between the different actions. But that is a different sort of complication; I'm looking for a way to describe these Actions themselves more succinctly.
Specifically, I'm aware there could be a factory method that takes an enum, to hide the complexity:
public enum WhichAction
{
Action1,
Action2
}
...
public static CreateSubAction(WhichAction which)
{
var it = new SubAction();
switch (which)
{
case WhichAction.Action1:
it.DoIt = it.GetAction1;
break;
case WhichAction.Action2:
it.DoIt = it.GetAction2;
break;
}
return it;
}
The downside of this is that each added action requires editing in multiple places.
ALTERNATIVE: sub-classes
Another alternative is to create multiple sub-classes.
That is what I was doing originally, but that was even more verbose - multiple lines per each new action.
And felt like "overkill".
After all, the approach I've got isn't terrible - its a single line for each new GetAction. It just felt like each of those lines "ought" to be much simpler.
Sadly, from what I understand, I don't think you can make the complexity disappear. You probably need to choose an approach from the ones you suggested (or even other solutions like using a strategy pattern).
Advice
When confronted with a design choice like this. I suggest you optimize for the consumer's side of things. In other words, design your classes to make them simple to use.
In your scenario, that would mean opting for your initial solution or the more complex solutions (factory method, sub-classes, strategy pattern, etc.).
The problem with the second solution is that your object can be in a limbo state when initializing it.
var it = new SubAction();
// Before you set DoIt, the object is not fully initialized.
it.DoIt = it.GetAction1;
Consumers can also forget to set DoIt. When possible, you should probably avoid designs that allow such mistakes.
While I'm still curious whether there are syntax alternatives that would streamline what I showed, so I'll accept an answer that shows a simpler syntax, turns out in my situation, I can easily avoid the need for those actions.
Discussing with a colleague, they pointed out that my current actions all have a similar pattern: get a string, pass it to SubAction.DoSomething.
Therefore I can simplify those actions down to a property that gets the appropriate string:
public abstract string CurrentValue { get; }
...
public virtual void DoIt()
{
DoSomething(CurrentValue);
}
Given the above, subclasses become so simple they no longer feel like "overkill":
public class SubAction1 : SubAction
{
protected override string CurrentValue => _Data.Value1;
}
...
// usage
new SubAction1()
That is straightforward; highly readable. And trivial to extend when additional conditions are needed.
There will be more complicated situations that do need to override DoSomething. In those, the "real work" dwarfs what I've shown; so its appropriate to subclass those anyway.
So say we have loaded a function F that take in/out a set of args and returns a result. How to check at runtime if this F does not act on anything other than args members and functions? Meaning no Console.Writeline, Singletons (or other stuff not presented in args). Is it possible with CodeContracts library or some other solution?
Say we know that [Pure] attribute was presented in the function definition. This sucks for many cases when we have a lambda, yet at least it would be something
Why I do not see how [Pure] can help - this code compiles:
class Test {
public struct Message {
public string Data;
}
public struct Package {
public int Size;
}
[Pure]
public static List<Package> Decomposse(Message m) {
Console.WriteLine("rrrr"); // This sould not happen
var mtu = 1400;
Package p = new Package{Size = mtu};
return Enumerable.Repeat(p, m.Data.Length / mtu).ToList();
}
}
And I want to eliminate (or at least detect that function calls stuff like Console.WriteLine("rrrr"))
It doesn't matter if the function has inputs or a result. Too many things can happen in a code body, e.g. instantiated object constructors. The problem is the modern language.
What about safe API calls which just retrieve data like DateTime.Now()? Are you going to build a list of API calls which mutate state and keep it updated for the rest of us over time, for all applications in your organization or on earth? Are you going to document what processes the compiler inlines? Then by reducing this approach to absurdity, can we accept it is not feasible?
My architecture models machines which should only change "Product" data points, but even I admit this is an unenforceable rule. I have other rules as well to try to enforce determinism. However, these modules must make API calls at some point to do the meaningful work already organized in APIs today. Otherwise we would rewrite them all.
class Machine1Product
{
public Cvar<int> Y { get; set; }
}
class Machine1 : Producer<Machine1Product>, IMachine
{
public Cvar<int> X { get; set; }
public void M()
{
// work which changes only product data points (Y)
}
}
Until a minimalist language is developed for functions, there is no observing or preventing side effects.
I am doing a refactor over certain code.
We have a list of investors with amounts assigned to each. The total of amounts should be equal to another total, but sometimes there are a couple of cents of difference, so we use different algorithms to assign these differences to each investor.
The current code is something like this:
public void Round(IList<Investors> investors, Enum algorithm, [here goes a list of many parameters]) {
// some checks and logic here - OMMITED FOR BREVITY
// pick method given algorithm Enum
if (algoritm == Enum.Algorithm1) {
SomeStaticClass.Algorithm1(investors, remainders, someParameter1, someParameter2, someParameter3, someParameter4)
} else if (algoritm == Enum.Algorithm2) {
SomeStaticClass.Algorithm2(investors, remainders, someParameter3)
}
}
so far we only have two algorithms. I have to implement the third one. I was given the possibility to refactor both existing implementations as well as do some generic code to make this function for future algorithms, maybe custom to each client.
My first thought was "ok, this is a strategy pattern". But the problem I see is that both algorithms receive a different parameter list (except for the first two). And future algorithms can receive a different list of parameters as well. The only thing in "common" is the investor list and the remainders.
How can I design this so I have a cleaner interface?
I thought of
Establishing an interface with ALL possible parameters, and share it
among all implementations.
Using an object with all possible parameters as properties, and use that generic object as part of the interface. I
would have 3 parameters: The list of investors, the remainders object, and a "parameters" object. But in this case, I have a similar problem. To instantiate each object and fill the required properties depends on the algorithm (unless I set all of them). I
would have to use a factory (or something) to instantiate it, using all parameters in the interface, am I right? I would be moving the problem of too many parameters to that "factory" or whatever.
Using a dynamic object instead of a statically typed object. Still
presents the same problems as before, the instantiation
I also thought of using the Visitor Pattern, but as I understand, that would be the case if I had different algorithms for different entities to use, like, another class of investors. So I don't think it is the right approach.
So far the one that convinces me the most is the second, although I am still a bit reticent about it.
Any ideas?
Thanks
Strategy has different implementations. Its straightforward when all alternate Concrete Strategies require same type signature. But when concrete implementations start asking for different data from Context, we have to gracefully take a step back by relaxing encapsulation ("breaking encapsulation" is known drawback of strategy), either we can pass Context to strategies in method signature or constructor depending upon how much is needed.
By using interfaces and breaking big object trees in to smaller containments we can restrict the access to most of the Context state.
following code demonstrates passing through method parameter.
public class Context {
private String name;
private int id;
private double salary;
Strategy strategy;
void contextInterface(){
strategy.algorithmInterface(this);
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public double getSalary() {
return salary;
}
}
public interface Strategy {
// WE CAN NOT DECIDE COMMON SIGNATURE HERE
// AS ALL IMPLEMENTATIONS REQUIRE DIFF PARAMS
void algorithmInterface(Context context);
}
public class StrategyA implements Strategy{
#Override
public void algorithmInterface(Context context) {
// OBSERVE HERE BREAKING OF ENCAPSULATION
// BY OPERATING ON SOMEBODY ELSE'S DATA
context.getName();
context.getId();
}
}
public class StrategyB implements Strategy{
#Override
public void algorithmInterface(Context context) {
// OBSERVE HERE BREAKING OF ENCAPSULATION
// BY OPERATING ON SOMEBODY ELSE'S DATA
context.getSalary();
context.getId();
}
}
Okay, I might be going in the wrong direction... but it seems kinda weird that you're passing in arguments to all the algorithms, and the identifier to which algorithm to actually use. Shouldn't the Round() function ideally just get what it needs to operate?
I'm imagining the function that invokes Round() to look something like:
if (something)
algToUse = Enum.Algorithm1;
else
if (otherthing)
algToUse = Enum.Algorithm2;
else
algToUse = Enum.Algorithm3;
Round(investors, remainder, algToUse, dayOfMonth, lunarCycle, numberOfGoblinsFound, etc);
... what if, instead, you did something like this:
public abstract class RoundingAlgorithm
{
public abstract void PerformRounding(IList<Investors> investors, int remainders);
}
public class RoundingRandomly : RoundingAlgorithm
{
private int someNum;
private DateTime anotherParam;
public RoundingRandomly(int someNum, DateTime anotherParam)
{
this.someNum = someNum;
this.anotherParam = anotherParam;
}
public override void PerformRounding(IList<Investors> investors, int remainder)
{
// ... code ...
}
}
// ... and other subclasses of RoundingAlgorithm
// ... later on:
public void Round(IList<Investors> investors, RoundingAlgorithm roundingMethodToUse)
{
// ...your other code (checks, etc)...
roundingMethodToUse.Round(investors, remainders);
}
... and then your earlier function simply looks like:
RoundingAlgorithm roundingMethod;
if (something)
roundingMethod = new RoundingByStreetNum(1, "asdf", DateTime.Now);
else
if (otherthing)
roundingMethod = new RoundingWithPrejudice(null);
else
roundingMethod = new RoundingDefault(1000);
Round(investors, roundingMethod);
... basically, instead of populating that Enum value, just create a RoundingAlgorithm object and pass that in to Round() instead.
We have a Web API library, that calls into a Business/Service library(where our business logic is located), which in turn calls a Data access library (Repository).
We use this type of data transfer object all over the place. It has a "Payers" property that we may have to filter (meaning, manipulate its value). I have gone about implementing that check as such, but it feels dirty to me, as I'm calling the same function all over the place. I have thought about either:
Using an attribute filter to handle this or
Making the RequestData a property on the class, and do the filtering in the constructor.
Any additional thoughts or design patterns where this could be designed more efficiently:
public class Example
{
private MyRepository _repo = new MyRepository();
private void FilterRequestData(RequestData data)
{
//will call into another class that may or may not alter RequestData.Payers
}
public List<ReturnData> GetMyDataExample1(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample1(data);
}
public List<ReturnData> GetMyDataExample2(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample2(data);
}
public List<ReturnData> GetMyDataExample3(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample3(data);
}
}
public class RequestData
{
List<string> Payers {get;set;}
}
One way of dealing with repeated code like that is to use a strategy pattern with a Func (and potentially some generics depending on your specific case). You could refactor that into separate classes and everything but the basic idea looks like that:
public class MyRepository
{
internal List<ReturnData> GetMyDataExample1(RequestData arg) { return new List<ReturnData>(); }
internal List<ReturnData> GetMyDataExample2(RequestData arg) { return new List<ReturnData>(); }
internal List<ReturnData> GetMyDataExample3(RequestData arg) { return new List<ReturnData>(); }
}
public class ReturnData { }
public class Example
{
private MyRepository _repo = new MyRepository();
private List<ReturnData> FilterRequestDataAndExecute(RequestData data, Func<RequestData, List<ReturnData>> action)
{
// call into another class that may or may not alter RequestData.Payers
// and then execute the actual code, potentially with some standardized exception management around it
// or logging or anything else really that would otherwise be repeated
return action(data);
}
public List<ReturnData> GetMyDataExample1(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample1);
}
public List<ReturnData> GetMyDataExample2(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample2);
}
public List<ReturnData> GetMyDataExample3(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample3);
}
}
public class RequestData
{
List<string> Payers { get; set; }
}
This sort of thinking naturally leads to aspect oriented programming.
It's specifically designed to handle cross-cutting concerns (e.g. here, your filter function cuts across your query logic.)
As #dnickless suggests, you can do this in an ad-hoc way by refactoring your calls to remove the duplicated code.
More general solutions exist, such as PostSharp which give you a slightly cleaner way of structuring code along aspects. It is proprietary, but I believe the free tier gives enough to investigate an example like this. At the very least it's interesting to see how it would look in PostSharp, and whether you think it improves it at all! (It makes strong use of attributes, which extends first suggestion.)
(N.B. I'm not practically suggesting installing another library for a simple case like this, but highlighting how these types of problems might be examined in general.)
I have a math helper class where every single function is static, i.e., params fed in as arguments, value returned. Should I declare the entire class as static? Would adding the static modifier to the class make a difference in performance?
Also, I am not sure what this guideline means in: "do not treat static classes as a miscellaneous bucket." - I have a few classes that are just a bunch of miscellaneous static functions...
It's perfectly fine to make classes like that static, in fact if you look at System.Math you'll see it's static as well:
public static class Math
What the guideline is trying to say is you should not put every static method you have to one static class which would do everything and play a role of a bucket for static methods. Instead, if it's appropriate, create smaller util classes with methods related to the same functionality, like it's done with System.Math and couple more within BCL as well.
Should I declare the entire class as static?
Yes. Adding static to a class says that it contains only static members and that you can't ever instantiate it. Without it, users of your class might get confused and try to create an instance or variable of your class. With static, that's not possible.
It seems like this is exactly your case.
Would adding the static modifier to the class make a difference in performance?
No, call to a static method will always have the same performance characteristics, it doesn't matter whether the containing class is static or not. Actually, the whole concept of static classes doesn't exist at the CIL level, they're just sealed abstract classes (a combination that wouldn't compile in C#).
But even if there was a difference, it would be tiny. Don't optimize prematurely, especially when it comes to micro-optimizations.
Helper classes are normally static classes, so that you don't need to instantiate them. There is no great cost in instantiating a managed .NET object (especially helper classes), it is just a matter of convenience.
It is extremely tempting to just put together a static class with minimal helper methods and get the job done. They have their place in code, and can be used especially when there is deterministic input/output. e.g. ComputeHash of a string, Find Average of numbers etc.
But the one reason, Static classes are discouraged is because they normally interfere with unit testing and present all sorts of problems. (Fakes, Moles, Private Accessors etc.)
An interfaced based approach for even helper classes, helps with the unit testing of the overall code. This is especially true for big projects which involve workflows such that the static helper methods are only a part of the workflow.
e.g. Suppose you need to check if the current year is a leap year. It is tempting to write a quick static method.
public static class DateHelper
{
public static bool IsLeapYear()
{
var currentDate = DateTime.UtcNow;
// check if currentDate's year is a leap year using some unicorn logic
return true; // or false
}
}
and if this method is used in your code somewhere like:
public class Birthday
{
public int GetLeapYearDaysData()
{
// some self-logic..
// now call our static method
var isLeapYear = DateHelper.IsLeapYear();
// based on this value, you might return 100 or 200.
if (isLeapYear)
{
return 100;
}
return 200;
}
}
Now, if you go and try to unit test this method public int GetLeapYearDaysData(), you might end up in trouble since the return value is indeterminate.. i.e. depends on the current year and it is not recommended to have unit tests behaving unpredictably/deteriorate as time progresses.
// this unit test is flaky
[Test]
public void TestGetLeapYearDaysData()
{
var expected = 100;
// we don't know if this method will return 100 or 200.
var actual = new Birthday().GetLeapYearDaysData();
Assert.AreEqual(expected, actual);
}
The above problem happens because we cannot control/mock the method IsLeapYear() in the above code. so we're at its mercy.
Now imagine the following design:
public interface IDateHelper
{
bool IsLeapYear();
}
public class DateHelper : IDateHelper
{
public bool IsLeapYear()
{
var currentDate = DateTime.UtcNow;
// check if currentDate's year is a leap year using some unicorn logic
return true; // or false
}
}
Now our birthday class can be injected with a helper:
public class Birthday
{
private IDateHelper _dateHelper;
// any caller can inject their own version of dateHelper.
public Birthday(IDateHelper dateHelper)
{
this._dateHelper = dateHelper;
}
public int GetLeapYearDaysData()
{
// some self-logic..
// now call our injected helper's method.
var isLeapYear = this._dateHelper.IsLeapYear();
// based on this value, you might return 100 or 200.
if (isLeapYear)
{
return 100;
}
return 200;
}
}
// now see how are unit tests can be more robust and reliable
// this unit test is more robust
[Test]
public void TestGetLeapYearDaysData()
{
var expected = 100;
// use any mocking framework or stubbed class
// to reliably tell the unit test that 100 needs to be returned.
var mockDateHelper = new Mock<IDateHelper>();
// make the mock helper return true for leap year check.
// we're no longer at the mercy of current date time.
mockDateHelper.Setup(m=>m.IsLeapYear()).Returns(true);
// inject this mock DateHelper in our BirthDay class
// we know for sure the value that'll be returned.
var actual = new Birthday(mockDateHelper).GetLeapYearDaysData();
Assert.AreEqual(expected, actual);
}
As you can see, the moment the helper methods were Interface based, they were easily testable. Over the course of a big project, many such smaller static methods ultimately result in bottlenecks in testing key functional flows.
So it pays to be aware of this pitfall in advance and make the additional investment upfront. Basically identify what classes/methods need to be static and what shouldn't be.
It all starts from when should I have a static method, and that is when you don't have any dependency on instance variables.
Now that said if none of you methods are depending on instance variable, you can make your class static.
Static class serve several benefits, and many more.