C# в котором нет friend... как правильно?
От: vitasR  
Дата: 26.09.10 07:44
Оценка:
Hi,

у нас тут возникла дискуссия по одному простенькому вопросу... хочу спросить мнение общественности как правильно сделать (интересует именно теоретически-идеологический аспект вопроса)

Есть класс такого вида:

public class MyClass {
private List<string> folderList;
// .... a lot of useful public methods here.....
}

все прекрасно — список фолдеров спрятан внутри, общение с внешним миром через публичные методы.

Но вот проблема. Есть GUI'ный класс Setup, через который юзер должен иметь возможность изменять список фолдеров, т.е. иметь к нему доступ.

Как идеологически правильно это можно сделать? по сути, имеет место ситуация, когда folderList должен быть приватным для всех, кроме как для класса Setup. В C++ это естесственным образом решается через friend class. а в C# ?

1. сделать folderList public ну или internal — собственно так и сделали, но как-то неправильно это по ощущениям.

2. сделать публичные методы для чтения/модификации folderList -- ну а чем это лучше чем п.1 ?

3. унаследовать Setup от MyClass не получится, т.к. Setup WPF'ный класс уже имеющий развесистый список предков,а множественное наследование C# опять же не признает. да и неправильно это

4. пока писал придумал извращенный вариант: сделать метод в классе Setup, с параметром List<string> folderList (возможно его инкапсулировать в спец.класс типа MyClassParameters); при необходимости настройки параметров вызывается нетод в классе MyClass, который дергает метод в Setup, отдавая ему ссылку на свой folderList, внутри Setup производится правка переданного списка. ура, искусственный friend сделан. Только по-моему слишком все сложно...

5. Ваш вариант?
Re: C# в котором нет friend... как правильно?
От: Mr.Delphist  
Дата: 26.09.10 11:49
Оценка:
Здравствуйте, vitasR, Вы писали:

R>5. Ваш вариант?


Огласите основные юз-кейсы, без этого можно гадать долго. Например:
1. Пересоздание объекта MyClass после каждого изменения списка фолдеров (т.е. лист получаем в конструкторе). Минус — в ряде случаев это внесет неоправданные усложнения
2. Делаем наследника MyClassRW от MyClass, где добавляем интерфейс для модификации списка фолдеров. Порождаем MyClassRW, отдаем инстанс в GUI как MyClassRW, а всем остальным — как обычный MyClass. Минусы — потенциальные касты, да и наследование без особой нужды применять не след.
3. И т.п.
Re: C# в котором нет friend... как правильно?
От: Aikin Беларусь kavaleu.ru
Дата: 27.09.10 11:53
Оценка:
Здравствуйте, vitasR, Вы писали:

R>Hi,


R>у нас тут возникла дискуссия по одному простенькому вопросу... хочу спросить мнение общественности как правильно сделать (интересует именно теоретически-идеологический аспект вопроса)


R>Есть класс такого вида:

1) Что делает и как используется этот класс? Это что-то типа настроек приложения?
2) Верно ли предположение, что этот folderList нужно заполнять только один раз при установке программы?



Если 2 верно: передавать folderList в конструктор класса и забыть про все.
Если 2 неверно, то можно в тот же конструктор передать старый экземпляр MyClass и внутри конструктора копировать остальные поля из старого объекта в новый

Пришло в голову: сделать статический метод ChangeFolderList(MyClass claszz, List<Folder> newFolders) -- использовать ттакое неправилно заметно сложнее


По поводу первого вопроса:
если это банальные настройки приложения, то не заморачивайся и делай все сетеры публичны. Программеры у вас, надеюсь, вменяемые, так что им нах не понадобиться ломать приложение изменяя этот класс.


Мыслей еще много, но доминирует следующая: придумал человек себе проблему и решает ее, нет чтобы о чем-то действительно важном думал (без обид)

СУВ, Aikin
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Re: C# в котором нет friend... как правильно?
От: MxMsk Португалия  
Дата: 27.09.10 11:53
Оценка:
Здравствуйте, vitasR, Вы писали:

