Click here to Skip to main content
15,886,030 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello Guys,

Recently I came across a scenario where Single responsibility and Open close principle get violated in my c# code. below is the scenario :

I am having two classes :

1. Export Questionnaire - export questionnaire functionality
2. Export Initial Bid - export initial bid functionality

1. Export First
C#
  internal class ExportQuestionnaire
    {
// startrow, startcolumn and end column is position where exporting will start on a given template.
        public int startRowPosition { get; set; }
        public int startColumnPosition { get; set; }
        public int endColumnPosition { get; set; }

        public List<int> unSupportedQuestion { get; set; }

// Constructor will initialize hard coded values for the class
        public ExportQuestionnaire(int _startRowPosition, int _startColumnPosition, int _endColumnPosition)
        {
            startRowPosition = _startRowPosition;
            startColumnPosition = _startColumnPosition;
            endColumnPosition = _endColumnPosition;
            unSupportedQuestion = new List<int>() { 3, 4, 5, 10, 11, 15, 16 };
        }
// ProcessRow - function will process row by row exporting for a worksheet - aspose
        public DataRow ProcessRow(DataRow drif, Question question, int countQuestion, long eventCode)
        {
            
        }
// GenerateSecureCode_Q - will generate secure code for exported sheet. first column of each sheet will have some secure code which will be hidden from end user.

        public string GenerateSecureCode_Q(Question question)
        {
            // will call GenerateSecureCode internally.
        }

        public string GenerateSecureCode(List<FirstRowChoice> lstQuestionchoice)
        {
            
        }

        public int GetFirstIdFromSheetColumn(string questionString)
        {
           
        }
// ProcessDocument - will process each worksheet in a workbook [Aspose]
        public void ProcessDocument(Workbook templateWorkbook, ExcelHelper excelHelper, DataTable dt, SecureString _ExcelProtection)
        {
            
        }

        public void ApplyStyle(Worksheet worksheet, int count)
        {

        }

    }


2. Export Second

C#
internal class ExportInitialBid
 {
     public int startRowPosition { get; set; }
     public int startColumnPosition { get; set; }
     public int endColumnPosition { get; set; }

     public ExportInitialBid(int _startRowPosition, int _startColumnPosition, int _endColumnPosition)
     {
         startRowPosition = _startRowPosition;
         startColumnPosition = _startColumnPosition;
         endColumnPosition = _endColumnPosition;
     }

     public DataRow ProcessRow(DataRow drif, Second lib, List<Second> SecondList)
     {

     }

     public void ProcessDocument(Workbook templateWorkbook, ExcelHelper excelHelper, DataTable dt, int Resolution, SecureString _ExcelProtection)
     {

     }

     private void ApplyStyle(Worksheet worksheet, int rowCount, int columnCount)
     {

     }

     private void ApplyDecimalStyle(Worksheet worksheet, int Count, int columnCount, int Resolution)
     {

     }
 }


Now, I am trying to DRY it and creating separate classes for ApplyStyle, ApplyDecimalStyle, ProcessRow, ProcessDocument keeping one base abstract class for each of these.
in future if i need to require one more ExportSomething, I will create one new pair of ApplyStyle, ApplyDecimalStyle, ProcessRowand ProcessDocument , extending abstract class of past.

But in this way huge no. of classes get created. while previously only two classes i had.

Is this correct approach to separate each and everything in different classes in c# ?

you can ignore answering, if this long question is annoying. but if you do, i will learn something new.

Thanks

[UPDATE 1] : Rename classes and provided comments.
Posted
Updated 16-Aug-15 2:29am
v2

Hi girishmeena,

Of course these prinicple should be applied to your C# code (as for any other language - what language did you use "before" C#?).

But your question seems to target a specific abstraction problem.
Sorry if I don't really get what you want here. But only from naming it seems you miss some OOP? A class with name CreateSecondRow seems not "natural" for me (this should be the name of a method or function). So I would suggest a "RowFactory" class - make it a baseclass (maybe abstract) and create different implementations by inheriting and overwriting of the needed "Create..." methods. (goggle: Factory pattern)
As alternative solution you could also create an Interface and let independend factory classes (no inheritance between them) implement it (but with this solution code duplication may be difficult to avoid).
But again, from your class and methods naming and your example code it's hard to get what is your real target here, maybe if you can describe your ultimate goal, we can come up with a better solution?

Is this correct approach to separate each and everything in different classes in c# ?
Of course not, normal OOP principles apply to C# as to every other OOP language I know. Things that belong together should be implemented together, the data and the operations (methods) that act on the data...

Kind regards

Johannes
 
Share this answer
 
Any though on below code .....


C#
// Note : no need to modify existing code, only available for extension.
// right now implemented for questionnaire/ intial bid export.

// Interface for exported sheet start Row and column hard values
interface IRowColumnStart
{
    int startRowPos { get; set; }
    int startColPos { get; set; }
    int endColPos { get; set; }
}

interface unSupportedQ
{
    List<int> unSupportedQ { get; set; }
}

// IRowColumnStart extended class for initial bid export
public class startRowsColumn : IRowColumnStart
{
    public int startRowPos { get; set; }
    public int startColPos { get; set; }
    public int endColPos { get; set; }

    public startRowsColumn(int _startRowPos, int _startColPos, int _endColPos)
    {
        startRowPos = _startRowPos;
        startColPos = _startColPos;
        endColPos = _endColPos;
    }
}

// IRowColumnStart extended class for questionnaire export
public class startRowColumnQ : IRowColumnStart, unSupportedQ
{
    public int startRowPos { get; set; }
    public int startColPos { get; set; }
    public int endColPos { get; set; }
    public List<int> unSupportedQ { get; set; }

    public startRowColumnQ(int _startRowPos, int _startColPos, int _endColPos, List<int> _unSupportedQ)
    {
        startRowPos = _startRowPos;
        startColPos = _startColPos;
        endColPos = _endColPos;
        unSupportedQ = _unSupportedQ;
    }
}



C#
// Note : no need to modify existing code, only available for extension.

// Main Interface for processing export request
interface IProcessExport<t,>
{
    DataRow ProRow(T param);
    void ProWsheet(T1 param);
}

// IProcessExport<t,> extended class for questionnaire export
internal class ProcessExportQ : IProcessExport<rowqparam,>
{
    private IProcessRow<rowqparam> IProcessRow;
    private IProcessWorksheet<worksheetqparam,> IProcessDoc;

    public ProcessExportQ(IProcessRow<rowqparam> i, IProcessWorksheet<worksheetqparam,> j)
    {
        IProcessRow = i;
        IProcessDoc = j;
    }

    public DataRow ProRow(RowQParam qParam)
    {
        return IProcessRow.ProRow(qParam);
    }

    public void ProWsheet(WorksheetQParam qParam)
    {
        IProcessDoc.ProcessWorksheet(qParam);
    }
}

// IProcessExport<t,> extended class for initial bid export
internal class ProcessExportIBid : IProcessExport<rowibidparam,>
{
    private startRowsColumn objRow;
    private IProcessRow<rowibidparam> IProcessRow;
    private IProcessWorksheet<worksheetibidparam,> IProcessDoc;

    public ProcessExportIBid(IProcessRow<rowibidparam> i, IProcessWorksheet<worksheetibidparam,> j)
    {
        IProcessRow = i;
        IProcessDoc = j;
}

    public DataRow ProRow(RowIBidParam iBParam)
{
        return IProcessRow.ProRow(iBParam);
    }

    public void ProWsheet(WorksheetIBidParam iBParam)
    {
        IProcessDoc.ProcessWorksheet(iBParam);
    }
}
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900