VisualWorks Application Model — КиберПедия 

Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

VisualWorks Application Model

2022-10-10 60
VisualWorks Application Model 0.00 из 5.00 0 оценок
Заказать работу

As I've discussed above, Smalltalk 80's MVC was very influential and had some excellent features, but also some faults. As Smalltalk developed in the 80's and 90's this led to some significant variations on the classic MVC model. Indeed one could almost say that MVC disappeared, if you consider the view/controller separation to be an essential part of MVC - which the name does imply.

The things that clearly worked from MVC were Separated Presentation and Observer Synchronization. So these stayed as Smalltalk developed - indeed for many people they were the key element of MVC.

Smalltalk also fragmented in these years. The basic ideas of Smalltalk, including the (minimal) language definition remained the same, but we saw multiple Smalltalks develop with different libraries. From a UI perspective this became important as several libraries started using native widgets, the controls used by the Forms and Controls style.

Smalltalk was originally developed by Xerox Parc labs and they span off a separate company, ParcPlace, to market and develop Smalltalk. ParcPlace Smalltalk was called VisualWorks and made a point of being a cross-platform system. Long before Java you could take a Smalltalk program written in Windows and run it right away on Solaris. As a result VisualWorks didn't use native widgets and kept the GUI completely within Smalltalk.

In my discussion of MVC I finished with some problems of MVC - particularly how to deal with view logic and view state. VisualWorks refined its framework to deal with this by coming up with a construct called the Application Model - a construct that moves towardsPresentation Model. The idea of using something like a Presentation Model wasn't new to VisualWorks - the original Smalltalk 80 code browser was very similar, but the VisualWorks Application Model baked it fully into the framework.

A key element of this kind of Smalltalk was the idea of turning properties into objects. In our usual notion of objects with properties we think of a Person object having properties for name and address. These properties may be fields, but could be something else. There is usually a standard convention for accessing the properties: in Java we would see temp = aPerson.getName() and aPerson.setName("martin"), in C# it would temp = aPerson.name and aPerson.name = "martin".

A Property Object changes this by having the property return an object that wraps the actual value. So in VisualWorks when we ask for a name we get back a wrapping object. We then get the actual value by asking the wrapping object for its value. So accessing a person's name would use temp = aPerson name value and aPerson name value: 'martin'

Property objects make the mapping between widgets and model a little easier. We just have to tell the widget what message to send to get the corresponding property, and the widget knows to access the proper value using value and value:. VisualWorks's property objects also allow you to set up observers with the message onChangeSend: aMessage to: anObserver.

You won't actually find a class called property object in Visual Works. Instead there were a number of classes that followed the value/value:/onChangeSend: protocol. The simplest is the ValueHolder - which just contains its value. More relevant to this discussion is the AspectAdaptor. The AspectAdaptor allowed a property object to wrap a property of another object completely. This way you could define a property object on a PersonUI class that wrapped a property on a Person object by code like

adaptor:= AspectAdaptor subject: personadaptor forAspect: #nameadaptor onChangeSend: #redisplay to: self

So let's see how the application model fits into our running example.

Figure 9: Class diagram for visual works application model on the running example

The main difference between using an application model and classic MVC is that we now have an intermediate class between the domain model class (Reader) and the widget - this is the application model class. The widgets don't access the domain objects directly - their model is the application model. Widgets are still broken down into views and controllers, but unless you're building new widgets that distinction isn't important.

When you assemble the UI you do so in a UI painter, while in that painter you set the aspect for each widget. The aspect corresponds to a method on the application model that returns a property object.

Figure 10: Sequence diagram showing how updating the actual value updates the variance text.

Figure 10 shows how the basic update sequence works. When I change a value in text field, that field then updates the value in the property object inside the application model. That update follows through to the underlying domain object, updating its actual value.

At this point the observer relationships kick in. We need to set things up so that updating the actual value causes the reading to indicate that it has changed. We do this by putting a call in the modifier for actual to indicate that the reading object has changed - in particular that the variance aspect has changed. When setting up the aspect adaptor for variance it's easy to tell it to observe the reader, so it picks up the update message which it then forwards to its text field. The text field then initiates getting a new value, again through the aspect adaptor.

Using the application model and property objects like this helps us wire up the updates without having to write much code. It also supports fine-grained synchronization (which I don't think is a good thing).

Application models allow us to separate behavior and state that's particular to the UI from real domain logic. So one of the problems I mentioned earlier, holding the currently selected item in a list, can be solved by using a particular kind of aspect adaptor that wraps the domain model's list and also stores the currently selected item.

The limitation of all this, however, is that for more complex behavior you need to construct special widgets and property objects. As an example the provided set of objects don't provide a way to link the text color of the variance to the degree of variance. Separating the application and domain models does allow us to separate the decision making in the right way, but then to use widgets observing aspect adapters we need to make some new classes. Often this was seen as too much work, so we could make this kind of thing easier by allowing the application model to access the widgets directly, as in Figure 11.

Figure 11: Application Model updates colors by manipulating widgets directly.

Directly updating the widgets like this is not part of Presentation Model, which is why the visual works application model isn't truly a Presentation Model. This need to manipulate the widgets directly was seen by many as a bit of a dirty workaround and helped develop the Model-View-Presenter approach.

So now the soundbites on Application Model

· Followed MVC in using Separated Presentation and Observer Synchronization.

· Introduced an intermediate application model as a home for presentation logic and state - a partial development of Presentation Model.

· Widgets do not observe domain objects directly, instead they observe the application model.

· Made extensive use of Property Objects to help connect the various layers and to support the fine grained synchronization using observers.

· It wasn't the default behavior for the application model to manipulate widgets, but it was commonly done for complicated cases.

Model-View-Presenter (MVP)

MVP is an architecture that first appeared in IBM and more visibly at Taligent during the 1990's. It's most commonly referred via the Potel paper. The idea was further popularized and described by the developers of Dolphin Smalltalk. As we'll see the two descriptions don't entirely mesh but the basic idea underneath it has become popular.

To approach MVP I find it helpful to think about a significant mismatch between two strands of UI thinking. On the one hand is the Forms and Controller architecture which was the mainstream approach to UI design, on the other is MVC and its derivatives. The Forms and Controls model provides a design that is easy to understand and makes a good separation between reusable widgets and application specific code. What it lacks, and MVC has so strongly, is Separated Presentation and indeed the context of programming using a Domain Model. I see MVP as a step towards uniting these streams, trying to take the best from each.

The first element of Potel is to treat the view as a structure of widgets, widgets that correspond to the controls of the Forms and Controls model and remove any view/controller separation. The view of MVP is a structure of these widgets. It doesn't contain any behavior that describes how the widgets react to user interaction.

The active reaction to user acts lives in a separate presenter object. The fundamental handlers for user gestures still exist in the widgets, but these handlers merely pass control to the presenter.

The presenter then decides how to react to the event. Potel discusses this interaction primarily in terms of actions on the model, which it does by a system of commands and selections. A useful thing to highlight here is the approach of packaging all the edits to the model in a command - this provides a good foundation for providing undo/redo behavior.

As the Presenter updates the model, the view is updated through the same Observer Synchronization approach that MVC uses.

The Dolphin description is similar. Again the main similarity is the presence of the presenter. In the Dolphin description there isn't the structure of the presenter acting on the model through commands and selections. There is also explicit discussion of the presenter manipulating the view directly. Potel doesn't talk about whether presenters should do this or not, but for Dolphin this ability was essential to overcoming the kind of flaw in Application Model that made it awkward for me to color the text in the variation field.

One of the variations in thinking about MVP is the degree to which the presenter controls the widgets in the view. On one hand there is the case where all view logic is left in the view and the presenter doesn't get involved in deciding how to render the model. This style is the one implied by Potel. The direction behind Bower and McGlashan was what I'm calling Supervising Controller, where the view handles a good deal of the view logic that can be described declaratively and the presenter then comes in to handle more complex cases.

You can also move all the way to having the presenter do all the manipulation of the widgets. This style, which I call Passive View isn't part of the original descriptions of MVP but got developed as people explored testability issues. I'm going to talk about that style later, but that style is one of the flavors of MVP.

Before I contrast MVP with what I've discussed before I should mention that both MVP papers here do this too - but not quite with the same interpretation I have. Potel implies that MVC controllers were overall coordinators - which isn't how I see them. Dolphin talks a lot about issues in MVC, but by MVC they mean the VisualWorks Application Model design rather than classic MVC that I've described (I don't blame them for that - trying to get information on classic MVC isn't easy now let alone then.)

So now it's time for some contrasts:

· Forms and Controls: MVP has a model and the presenter is expected to manipulate this model with Observer Synchronization then updating the view. Although direct access to the widgets is allowed, this should be in addition to using the model not the first choice.

· MVC: MVP uses a Supervising Controller to manipulate the model. Widgets hand off user gestures to the Supervising Controller. Widgets aren't separated into views and controllers. You can think of presenters as being like controllers but without the initial handling of the user gesture. However it's also important to note that presenters are typically at the form level, rather than the widget level - this is perhaps an even bigger difference.

· Application Model: Views hand off events to the presenter as they do to the application model. However the view may update itself directly from the domain model, the presenter doesn't act as a Presentation Model. Furthermore the presenter is welcome to directly access widgets for behaviors that don't fit into the Observer Synchronization.

There are obvious similarities between MVP presenters and MVC controllers, and presenters are a loose form of MVC controller. As a result a lot of designs will follow the MVP style but use 'controller' as a synonym for presenter. There's a reasonable argument for using controller generally when we are talking about handling user input.

Figure 12: Sequence diagram of the actual reading update in MVP.

Let's look at an MVP (Supervising Controller) version of the ice-cream monitor (Figure 12). It starts much the same as the Forms and Controls version - the actual text field raises an event when its text is changed, the presenter listens to this event and gets the new value of the field. At this point the presenter updates the reading domain object, which the variance field observes and updates its text with. The last part is the setting of the color for the variance field, which is done by the presenter. It gets the category from the reading and then updates the color of the variance field.

Here are the MVP soundbites:

· User gestures are handed off by the widgets to a Supervising Controller.

· The presenter coordinates changes in a domain model.

· Different variants of MVP handle view updates differently. These vary from using Observer Synchronization to having the presenter doing all the updates with a lot of ground in-between.

Humble View

In the past few years there's been a strong fashion for writing self-testing code. Despite being the last person to ask about fashion sense, this is a movement that I'm thoroughly immersed in. Many of my colleagues are big fans of xUnit frameworks, automated regression tests, Test-Driven Development, Continuous Integration and similar buzzwords.

When people talk about self-testing code user-interfaces quickly raise their head as a problem. Many people find that testing GUIs to be somewhere between tough and impossible. This is largely because UIs are tightly coupled into the overall UI environment and difficult to tease apart and test in pieces.

Sometimes this test difficulty is over-stated. You can often get surprisingly far by creating widgets and manipulating them in test code. But there are occasions where this is impossible, you miss important interactions, there are threading issues, and the tests are too slow to run.

As a result there's been a steady movement to design UIs in such a way that minimizes the behavior in objects that are awkward to test. Michael Feathers crisply summed up this approach in The Humble Dialog Box. Gerard Meszaros generalized this notion to idea of a Humble Object - any object that is difficult to test should have minimal behavior. That way if we are unable to include it in our test suites we minimize the chances of an undetected failure.

The Humble Dialog Box paper uses a presenter, but in a much deeper way than the original MVP. Not just does the presenter decide how to react to user events, it also handles the population of data in the UI widgets themselves. As a result the widgets no longer have, nor need, visibility to the model; they form a Passive View, manipulated by the presenter.

This isn't the only way to make the UI humble. Another approach is to use Presentation Model, although then you do need a bit more behavior in the widgets, enough for the widgets to know how to map themselves to the Presentation Model.

The key to both approaches is that by testing the presenter or by testing the presentation model, you test most of the risk of the UI without having to touch the hard-to-test widgets.

With Presentation Model you do this by having all the actual decision making made by the Presentation Model. All user events and display logic is routed to the Presentation Model, so that all the widgets have to do is map themselves to properties of the Presentation Model. You can then test most of the behavior of the Presentation Modelwithout any widgets being present - the only remaining risk lies in the widget mapping. Provided that this is simple you can live with not testing it. In this case the screen isn't quite as humble as with the Passive View approach, but the difference is small.

Since Passive View makes the widgets entirely humble, without even a mapping present, Passive View eliminates even the small risk present with Presentation Model. The cost however is that you need a Test Double to mimic the screen during your test runs - which is extra machinery you need to build.

A similar trade-off exists with Supervising Controller. Having the view do simple mappings introduces some risk but with the benefit (as with Presentation Model) of being able to specify simple mapping declaratively. Mappings will tend to be smaller forSupervising Controller than for Presentation Model as even complex updates will be determined by the Presentation Model and mapped, while a Supervising Controller will manipulate the widgets for complex cases without any mapping involved.

 

Веб-сервис для получения ежедневных данных (курсы валют, учетные цены драг. металлов...)

<--Назад к JAX-WS

Веб-сервис: www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx

При работе без использования.NET Framework для доступа к веб - сервису необходимо установить SOAP клиент и MSXML4.0 с сайта Microsoft.

  • SOAP Toolkit 3.0
  • MSXML 4.0

 

Описаниеметодовсервиса:
GetCursOnDate(On_date) получениекурсоввалютнаопределеннуюдату (ежедневныекурсывалют), GetSeldCursOnDate (ежемесячныекурсывалют)
Аргументы:
On_date - Датазапросадлякурсов, формат - System.DateTime
Результат:
XML документвформате System.Data.Dataset, содержащийтаблицу [ValuteCursOnDate],
таблицасодержитполя:

  • Vname - Название валюты
  • Vnom - Номинал
  • Vcurs - Курс
  • Vcode - ISO Цифровой код валюты
  • VchCode - ISO Символьный код валюты

результирующий DataSet содержит ExtendedProperty поле "OnDate" показывающее дату для которой присланы данные в таблице.

EnumValutes(Seld) Справочник по кодам валют, содержит полный перечень валют котируемых Банком России.
Аргументы:
Seld - формат -boolean

  • False - перечень ежедневных валют
  • True - перечень ежемесячных валют

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [EnumValutes],
таблица содержит поля:

  • Vcode - Внутренний код валюты*
  • Vname - Название валюты
  • VEngname - Англ. название валюты
  • Vnom - Номинал
  • VcommonCode - Внутренний код валюты, являющейся 'базовой'**
  • VnumCode - цифровой код ISO
  • VcharCode - 3х буквенный код ISO

* Внутренний код - код для идентификации валют, является локальным и уникальным идентификатором валюты в данной базе, необходим для использования в качестве параметра для методов GetCursDynamic (GetCursDynamicXML).
** Этот код используется для связи, при изменениях кодов или названий фактически одной и той же валюты.

Получение последней даты публикации курсов валют: ежедн./ежемес.

  • GetLatestDateTime(), GetLatestDateTimeSeld() - Результат: формат - System.DateTime
  • GetLatestDate(),GetLatestDateSeld() - Результат: формат - String

GetCursDynamic(FromDate, ToDate, ValutaCode) Получение динамики ежедневных курсов валюты
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime
  • ValutaCode Внутренний код валюты, тип String

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [ValuteCursDynamic],
таблица содержит поля:

  • CursDate - Дата котирования
  • Vcode - Внутренний код валюты*
  • Vnom - Номинал
  • Vcurs - курс

* Этот код может изменяться, в случае если в запрошенном временном промежутке запрашиваемая валюта меняла название, номинал или код.

DragMetDynamic(FromDate, ToDate) Получение динамики учетных цен на драгоценные металлы
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [DrgMet],
таблица содержит поля:

  • DateMet Дата котирования
  • CodMet Тип металла (1- Золото, 2- Серебро,3 -Платина,4 - Палладий)
  • price Учетная цена

ВНИМАНИЕ c 01.07.2008 дата установления цены является действующей, до 01.07.2008 - датой установления.

 

NewsInfo(FromDate, ToDate) Получение новостей сервера
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [News],
таблица содержит поля:

  • Doc_id ID документа
  • DocDate Дата документа
  • Title Заголовок
  • Url URL документа

SwapDynamic(FromDate, ToDate) Условия заключения сделок «валютный своп» по покупке долларов США и евро за рубли, заключенных Банком России XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [Swap],
таблица содержит поля:

  • DateBuy Дата начала сделки
  • DateSell Дата окончания сделки
  • BaseRate Процентная ставка по российским рублям, в процентах годовых, %
  • SD Базовый курс, руб./долл.
  • TIR Своп-разница, руб.
  • DEADLINEBS Время завершения расчетов в первый день сделки

DepoDynamic(FromDate, ToDate) Получение динамики ставок привлечения средств по депозитным операциям
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [Depo],
таблица содержит поля:

  • DateDepo Дата
  • Overnight Overnight
  • Tom-next Tom-next
  • P1week 1 week
  • P2weeks 2 weeks
  • P1month 1 month
  • P3month 3 months
  • SpotNext Spot/ next
  • SpotWeek Spot/ week
  • Spot2Weeks Spot/2 weeks
  • CallDeposit Call Deposit

OstatDynamic(FromDate, ToDate) Получение динамики сведений об остатках средств на корреспондентских счетах кредитных организаций XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [Ostat],
таблица содержит поля:

  • DateOst Дата
  • InRuss По России
  • InMoscow По Московскому региону

OstatDepo(FromDate, ToDate) Депозиты банков в Банке России XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Результат:
XML документ в формате System.Data.Dataset, содержащий таблицу [OD],
таблица содержит поля:

  • D0 Дата
  • D1_7 от 1 до 7 дней
  • D8_30 от 8 до 30 дней
  • depo до востребования
  • total Итого

mrrf(FromDate, ToDate) Международные резервы Российской Федерации, ежемесячные значения XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

mrrf7D(FromDate, ToDate) Международные резервы Российской Федерации, еженедельные значения XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Saldo(FromDate, ToDate) Сальдо операций ЦБ РФ по предоставлению/абсорбированию ликвидности XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Ruonia (FromDate, ToDate) Ставка RUONIA XSD
Аргументы:

  • FromDate Датаначала, тип System.DateTime
  • ToDate Датаокончания, тип System.DateTime

ROISfix (FromDate, ToDate) Ставка ROISfix XSD
Аргументы:

  • FromDate Датаначала, тип System.DateTime
  • ToDate Датаокончания, тип System.DateTime

MKR (FromDate, ToDate) Ставки межбанковского кредитного рынка XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

DV (FromDate, ToDate) Требования Банка России к кредитным организациям XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Repo_debt (FromDate, ToDate) Задолженность кредитных организаций перед Банком России по операциям прямого РЕПО XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Coins_base (FromDate, ToDate) Отпускные цены Банка России на инвестиционные монеты XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

FixingBase (FromDate, ToDate) Фиксинги на драгоценные металлы XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Overnight (FromDate, ToDate) Ставка по кредиту «overnight» (однодневный расчетный кредит) XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Bauction (FromDate, ToDate) База данных по размещению бюджетных средств на депозиты коммерческих банков XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

SwapDayTotal (FromDate, ToDate) Задолженность кредитных организаций перед Банком России по сделкам «валютный своп» XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

SwapMonthTotal (FromDate, ToDate) Объем сделок «валютный своп» по покупке долларов сша и евро за рубли, заключенных банком россии XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

SwapInfoSellUSD (FromDate, ToDate) Условия заключения сделок «валютный своп» по продаже долларов сша за рубли XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

SwapInfoSellUSDVol (FromDate, ToDate) Объем сделок «валютный своп» по продаже долларов сша за рубли, заключенных банком россии XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

BiCurBase (FromDate, ToDate) Стоимость бивалютной корзины XSD
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

BiCurBacket() Структура бивалютной корзины XSD

RepoDebtUSD (FromDate, ToDate) Задолженность кредитных организаций перед Банком России по операциям РЕПО в иностранной валюте RepoDebtUSD.xsd new
Аргументы:

  • FromDate Дата начала, тип System.DateTime
  • ToDate Дата окончания, тип System.DateTime

Данные методы возвращают только 'простые' XML документы, без использования схем:

  • Updated MainInfoXML() Получение основной информации - Ставка рефинансирования, золотовалютные резервы, денежная база, денежная масса
  • XVolXML() Операции Банка России на рынке государственных ценных бумаг по поручению Министерства финансов Российской Федерации
  • OmodInfoXML() Операции на открытом рынке
  • AllDataInfoXML() Получение всей оперативной (ежедневной) информации

Метода для работы с базой по курсам редких валют, предоставляемые агентством «Thomson Reuters» new

  • GetLatestReutersDateTime Последняя дата публикации редких валют от Thomson Reuters
  • EnumReutersValutes Справочник по кодам редких валют от Thomson Reuters
  • GetReutersCursOnDate Получение ежедневных курсов редких валют от Thomson Reuters
  • GetReutersCursDynamic Получение динамики ежедневных курсов редкой валюты от Thomson Reuters
Методы веб - сервиса, названия которых оканчиваются на XML, возвращают данные в формате "простых" XML документов без использования схем и предназначены для систем построенных не на платформе.NET Framework.

Пример работы с веб - сервисом для получения курсов валют QueryVal.zip на.NET C#

Пример работы с веб - сервисом для получения "Международные резервы Российской Федерации, ежемесячные значения" и пример работы с курсами валют MrrfSample.rar (макрос) из MS Excel с помощью SoapToolkit 3.0 и Xml sdk

Пример работы с веб - сервисом для получения информации WSExplorer.rar на.NET C#

По вопросам: [email protected]


Поделиться с друзьями:

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...

Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.096 с.