dimanche 17 juin 2018

How to make a common behavior when a single class needs different structure

I got some C# classes with a method which creates a string I need. 2 classes does it the same but 1 class does it differently:

public class Base 
{
    public abstract bool GetAction(out string res);
}

// There is another class B which does the same
public class A : Base 
{
    public override bool GetAction(out string res)
    {
       ...
       string str1 = some logic to get a string needed
       string str2 = some logic to get another string needed
       res = str1 + str2;
       ...
    }
}

public class C : Base
{
    List<Configs> configs;
    ...

    public override bool GetAction(out string res)
    {
       ...
       for(int i = 0 ; i < configs.size(); i++)
       {
           string str1 = some logic to get string based on configs[i].cfgString;
           string str2 = some logic to get another string based on configs[i].cfgString;
           res = res + configs[i].cfgString + str1 + str2; //immutable string is not the issue here so please ignore it
        }
     }

Now there's a need to get the str1 and str2 by itself.

I started making a return class instead of the bool of the GetAction method like this:

public StringsInfoClass
{
    public string Str1 { get; set; }
    public string Str2 { get; set; }
    ...
    public string ToString()
    { 
        return Str1 + Str2;
    }
}

The problem is that classes A and B has indeed only a single Str1 and Str2 while class C can have several of them. And since they are deriving from the same base class, the user will expect the same interface. What do you believe a good implementation for this problem here could be?

samedi 16 juin 2018

C# alternative for using enum as method parameter

I have the following method that downloads a set of item prices or license prices and stores it on the local HDD. The only difference between the two is the input list that dictates what items that should be queried for. The application is being deployed as a clickonce app so the storage of the file differs from debug to deployment build.

    private const string PRICEFILE = "Resources\\prices.xml";
    private const string RATEFILE = "Resources\\rates.xml";
    private const string INPUTFILE = "Resources\\ItemsList.txt";
    private const string INPUTFILELICENSE = "Resources\\Licenses.txt";
    private const string LICENSEFILE = "Resources\\Licenses.xml";

   public string getFromInventoryTableOnServer(InventoryTypeEnum type)
    {
        string _input = "";
        string _output = "";
        // Get items from items file in resources
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            if (type.Equals(InventoryTypeEnum.Prices))
            {
                _input = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + INPUTFILE;
                _output = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + PRICEFILE;
            }
            else if (type.Equals(InventoryTypeEnum.Licences))
            {
                _input = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + INPUTFILELICENSE;
                _output = ApplicationDeployment.CurrentDeployment.DataDirectory + @"\" + LICENSEFILE;
            }
        }
        else
        {
            if (type.Equals(InventoryTypeEnum.Prices))
            {
                _input = INPUTFILE;
                _output = PRICEFILE;
            }
            else if (type.Equals(InventoryTypeEnum.Licences))
            {
                _input = INPUTFILELICENSE;
                _output = LICENSEFILE;
            }
        }


        // Read file
        List<string> items = new List<string>();
        using (var sr = new StreamReader(_input))
        {


            while (!sr.EndOfStream)
            {
                items.Add(sr.ReadLine().Split(new[] { Environment.NewLine }, StringSplitOptions.None)[0]);
            }

        }