R>5. Ваш вариант?

Ввести интерфейс IMyClassFoldersEditor и реализовать его неявно в MyClass.

Хотя мне кажется, уж если MyClass должен предоставлять функции изменения списка папок, то пускай он их явно предоставляет в виде методов AddFolder, RemoveFolder и т.п., а в случае WPF более удачным решением мне видится ObservableCollection.
Re: C# в котором нет friend... как правильно?
От: dfbag7 Россия  
Дата: 27.09.10 13:03
Оценка:
Здравствуйте, vitasR, Вы писали:

R>у нас тут возникла дискуссия по одному простенькому вопросу... хочу спросить мнение общественности как правильно сделать (интересует именно теоретически-идеологический аспект вопроса)


R>Есть класс такого вида:


R>public class MyClass {

R> private List<string> folderList;
R> // .... a lot of useful public methods here.....
R>}

R>все прекрасно — список фолдеров спрятан внутри, общение с внешним миром через публичные методы.


R>Но вот проблема. Есть GUI'ный класс Setup, через который юзер должен иметь возможность изменять список фолдеров, т.е. иметь к нему доступ.


Чтобы оценить ваше решение, информации об ответственности класса недостаточно. Наиболее универсальное решение — классическое (геттеры/сеттеры, при необходимости — events для извещения других классов об изменениях). Но такое решение в некоторых случаях будет слишком тяжеловесным.

Могу предложить следующее упражнение, которое я сам использую при оценке зависимости и связанности классов, и, следовательно, для оценки качества архитектуры: попробуйте представить, что перед вами поставлена задача создать две программы с аналогичным функционалом: одна будет использовать GUI, а другая — командную строку. Как при этом изменится MyClass? А если появится еще одна задача — например, сделать аналогичный функционал, вызываемый из NAnt, или интегрировать MyClass в WEB-приложение? По идее, MyClass должен быть спроектирован так, чтобы его можно было во всех трех случаях использовать без изменений.

В любом случае, если количество классов-клиентов MyClass растет, friend уже не кажется таким удобным решением.
Re: C# в котором нет friend... как правильно?
От: _FRED_ Черногория
Дата: 30.09.10 15:04
Оценка: +1
Здравствуйте, vitasR, Вы писали:

R>у нас тут возникла дискуссия по одному простенькому вопросу... хочу спросить мнение общественности как правильно сделать (интересует именно теоретически-идеологический аспект вопроса)

