REF: simplify info.py
- [ ] closes #xxxx
- [ ] tests added / passed
- [ ] passes `black pandas`
- [ ] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry

Enable polymorphism and builder pattern in ``info.py``.
The main benefits:
- Separated data representation from data itself
- More clear construction of each element via builder pattern
- Different builders for various cases (verbose with counts, verbose without counts, non-verbose) enabled one eliminate numerous if statements

May be useful to implement the present PR first and then build ``Series.info`` (https://github.com/pandas-dev/pandas/pull/31796) on top of this.
I do realize that I deleted ``BaseInfo`` class.
Now I see that it is required by the referenced PR, so I can move it back.

**Note:** needed to change test behavior. Here is the reason why.
I noticed inconsistency:
```
>>> df = pd.DataFrame({'long long column': np.random.rand(1000000)})
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000000 entries, 0 to 999999
Data columns (total 1 columns):
 #   Column            Non-Null Count    Dtype
---  ------            --------------    -----
 0   long long column  1000000 non-null  float64
dtypes: float64(1)
memory usage: 7.6 MB
```
Here we have two spaces between columns.

However, if we create a dataframe with 10000 columns, then the distance between # col and "Column" is only one space.
```
>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame(np.random.rand(3, 10001))
>>> with open('out.txt', 'w') as buf: df.info(verbose=True, buf=buf)
```

```
$ tail out.txt
 9993  9993    float64
 9994  9994    float64
 9995  9995    float64
 9996  9996    float64
 9997  9997    float64
 9998  9998    float64
 9999  9999    float64
 10000 10000   float64
dtypes: float64(10001)
memory usage: 234.5 KB
```
See, only one space between the first and the second columns.
I find it inconsistent.
So, I changed it, so that there are two spaces everywhere.
What do you think?

I am going to finalize it by documenting and introducing typing where required.

I separated ``BaseInfo`` and ``TableBuilderAbstract`` to make integration of series info smoother.
It seems that all that is required for the series info is to derive ``SeriesInfo`` from ``BaseInfo`` and ``SeriesTableBuilder`` from ``TableBuilderAbstract``. Moreover, some of the methods from ``DataFrameTableBuilder`` can probably be useful for ``SeriesTableBuilder`` as well (like column widths detection, for instance). Or al least they can be similar. Merged master.
By the way, looks like the recent bug (https://github.com/pandas-dev/pandas/issues/37245) would not have emerged in this implementation. CI checks failures related to datetime. Looks like these are common across multiple PRs now. @jreback ping > Merged master.
> By the way, looks like the recent bug (#37245) would not have emerged in this implementation.

how is that? @MarcoGorelli if you have any further comments.

I am ok with this as is. @ivanovmg really prefer to have much smaller / incremental PRs. Sure i understand once in a while its advantageous to do it all at once. But review will inevitable take *way* longer. > 
> 
> > Merged master.
> > By the way, looks like the recent bug (#37245) would not have emerged in this implementation.
> 
> how is that?

Probably because in this PR we iterate over items, rather than access by index (in master). > @MarcoGorelli if you have any further comments.

I can review during the weekend, but there's no need to wait for me if you'd like this in sooner > 
> 
> > @MarcoGorelli if you have any further comments.
> 
> I can review during the weekend, but there's no need to wait for me if you'd like this in sooner

I could be ready with series.info by the end of this week.
This PR is holding me.
I guess, we can figure out the remaining concerns (if any) in that one (with series info). thanks @ivanovmg 