        // Connection to database and table
        List<InventTableDW> it;
        using (AXDataContext ax = new AXDataContext())
        {
            var table = ax.GetTable<InventTableDW>();

            // Query AX for item info, specially prices
            var query =
                from p in table
                where items.Contains(p.ItemID) && p.ItemGroupID == "100"
                orderby p.ItemID
                select p;

            try
            {
                it = query.ToList();
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }


        // Write to the price file
        try
        {
            using (var sw = new StreamWriter(_output))
            {
                {
                    var ser = new XmlSerializer(typeof(List<InventTableDW>));
                    ser.Serialize(sw, it);
                }
            }
        }
        catch (Exception e)
        {
            return e.Message;
        }
        return "";
    }

enum InventoryTypeEnum
{
    Prices,
    Licences
}

I'm not very proud of the current implementation as it looks a bit messy. Do you have any improvement suggestions?

Many thanks!

Data passing between Main and Delegate Object without introducing tight coupling?

I am working with delegate, datasource pattern to achieve lean View Controller in iOS, I did separated DataSource and Delegate into separate objects.

This code can be executed in playground

// Calender Delegate
protocol CalenderDelegate: class{
    func calender(_ calender: Calender, willDisplay year:Int)
    func calender(_ calender: Calender, didSelect date: Date)
    func calenderShouldChange(_ calender: Calender) -> Bool
}

// Calender DataSource

protocol CalenderDataSource{
    func calender(_ calender: Calender, eventsFor date: Date) -> [String]
    func calender(_ calender: Calender, add event: String, to date: Date)
}

// Calander Object

class Calender{
    weak var delegate: CalenderDelegate?
    var dataSource: CalenderDataSource?
    var selectedDate: Date = Date()
    var currentYear: Int = 2018

    func changeDate(to date: Date){
        self.selectedDate = date
        delegate?.calender(self, didSelect: date)
        if let items = dataSource?.calender(self, eventsFor: date){
            print("Events for \(date) are")
            items.forEach{print($0)}
        }
        else{
            print("This is a rest day not event hurrrhhhhaaa!")
        }
    }

    func changeYear(to year: Int) {
        if delegate?.calenderShouldChange(self) ?? true{
            delegate?.calender(self, willDisplay: year)
            self.currentYear = year
            print(year)
        }
    }


    func add(event: String){
        dataSource?.calender(self, add: event, to: selectedDate)
    }
}

// Datasource

class RemindersCalenderDataSource: CalenderDataSource{

    func calender(_ calender: Calender, eventsFor date: Date) -> [String] {
        return ["Event 1","Event 2","Event 3","Event 4","Event 4"]
    }
    func calender(_ calender: Calender, add event: String, to date: Date) {
        print("Events for date are \(event) \(date).")
    }
}
protocol ReminderPresenting {
    func yearChanged(to year: Int)
}

// Delegate
class RemindersCalenderDelegate: CalenderDelegate{

    var parentController: ReminderPresenting?

    func calender(_ calender: Calender, willDisplay year: Int) {
        self.parentController?.yearChanged(to: year)
        // self.title = "Year: \(year)"

    }
    func calender(_ calender: Calender, didSelect date: Date) {
        print("You selected date \(date)")
    }
    func calenderShouldChange(_ calender: Calender) -> Bool {
        return true
    }
}

//Gernal Object like ViewController
class Reminders: ReminderPresenting{
    var title = "Year: 2200"
    var calender = Calender()

    init() {
        calender.delegate = RemindersCalenderDelegate()
        calender.dataSource = RemindersCalenderDataSource()
    }
    func yearChanged(to year: Int) {
        self.title = "Year: \(year)"
        print(self.title)
    }
}

My question is

How to set the title property of Reminders class from RemindersCalenderDelegate's willDisplay method without creating high coupling in both objects.

This solution is not accepted

// In RemindersCalenderDelegate 
var parentController: Reminders?

func calendar(_ calendar: Calendar, willDisplay year: Int) {
    parentController?.title = "Year: \(year)"
}

Example is taken from: Paul Hudson. “Swift Design Patterns.” Book.

anonymous pattern matching

I think my dilemma is actually "what is anonymous pattern matching"? This is the error i get below.

type Bit = Int

def function(bits: List[Bit]): something = 
  bits.map(
    bit => bit match {
      case 0 =>  <do something 0>
      case 1 =>  <do something 1>
    }
  )

I have found the fix. It is below.

bits.foreach(
          case 0 =>  <do somthing 0>
          case 1 =>  <do somthing 1>
      )

I want to understand my error before i dumbly apply the solution. (Why cant i use .map? ) Thank you.

c# multiple classes same methods

I have 4 classes

class A {
    private List<InputSelector> _lstA = new List<InputSelector();
    private List<InputSelector> _lstB = new List<InputSelector();
    private List<InputSelector> _lstC = new List<InputSelector();

