Microsoft Outlook 2002 и выше удаляет "дополнительные разрывы строки" из текстовых сообщений значением по умолчанию (kb308319) . Таким образом, Outlook, кажется, просто игнорирует последовательности перевода строки и/или возврата каретки в текстовых сообщениях, выполняя все строки вместе.
Это может вызвать проблемы, при попытке написать код, который автоматически генерирует электронное письмо, которое будет считано кем-то использующим Outlook.
, Например, предположите, что Вы хотите предоставить отдельные сведения каждый на отдельных строках для ясности, как это:
Транзакции необходимо уделять внимание!
PostedDate: Сумма 1/30/2009
: 12 222,06$
TransID: 8gk288g229g2kg89
PostalCode: 91543
Ваш получатель Outlook будет видеть информацию все разбитые вместе, следующим образом:
Транзакции необходимо уделять внимание! PostedDate: Сумма 30.01.2009: TransID за 12 222,06$: 8gk288g229g2kg89 ZipCode: 91543
, кажется, нет легкого решения. Альтернативы:
Это может быть полезно для вас.
Маленькое руководство по дизайну API (машина обратного пути)
Я не уверен, что у меня есть отличный ответ на все ваши вопросы, но я думаю, что у меня есть хороший ответ на самый первый.
Попробуйте использовать его раньше. это когда-либо написано. Под этим я подразумеваю писать модульные тесты для кода, как если бы он действительно существовал. Напишите часть кода, который будет использовать API, еще до того, как вы напишете хотя бы одну строчку API. Когда вы попытаетесь использовать его, вы быстро увидите, что работает, а что не работает в дизайне, который вы задумали, и вы »
Q4:
На мой взгляд, у Джоша Блоха есть лучшие идеи, когда дело доходит до написания хороших API , и он может объяснить их очень легко для понимания. Видео выше будет адресовано вам Q1-3.
Самый безопасный способ (т. Е. Самый простой способ не допустить ошибки в вашем приложении) может заключаться в следующем.
Создайте интерфейс, который абстрагирует ваше использование TFS, например:
interface ITfs
{
bool checkout(string filename);
}
Напишите класс, реализующий этот интерфейс с помощью TFS:
class Tfs : ITfs
{
public bool checkout(string filename)
{
... code here which uses the TFS assembly ...
}
}
Напишите другой класс, реализующий этот интерфейс без использования TFS:
class NoTfs : ITfs
{
public bool checkout(string filename)
{
//TFS not installed so checking out is impossible
return false;
}
}
Создайте где-нибудь синглтон:
static class TfsFactory
{
public static ITfs instance;
static TfsFactory()
{
... code here to set the instance
either to an instance of the Tfs class
or to an instance of the NoTfs class ...
}
}
Теперь есть только одно место, с которым нужно быть осторожным (например, TfsFactory конструктор); остальная часть вашего кода может вызывать методы ITfs вашего TfsFactory.instance, не зная, установлена ли TFS.
Чтобы ответить на недавние комментарии ниже:
Согласно моим тестам (я не знаю, является ли это «определенным поведением» ') возникает исключение, когда (как только) вы вызываете метод, который зависит от отсутствующей сборки. Поэтому это ' актив для организации, написавшей это и всем, кто им пользуется. Учитывая важность хорошего дизайна API, на удивление мало написано по теме. В этом выступлении (записано в Javapolis), дизайнер библиотеки Java Джошуа Блох учит проектировать хорошие API, с множеством примеров того, что хорошие и плохие API выглядят так.
http://www.infoq.com/presentations/effective-api-design
Также вы можете прочитать книгу Практическое проектирование API: признание архитектора Java ™ Framework . Я не читал его, поэтому не уверен, может ли оно быть вам полезно.
Еще один ресурс для проверки: Как разработать (модуль) API
Apress - Практический дизайн API - Признание архитектора Java - 2008
Pragmatic - Интерфейсно-ориентированный дизайн - 2006
Ознакомьтесь с этим подкастом
В нем рассказывается о некоторых действительно хороших концепциях, касающихся дизайна api.
Прочтите Эффективная Java Джоша Блоха. Книга отлично подходит для любого Java-программиста, но также затрагивает множество вопросов, связанных с созданием полезного API.
На этот вопрос практически невозможно ответить. Это может быть даже неподходящий вопрос для переполнения стека (Человек A: Как мне решить конкретную проблему? Человек B: Вот этот окончательный ответ).
1. Каковы лучшие практики и шаблоны, которым следует следовать при проектировании API
О каком языке программирования идет речь? О каких областях проблемных областей мы говорим? Потому что то, что работает для одного языка программирования / проблемной области, может не работать на другом языке программирования / проблемной области.
2. Как добиться наилучшего сокрытия реализации (C ++ / Java)
На этот вопрос есть ответ , и писать здесь слишком долго. На самом деле, он настолько длинный, что ссылки на веб-сайт будет недостаточно. На этот вопрос ответят многие веб-сайты и книги. О, и я ' я просто говорю о C ++. Повторите весь этот процесс для Java. И для C #, и для Python, и для .... (и т. Д.)
4. Любые справочники / ссылки, которые содержат полезные примеры для начинающих
Выберите язык программирования. Затем я могу предоставить ссылки на книги и ссылки. Как писал Фред Брукс, серебряной пули не существует. Не существует единого менталитета, который можно было бы перенести с языка программирования на язык программирования. То, что делает хороший API на одном языке программирования, было бы ошибкой проектирования на другом языке программирования. Поверьте мне, я понял это, пытаясь применить идиомы C ++, Delphi и Java на этих языках. Это приводит к плохим API и плохому коду.
Существуют также конкурирующие школы мысли в разработке API. И, к сожалению, в действительности никто не прав на 100%. По факту, Вы становитесь отличным дизайнером API, когда знаете несколько школ мысли и знаете, когда применить определенную школу мысли к конкретной проблеме.
Функционально LINQ - это не что иное, как синтаксическое упрощение выражения монад. Linq to Objects (понимание списков - даже это уже было бы чрезвычайно полезно), о котором вы говорили, является лишь одним из возможных приложений этого (аналогично List-Monad в Haskell).
Начало построения вашего API на конкретных сценариях использования ; Сделайте свой дизайн конкретным, а не общим. Затем сделайте обобщение позже , если вы обнаружите, что API можно использовать повторно.
В прошлом я видел, как API-интерфейсы реорганизовывались до такой степени, что они стали настолько универсальными, что одним из параметров метода является объект «Параметры» или, что еще хуже, дерево DOM, соответствующее произвольной части XML; например,
void processData(Parameters reportParams);
С этим универсальным подходом: