У меня часто возникают проблемы с определением, когда расширять интерфейс или уменьшать его или использовать для этого какую-либо реализацию. Рассмотрим матрицу; он может быть квадратным или нет, поэтому я бы сказал:
interface IMatrix<T>
{
void InsertColumn(int position);
void InsertRow(int position);
void DeleteColumn(int position);
void DeleteRow(int position);
T ValueAt(int row, int col); //gets the value
void ValueAt(int row, int col, T value); //sets the value
}
Итак, вышеуказанная матрица может быть квадратной, но это не обязательно. Моей первой идеей было использование класса для создания идеи квадратной матрицы как
class SquareMatrix<T> : IMatrix<T>
{
private IMatrix<T> matrix;
public SquareMatrix(IMatrix<T> matrix) {this.matrix = matrix;}
public void InsertColumn(int position)
{
// Must ensure that a row and column are both added to keep it square
this.matrix.InsertRow(position);
this.matrix.InsertColumn(position);
}
// rest of methods similarly perform a row and column operation to keep square...
}
}
Однако я быстро понял, что могу передать квадратную матрицу в конструктор и получить некоторые плохие результаты, так как теперь я буду выполнять много дополнительных операций. Поэтому я чувствую, что это не очень хороший способ ограничить интерфейс только квадратным, если нет лучшего способа реализовать этот класс.
Тогда я подумал, ну ... квадратная матрица более строгая, чем обычная матрица, может быть, мне следует извлечь интерфейс из этого как ...
interface ISquareMatrix<T>
{
void InsertRow(int position);// adds a row and column, name selected for inheritance purposes
void DeleteRow(int position);// deletes a row and column, ...
void ValueAt(int row, int col, T value);
T ValueAt(int row, int col);
}
interface IMatrix<T> : ISquareMatrix<T>
{
void InsertColumn(int position);// adds only a column and now InsertRow should not also insert a column
void DeleteColumn(int position);// deletes only a column
}
Это выглядит нормально, но несколько нарушает мой ход, хотя и относится к наследованию, так как матрица SquareMatrix IS-A, а не наоборот. Кроме того, поскольку я выбрал свои имена таким образом, чтобы наследство казалось нормальным, я стал осторожнее с этим подходом.
abstract class MatrixBase<T> : IMatrix<T>
{
//Base class simply provides a matrix that we can use
IList<IList<T>> matrix = new List<IList<T>>();
public MatrixBase(int rows, int columns)
{
if(rows < 1) {/*throw ...*/}
if(columns < 1) {/*throw...*/}
// add rows and columns
}
public abstract void InsertColumn(int position);
// more abstract methods to implement interface
}
class Matrix<T> : MatrixBase<T>
{
//override all methods so that insert column only inserts a column
//and insert row only inserts a row
}
class SquareMatrix<T> : MatrixBase<T>//seems fishy since matrix base is an IMatrix
{
//override all methods so that insert row inserts a row and column
//and insert column calls insert row
}
Итак, как вы можете видеть, квадратная матрица снова стала матрицей, хотя интерфейсы читались бы в обратном порядке.
Во всяком случае, это мои мысли; Как бы вы смоделировали отношения между квадратной матрицей и матрицей, которой не должно быть квадрата? :) Спасибо!