    public A(){
        _lstA.Add(new InputSelector{ description = "ItemA"});
        _lstB.Add(new InputSelector{ description = "ItemB"});
        _lstC.Add(new InputSelector{ description = "ItemC"});
    }

    public List<InputSelector> getInputSelector(InputSelectorEnum input) {
        switch(type){
             case(InputSelectorEnum.A):
                 return _lstA;
             case(InputSelectorEnum.B):
                 return _lstB;
             case(InputSelectorEnum.C):
                 return _lstC;
        }
    }
}
[...]
class D {
    private List<InputSelector> _lstA = new List<InputSelector();
    private List<InputSelector> _lstB = new List<InputSelector();
    private List<InputSelector> _lstC = new List<InputSelector();

    public D(){
        _lstA.Add(new InputSelector{ description = "ItemA"});
        _lstB.Add(new InputSelector{ description = "ItemB"});
        _lstC.Add(new InputSelector{ description = "ItemC"});
    }

    public List<InputSelector> getInputSelector(InputSelectorEnum input) {
        switch(type){
             case(InputSelectorEnum.A):
                 return _lstA;
             case(InputSelectorEnum.B):
                 return _lstB;
             case(InputSelectorEnum.C):
                 return _lstC;
        }
    }
}

This is obviously not the best DRY pattern but I can't get my head around a better pattern.

Do you have any suggestion on how to simplify this/make it easier to modify/extend and I don't have to repeat it for all 4 classes?

Many thanks!

Generic strategy pattern with Spring

I want to create few mappers using strategy pattern -all of the mappers produce XXXDTO object but consume entities that aren't exactly the same. Here is my interface:

public interface XXXDTOMapper<T> {
    XXXDTO toXXXDTO(T source);
}

And here are my implemntations:

@Component
public class GoodXXXDTOMapper implements XXXDTOMapper<GoodDTO> {

@Override
public XXXDTO toXXXDTO(GoodDTO source) {
    // some logic here
    return XXXDDTO;
    }
}

and:

@Component
public class BadXXXDTOMapper implements XXXDTOMapper<BadDTO> {

@Override
public XXXDTO toXXXDTO(BadDTO source) {
    // some logic here
    return XXXDDTO;
    }
}

Is there a simple way to use this strategy pattern it in my XXXService class that aggregates those two types (GoodDTO and BadDTO) and produces XXXDTO? What I mean is:

@Service
public class XXXService {

    private final XXXMapper xxxMapper;

    @Autowired
    public XXXService(XXXMapper xxxMapper) {
        this.xxxMapper = xxxMapper;
    }

public Stream<XXXDTO> aggregate(Stream<BadDTO> badStream, Stream<GoodDTO> goodStream) {
        return Stream.concat(badStream.map(xxxMapper::toXXXDTO), goodStream.map(xxxMapper::toXXXDTO));
    }

My code doesn't compile atm - saying there were 2 beans found - I understand why it doesn't work but looking for advice how to work around it so my strategy pattern does work. Do I need to implement factory pattern as well so at runtime it is decided which bean is used? How would you do it without all the ifs?

vendredi 15 juin 2018

Proxy Layer need for Micro Service Application

In Micro service Applications it is better to add a proxy layer above the service layer to handle lot of things like communication , security etc. but I searched for a details for that layer (in Java as example) to see the power of using this type of proxy layer and how to be implemented ? and I did not reach to suitable answer for this question .

So I need a detail illustration for this (I appreciate that); and also the recommended design patterns for building micro service applications .

Actually I don't know if my question is related directly to software architecture design or something else ; so I apologize if it is not related .