R>Есть класс такого вида:
[c#]
R>public class MyClass {  
R> private List<string> folderList;  
R> // .... a lot of useful public methods here.....  
R>}
[/c#]
R>все прекрасно — список фолдеров спрятан внутри, общение с внешним миром через публичные методы.

R>Но вот проблема. Есть GUI'ный класс Setup, через который юзер должен иметь возможность изменять список фолдеров, т.е. иметь к нему доступ.


R>Как идеологически правильно это можно сделать? по сути, имеет место ситуация, когда folderList должен быть приватным для всех, кроме как для класса Setup. В C++ это естесственным образом решается через friend class. а в C# ?


R>1. сделать folderList public ну или internal — собственно так и сделали, но как-то неправильно это по ощущениям.


Нет, это как раз то, что нужно. Причём не "public" (это точно "неправильно"), а именно internal.

То есть, если в С++ вы для чего-то применилибы friend в шарпе используйте internal. Заморачиваться со всякими стратегиями имеет смысл тогдла, когда вы заморочились бы с ними и в С++, то есть исключительно для дела, а не для колдунства на областью видимости.
Help will always be given at Hogwarts to those who ask for it.
Re: C# в котором нет friend... как правильно?
От: __kot2  
Дата: 03.11.10 12:16
Оценка:
Здравствуйте, vitasR, Вы писали:
R>Как идеологически правильно это можно сделать? по сути, имеет место ситуация, когда folderList должен быть приватным для всех, кроме как для класса Setup. В C++ это естесственным образом решается через friend class. а в C# ?
friend это неестественная мера никогда. его применяют когда другого способа в принципе не существует. такой бэкдур в языке.
а если просто головой подумать на самое лобовое решение, что мы имеем:
model — MyClass
view — польз интерфейс, отображающий MyClass
controller — та штука, к которой обращается view для изменения model

короче у вас в схеме нет контроллера и вы пытаетесь действовать в обход него — либо переложив функционал контроллера на гуй, либо поместив внутрь MyClass. поэтому и получается коряво
Re: C# в котором нет friend... как правильно?
От: __kot2  
Дата: 03.11.10 12:18
Оценка: +1
Здравствуйте, vitasR, Вы писали:
R>public class MyClass {
R> private List<string> folderList;
R> // .... a lot of useful public methods here.....
R>}
да, и если там действительно "lot of useful methods" то я бы выделил folderList и прочие параметры в константный класс Settings
Re[2]: C# в котором нет friend... как правильно?
От: -VaS- Россия vaskir.blogspot.com
Дата: 04.11.10 18:55
Оценка:
__>да, и если там действительно "lot of useful methods" то я бы выделил folderList и прочие параметры в константный класс Settings

...и инжектить его в MyClass и в контроллер гуя.
Re: C# в котором нет friend... как правильно?
От: Wolverrum Ниоткуда  
Дата: 05.11.10 09:03
Оценка:
Смоделировать friend достаточно легко, например, парой методов:


Но, как видите, такое решение хоть и работает аналогично friend в рантайме, но оно потенциально громоздко в плане поддержки.

Я бы не заморачивался высокими материями, и использовал бы модификатор internal как быстрое и грязное решение, ну, или перепроектирование этих классов в случае наличия риска повторения ситуации.
Re: C# в котором нет friend... как правильно?
От: rg45 СССР  
Дата: 05.11.10 19:44
Оценка:
Здравствуйте, vitasR, Вы писали:

R>Hi,


R>у нас тут возникла дискуссия по одному простенькому вопросу... хочу спросить мнение общественности как правильно сделать (интересует именно теоретически-идеологический аспект вопроса)


R>Есть класс такого вида:


R>public class MyClass {

R> private List<string> folderList;
R> // .... a lot of useful public methods here.....
R>}

R>все прекрасно — список фолдеров спрятан внутри, общение с внешним миром через публичные методы.


R>Но вот проблема. Есть GUI'ный класс Setup, через который юзер должен иметь возможность изменять список фолдеров, т.е. иметь к нему доступ.


R>Как идеологически правильно это можно сделать? по сути, имеет место ситуация, когда folderList должен быть приватным для всех, кроме как для класса Setup. В C++ это естесственным образом решается через friend class. а в C# ?


Я бы сделал так, чтоб класс Setup взаимодействовал с MyClass не непосредственно, а через абстрактный интерфейс (ISetupable). Тогда в классе MyClass можно определить вложенный закрытый класс, имеющий доступ к закрытым членам MyClass и реализующий интерфейс ISetupable:
public interface ISetupable
{
    void SetupFolderList(List<string> folderList);
}

public class Setup
{
    public void Perform(ISetupable setupable)
    {
        List<string> folderList = new List<string>();
        //...
        setupable.SetupFolderList(folderList);
    }
}

public class MyClass
{
    public void Setup(Setup setup)
    {
        setup.Perform(new SetupAgent(this));
    }

    #region Implementation
    private List<string> _folderList;

    private class SetupAgent : ISetupable
    {
        public SetupAgent(MyClass myClass) { _myClass = myClass; }
        public void SetupFolderList(List<string> folderList) { _myClass._folderList = folderList; }
        private MyClass _myClass;
    }
    #endregion
}

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass();
        Setup setup = new Setup();
        myClass.Setup(setup);
    }
}

При такой архитектуре при необходимости не составит особого труда добавить транзакционность. Вообще, архитектура, в которой объекты разных классов связаны друг с другом через абстрактные интерфейсы имеет много преимуществ: большая изолированность и безопасность, лучшая расширяемость, рефакторопригодность, более простая тестируемость...
--
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.